From e749f44da9584681d5afd5b5ae9c740792f51626 Mon Sep 17 00:00:00 2001 From: mkkellogg Date: Wed, 30 Sep 2015 01:48:41 -0700 Subject: [PATCH] Added call to _renderer.resetGLState() at the end of light loop in WebGLShadowMap.render(), updated WebGLRenderer.refreshUniformsShadow() to send inverse of point light position to shader. Fixes #7260. --- src/renderers/WebGLRenderer.js | 5 +++ .../shaders/ShaderChunk/shadowmap_vertex.glsl | 32 ----------------- src/renderers/webgl/WebGLShadowMap.js | 34 +++++++------------ 3 files changed, 17 insertions(+), 54 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 7014267035..ef800830f8 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1989,6 +1989,11 @@ THREE.WebGLRenderer = function ( parameters ) { if ( light instanceof THREE.PointLight ) { + // for point lights we set the shadow matrix to be a translation-only matrix + // equal to inverse of the light's position + _vector3.setFromMatrixPosition( light.matrixWorld ).negate(); + light.shadowMatrix.identity().setPosition( _vector3 ); + // for point lights we set the sign of the shadowDarkness uniform to be negative uniforms.shadowDarkness.value[ j ] = - light.shadowDarkness; diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl index 6328c60dfb..32d612c08f 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl @@ -2,40 +2,8 @@ for( int i = 0; i < MAX_SHADOWS; i ++ ) { - #if defined(POINT_LIGHT_SHADOWS) - - // if shadowDarkness[ i ] < 0.0, that means we have a point light with a cube - // shadow map - if( shadowDarkness[ i ] < 0.0 ) { - - // calculate vector from light to vertex in view space - - vec3 fromLight = mvPosition.xyz - pointLightPosition[ i ]; - - // Transform 'fromLight' into world space by multiplying it on the left - // side of 'viewMatrix'. This is equivalent to multiplying it on the right - // side of the transpose of 'viewMatrix'. Since 'viewMatrix' is orthogonal, - // its transpose is the same as its inverse. - - fromLight = fromLight * mat3( viewMatrix ); - - // We repurpose vShadowCoord to hold the distance in world space from the - // light to the vertex. This value will be interpolated correctly in the fragment shader. - - vShadowCoord[ i ] = vec4( fromLight, 1.0 ); - - } else { - - vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition; - - } - - #else - vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition; - #endif - } #endif \ No newline at end of file diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index 0699aca3bc..26431bd7c9 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -100,27 +100,15 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var faceCount, isPointLight; if ( scope.enabled === false ) return; - if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; - - // set GL state for depth map + if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; + // Set GL state for depth map. _gl.clearColor( 1, 1, 1, 1 ); _state.disable( _gl.BLEND ); - _state.enable( _gl.CULL_FACE ); _gl.frontFace( _gl.CCW ); - - if ( scope.cullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.FRONT ); - - } else { - - _gl.cullFace( _gl.BACK ); - - } - - _state.setDepthTest( true ); + _gl.cullFace( scope.cullFace === THREE.CullFaceFront ? _gl.FRONT : _gl.BACK ); + _state.setDepthTest( true ); // save the existing viewport so it can be restored later _renderer.getViewport( _vector4 ); @@ -131,6 +119,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var light = _lights[ i ]; + if ( ! light.castShadow ) continue; + if ( light instanceof THREE.PointLight ) { faceCount = 6; @@ -172,8 +162,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { } - if ( ! light.castShadow ) continue; - if ( ! light.shadowMap ) { var shadowFilter = THREE.LinearFilter; @@ -321,15 +309,17 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { } - _renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w ); + //We must call _renderer.resetGLState() at the end of each iteration of + // the light loop in order to force material updates for each light. + _renderer.resetGLState(); } - // restore GL state + _renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w ); + // Restore GL state. var clearColor = _renderer.getClearColor(), clearAlpha = _renderer.getClearAlpha(); - _renderer.setClearColor( clearColor, clearAlpha ); _state.enable( _gl.BLEND ); @@ -339,7 +329,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { } - _renderer.resetGLState(); + _renderer.resetGLState(); scope.needsUpdate = false; -- GitLab