mrdoob/three.js — Issue #1221: Shadow mapping questions
Author: plopidou
Created: 2012-01-31 10:45:06+00:00
State: open

Dear all,

Here is a screenshot of a mesh subjected to a directional light and that "casts" shadows onto itself:

As you can see, the shadows start being applied where the light frustum begins (I indicated in a green dashed line the corresponding "limit" on the mesh).

So it is as if the directional light was being treated as a spot light. What am I doing wrong?

Here is the corresponding code:

var _shadowMapWidth = 4096;
var _shadowMapHeight = 4096;

[...]

light.shadowCameraVisible = true;
light.shadowCameraTop = 2000;
light.shadowCameraBottom = -2000;
light.shadowCameraRight = 2000;
light.shadowCameraLeft = -2000;
light.shadowMapWidth = _shadowMapWidth;
light.shadowMapHeight = _shadowMapHeight;
light.shadowMapBias = 0.0039;
light.shadowMapDarkness = 0.25;
light.castShadow = true;

[...]

renderer.shadowCameraNear = 0;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;

renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.25;
renderer.shadowMapWidth = _shadowMapWidth;
renderer.shadowMapHeight = _shadowMapHeight;

renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;

[...]

// straight out of the example with a few changes

var sceneHUD,
cameraOrtho,
hudMaterial;

function createHUD() {

cameraOrtho = new THREE.OrthographicCamera(
$(document).width() / -2,
$(document).width() / 2,
$(document).height() / 2,
$(document).height() / -2,
-10,
10000
);

cameraOrtho.position.y = 10;

var shader = {

uniforms: {
tDiffuse: { type: "t", value: 0, texture: null },
opacity: { type: "f", value: 1.0 }
},

vertexShader: [
"varying vec2 vUv;",
"void main() {",
"vUv = vec2( uv.x, 1.0 - uv.y );",
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"}"
].join("\n"),

fragmentShader: [
"uniform float opacity;",
"uniform sampler2D tDiffuse;",
"varying vec2 vUv;",
"void main() {",
"vec4 texel = texture2D( tDiffuse, vUv );",
"gl_FragColor = opacity * texel;",
"}"
].join("\n")

};
var uniforms = new THREE.UniformsUtils.clone( shader.uniforms );

hudMaterial = new THREE.ShaderMaterial({
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
uniforms: uniforms
});

var hudGeo = new THREE.PlaneGeometry(
_shadowMapWidth / 2,
_shadowMapHeight / 2
);

var hudMesh = new THREE.Mesh(
hudGeo,
hudMaterial
);
hudMesh.position.x = ( $(document).width() - _shadowMapWidth / 2 ) * -0.5;
hudMesh.position.y = ( $(document).height() - _shadowMapHeight / 2 ) * -0.5;

sceneHUD = new THREE.Scene();
sceneHUD.add( hudMesh );

cameraOrtho.lookAt( sceneHUD.position );
}

[...]

// shaders for the mesh

uniforms: THREE.UniformsUtils.merge([

THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"ambient"	: { type: "c", value: new THREE.Color( 0x050505 ) },
"diffuse"	: { type: "c", value: new THREE.Color( 0xeeeeee ) },
"tDiffuseGrass"	: { type: "t", value: 0, texture: null },
"tNormal"	: { type: "t", value: 1, texture: null },
"tDiffuseGround"	: { type: "t", value: 2, texture: null },
"tDiffuseCliff"	: { type: "t", value: 3, texture: null },
"tHeightMap"	: { type: "t", value: 4, texture: null },
"tSlopeMap"	: { type: "t", value: 5, texture: null },
"tDiffuseGravel"	: { type: "t", value: 6, texture: null },
"uNormalScale"	: { type: "f", value: 1.0 }
}

]),

vertexShader: [

"varying vec3 vLightWeighting;",
THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],

"varying vec2 vUv;",
"varying vec3 vPosition;",

"void main() {",

"vPosition = position;",
"vUv = uv;",

"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
"vec3 transformedNormal = normalize( normalMatrix * normal );",
THREE.ShaderChunk[ "lights_lambert_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],

"}"

].join("\n"),

fragmentShader: [

"uniform float opacity;",
"varying vec3 vLightWeighting;",

"uniform sampler2D tDiffuseGrass;",
"uniform sampler2D tDiffuseGround;",
"uniform sampler2D tDiffuseCliff;",
"uniform sampler2D tDiffuseGravel;",

"uniform sampler2D tNormal;",
"uniform sampler2D tHeightMap;",
"uniform sampler2D tSlopeMap;",

THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],

"varying vec2 vUv;",
"varying vec3 vPosition;",

"void main() {",

"gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
THREE.ShaderChunk[ "alphatest_fragment" ],
"gl_FragColor.xyz = gl_FragColor.xyz * vLightWeighting;",

/*"vec4 colorGround = texture2D( tDiffuseGround, (vUv * 8.0) );",
"vec4 colorGrass = texture2D( tDiffuseGrass, (vUv * 13.0) );",
"vec4 colorCliff = texture2D( tDiffuseCliff, (vUv * 10.0) );",
"vec4 colorGravel = texture2D( tDiffuseGravel, (vUv * 12.0) );",

"vec4 color = colorGrass * 1.0;",
"color = mix( colorGround, color, min(abs(10.0 - vPosition.z) / 220.0, 1.0) );",

"vec4 slope = texture2D( tSlopeMap, vUv );",
"color = mix( color, colorCliff, slope.r * 1.0 );",
"color = mix( color, colorGravel, slope.g * 1.0 );",

"gl_FragColor = gl_FragColor * color;",*/

THREE.ShaderChunk[ "shadowmap_fragment" ],
THREE.ShaderChunk[ "fog_fragment" ],

"}"

].join("\n")

Which leads me to my second question: as soon as I uncomment the few lines in the fragment shader, the textures are applied (that is good) but the shadow maps cast on the mesg dissapeat without a trace.Any clue? Should I change the way gl_FragColor is influenced by the textures? Change the position of the custom shader chunk in the list? Something else?

Many thanks.