I’ve been following Edan Kwan’s guide on shadows: http://blog.edankwan.com/post/three-js-advanced-tips-shadow . Specifically, I’ve been trying to apply the concepts to a field of Points. So the idea is that the particles can both cast shadows and receive shadows. I was able to cast shadows using customDistanceMaterial (since I’m using PointLights).
But I noticed that the ShaderChunk.shadowmap_fragment.glsl no longer exists, so I’m not really sure how to approach the problem of receiving shadows. I’ve tried using ShaderChunk.shadowmask_pras_fragment.glsl method - getShadowMask() , but I’m not quite sure if I’m doing it right (or even for the right purpose). Cause, I’m getting the value 1.0f for all vertices no matter what.
Just to make it clear, I’d like to receive shadows from other particles and other objects in the scene.
------------------------- (removed link, no longer relevant)
index.js:
var geo = new THREE.BufferGeometry();
geo.addAttribute( 'position', new THREE.BufferAttribute( position, 3 ));
geo.addAttribute( 'displacement', new THREE.BufferAttribute( displacement, 1 ));
var mat = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib.shadowmap,
{
color1: { type: 'c', value: undef },
color2: { type: 'c', value: undef }
}
]),
vertexShader: shaderParse(document.getElementById( 'vertexShader' ).textContent),
fragmentShader: shaderParse(document.getElementById( 'fragmentShader' ).textContent),
blending: THREE.NoBlending
});
mat.uniforms.color1.value = new THREE.Color( 0x20cc31);
mat.uniforms.color2.value = new THREE.Color( 0x2095cc);
var mesh = new THREE.Points( geo, mat );
mesh.customDistanceMaterial = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib.shadowmap,
{
lightPosition: {type: 'v3', value: new THREE.Vector3(0, 700, 0)},
}
]),
vertexShader: shaderParse(document.getElementById( 'distanceVertexShader' ).textContent),
fragmentShader: shaderParse(document.getElementById( 'distanceFragmentShader' ).textContent),
depthTest: true,
depthWrite: true,
side: THREE.BackSide,
blending: THREE.NoBlending
});
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
// . . .
var pointLight = new THREE.PointLight( 0xffffff, 1, 700 );
pointLight.castShadow = true;
pointLight.shadow.camera.near = 10;
pointLight.shadow.camera.far = 1000;
pointLight.shadow.bias = 0.1;
pointLight.shadow.mapSize.width = 4096;
pointLight.shadow.mapSize.height = 4096;
lights.add( pointLight );
vertexShader.vert:
attribute float displacement;
varying float pos;
// chunk(shadowmap_pars_vertex);
void main() {
vec4 worldPosition = modelMatrix * vec4( position.xyz, 1.0 );
vec4 mvPosition = viewMatrix * worldPosition;
// chunk(shadowmap_vertex);
pos = displacement;
gl_Position = projectionMatrix * mvPosition;
gl_PointSize = 1300.0 / length( mvPosition.xyz ) * 0.1;
}
fragmentShader.frag:
// chunk(common);
// chunk(packing);
// chunk(fog_pars_fragment);
// chunk(bsdfs);
// chunk(lights_pars_begin);
// chunk(shadowmap_pars_fragment);
// chunk(shadowmask_pars_fragment);
varying float pos;
uniform vec3 color1;
uniform vec3 color2;
void main() {
vec3 outgoingLight = mix(color2, color1, pos);
// chunk(fog_fragment);
outgoingLight *= getShadowMask();
gl_FragColor = vec4( outgoingLight, 1.0) );
}
Thanks in advance.
EDIT :
Apparently, the reason why getShadowMask() always returns 1.0f is because the following piece of code: shadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
inside ShaderChunk.shadowmask_pars_fragment.glsl
I’ve ran some tests and pointLight.shadow
is never set anywhere, so it never executes getPointShadow. On the other hand, getPointShadow always returns 0.0f … So I’m really not sure what’s happening here, maybe there’s something wrong with what I’m doing or maybe it’s just broken.