In my water shader i used shadows without lights code.
https://codepen.io/illuminsi/pen/ZYGPZwL
const uniforms = { maskTex: { value: maskTexture } };
for(let i in THREE.UniformsLib["lights"]){
uniforms[i]={value:null};
}
const material = new THREE.ShaderMaterial({
uniforms,
lights:true,
vertexShader,
fragmentShader
});
vertex shader peace:
uniform mat4 directionalShadowMatrix[NUM_DIR_LIGHT_SHADOWS];
varying vec4 vDirectionalShadowCoord[NUM_DIR_LIGHT_SHADOWS];
struct DirectionalLightShadow{
float shadowIntensity;
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform DirectionalLightShadow directionalLightShadows[NUM_DIR_LIGHT_SHADOWS];
void main(){
...
for(int i=0;i<NUM_DIR_LIGHT_SHADOWS;i++){
vDirectionalShadowCoord[i]=directionalShadowMatrix[i]*vec4(position,1.0);
}
}
fragment shader peace:
uniform mat4 directionalShadowMatrix[NUM_DIR_LIGHT_SHADOWS];
const float UnpackDownscale=255./256.; // 0..1 -> fraction (excluding 1)
const vec4 PackFactors=vec4(1.0,256.0,256.0*256.0,256.0*256.0*256.0);
const vec4 UnpackFactors4=vec4(UnpackDownscale/PackFactors.rgb,1.0/PackFactors.a);
float unpackRGBAToDepth(const in vec4 v){ return dot(v,UnpackFactors4); }
vec2 unpackRGBATo2Half(const in vec4 v){ return vec2(v.x+(v.y/255.0),v.z+(v.w/255.0)); }
// SHADOWMAP_PARS_FRAGMENT
struct DirectionalLightShadow{
float shadowIntensity;
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform DirectionalLightShadow directionalLightShadows[NUM_DIR_LIGHT_SHADOWS];
uniform sampler2D directionalShadowMap[NUM_DIR_LIGHT_SHADOWS];
varying vec4 vDirectionalShadowCoord[NUM_DIR_LIGHT_SHADOWS];
float texture2DCompare(sampler2D depths,vec2 uv,float compare){
return step(compare,unpackRGBAToDepth(texture2D(depths,uv)));
}
vec2 texture2DDistribution(sampler2D shadow,vec2 uv){
return unpackRGBATo2Half(texture2D(shadow,uv));
}
float VSMShadow(sampler2D shadow,vec2 uv,float compare){
float occlusion=1.0;
vec2 distribution=texture2DDistribution(shadow,uv);
float hard_shadow=step(compare,distribution.x); // Hard Shadow
if(hard_shadow!=1.0){
float distance=compare-distribution.x ;
float variance=max(0.00000,distribution.y*distribution.y);
float softness_probability=variance/(variance+distance*distance); // Chebeyshevs inequality
softness_probability=clamp((softness_probability-0.3)/(0.95-0.3),0.0,1.0); // 0.3 reduces light bleed
occlusion=clamp(max(hard_shadow,softness_probability),0.0,1.0);
}
return occlusion;
}
float getShadow(sampler2D shadowMap,vec2 shadowMapSize,float shadowIntensity,float shadowBias,float shadowRadius,vec4 shadowCoord){
float shadow=1.0;
shadowCoord.xyz/=shadowCoord.w;
shadowCoord.z+=shadowBias;
bool inFrustum=shadowCoord.x>=0.0 && shadowCoord.x<=1.0 && shadowCoord.y>=0.0 && shadowCoord.y<=1.0;
bool frustumTest=inFrustum && shadowCoord.z<=1.0;
if(frustumTest){
#if defined(SHADOWMAP_TYPE_VSM)
shadow=VSMShadow(shadowMap,shadowCoord.xy,shadowCoord.z);
#else // no percentage-closer filtering:
shadow=texture2DCompare(shadowMap,shadowCoord.xy,shadowCoord.z);
#endif
}
return mix(1.0,shadow,shadowIntensity);
}
vec2 cubeToUV(vec3 v,float texelSizeY){
vec3 absV=abs(v);
float scaleToCube=1.0/max(absV.x,max(absV.y,absV.z));
absV*=scaleToCube;
v*=scaleToCube*(1.0-2.0*texelSizeY);
vec2 planar=v.xy;
float almostATexel=1.5*texelSizeY;
float almostOne=1.0-almostATexel;
if(absV.z>=almostOne){
if(v.z>0.0)
planar.x=4.0-v.x;
}else if(absV.x>=almostOne){
float signX=sign(v.x);
planar.x=v.z*signX+2.0*signX;
}else if(absV.y>=almostOne){
float signY=sign(v.y);
planar.x=v.x+2.0*signY+2.0;
planar.y=v.z*signY-2.0;
}
return vec2(0.125,0.25)*planar+vec2(0.375,0.75);
}
float getPointShadow(sampler2D shadowMap,vec2 shadowMapSize,float shadowIntensity,float shadowBias,float shadowRadius,vec4 shadowCoord,float shadowCameraNear,float shadowCameraFar){
float shadow=1.0;
vec3 lightToPosition=shadowCoord.xyz;
float lightToPositionLength=length(lightToPosition);
if(lightToPositionLength-shadowCameraFar<=0.0 && lightToPositionLength-shadowCameraNear>=0.0){
float dp=(lightToPositionLength-shadowCameraNear)/(shadowCameraFar-shadowCameraNear);
dp+=shadowBias;
vec3 bd3D=normalize(lightToPosition);
vec2 texelSize=vec2(1.0)/(shadowMapSize*vec2(4.0,2.0));
shadow=texture2DCompare(shadowMap,cubeToUV(bd3D,texelSize.y),dp);
}
return mix(1.0,shadow,shadowIntensity);
}
// SHADOWMASK_PARS_FRAGMENT
float getShadowMask(){
float shadow=1.0;
DirectionalLightShadow directionalLight;
#pragma unroll_loop_start
for(int i=0;i<NUM_DIR_LIGHT_SHADOWS;i++){
directionalLight=directionalLightShadows[i];
shadow*=getShadow(directionalShadowMap[i],directionalLight.shadowMapSize,directionalLight.shadowIntensity,directionalLight.shadowBias,directionalLight.shadowRadius,vDirectionalShadowCoord[i]);
}
#pragma unroll_loop_end
return shadow;
}
void main(){
float shadow=getShadowMask();
gl_FragColor=vec4(1.0,1.0,1.0,1.0);
gl_FragColor.rgb*=shadow;