提交 495e8cbc 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #11764 from WestLangley/dev-point_shadow

Fix PointLight shadowmapping DistanceRGBA shader
...@@ -58,8 +58,8 @@ ...@@ -58,8 +58,8 @@
var pointLight = new THREE.PointLight( color, 1, 30 ); var pointLight = new THREE.PointLight( color, 1, 30 );
pointLight.castShadow = true; pointLight.castShadow = true;
pointLight.shadow.camera.near = 1; pointLight.shadow.camera.near = 1;
pointLight.shadow.camera.far = 30; pointLight.shadow.camera.far = 60;
pointLight.shadow.bias = 0.01; pointLight.shadow.bias = - 0.005; // reduces self-shadowing on double-sided objects
var geometry = new THREE.SphereGeometry( 0.3, 12, 6 ); var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
var material = new THREE.MeshBasicMaterial( { color: color } ); var material = new THREE.MeshBasicMaterial( { color: color } );
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
torusKnot = new THREE.Mesh( geometry, material ); torusKnot = new THREE.Mesh( geometry, material );
torusKnot.position.set( 0, 5, 0 ); torusKnot.position.set( 0, 5, 0 );
torusKnot.castShadow = true; torusKnot.castShadow = true;
torusKnot.receiveShadow = true;
scene.add( torusKnot ); scene.add( torusKnot );
// custom distance material // custom distance material
......
...@@ -2418,6 +2418,8 @@ function WebGLRenderer( parameters ) { ...@@ -2418,6 +2418,8 @@ function WebGLRenderer( parameters ) {
uniforms.shadowBias = shadow.bias; uniforms.shadowBias = shadow.bias;
uniforms.shadowRadius = shadow.radius; uniforms.shadowRadius = shadow.radius;
uniforms.shadowMapSize = shadow.mapSize; uniforms.shadowMapSize = shadow.mapSize;
uniforms.shadowCameraNear = shadow.camera.near;
uniforms.shadowCameraFar = shadow.camera.far;
} }
......
...@@ -51,6 +51,8 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { ...@@ -51,6 +51,8 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
float shadowBias; float shadowBias;
float shadowRadius; float shadowRadius;
vec2 shadowMapSize; vec2 shadowMapSize;
float shadowCameraNear;
float shadowCameraFar;
}; };
uniform PointLight pointLights[ NUM_POINT_LIGHTS ]; uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
......
...@@ -32,7 +32,7 @@ IncidentLight directLight; ...@@ -32,7 +32,7 @@ IncidentLight directLight;
getPointDirectLightIrradiance( pointLight, geometry, directLight ); getPointDirectLightIrradiance( pointLight, geometry, directLight );
#ifdef USE_SHADOWMAP #ifdef USE_SHADOWMAP
directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0; directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
#endif #endif
RE_Direct( directLight, geometry, material, reflectedLight ); RE_Direct( directLight, geometry, material, reflectedLight );
......
...@@ -201,18 +201,20 @@ ...@@ -201,18 +201,20 @@
} }
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );
// for point lights, the uniform @vShadowCoord is re-purposed to hold // for point lights, the uniform @vShadowCoord is re-purposed to hold
// the distance from the light to the world-space position of the fragment. // the vector from the light to the world-space position of the fragment.
vec3 lightToPosition = shadowCoord.xyz; vec3 lightToPosition = shadowCoord.xyz;
// dp = normalized distance from light to fragment position
float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); // need to clamp?
dp += shadowBias;
// bd3D = base direction 3D // bd3D = base direction 3D
vec3 bd3D = normalize( lightToPosition ); vec3 bd3D = normalize( lightToPosition );
// dp = distance from light to fragment position
float dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;
#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )
......
...@@ -37,7 +37,7 @@ float getShadowMask() { ...@@ -37,7 +37,7 @@ float getShadowMask() {
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
pointLight = pointLights[ i ]; pointLight = pointLights[ i ];
shadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0; shadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
} }
......
...@@ -194,7 +194,9 @@ var ShaderLib = { ...@@ -194,7 +194,9 @@ var ShaderLib = {
UniformsLib.common, UniformsLib.common,
UniformsLib.displacementmap, UniformsLib.displacementmap,
{ {
lightPos: { value: new Vector3() } lightPos: { value: new Vector3() },
shadowCameraNear: { value: 1 },
shadowCameraFar: { value: 1000 }
} }
] ), ] ),
......
uniform vec3 lightPos; uniform vec3 lightPos;
uniform float shadowCameraNear;
uniform float shadowCameraFar;
varying vec4 vWorldPosition; varying vec4 vWorldPosition;
#include <common> #include <common>
...@@ -18,6 +20,10 @@ void main () { ...@@ -18,6 +20,10 @@ void main () {
#include <alphamap_fragment> #include <alphamap_fragment>
#include <alphatest_fragment> #include <alphatest_fragment>
gl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 ); float dist = length( vWorldPosition.xyz - lightPos.xyz );
dist = ( dist - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );
dist = saturate( dist ); // clamp to [ 0, 1 ]
gl_FragColor = packDepthToRGBA( dist );
} }
...@@ -140,7 +140,9 @@ var UniformsLib = { ...@@ -140,7 +140,9 @@ var UniformsLib = {
shadow: {}, shadow: {},
shadowBias: {}, shadowBias: {},
shadowRadius: {}, shadowRadius: {},
shadowMapSize: {} shadowMapSize: {},
shadowCameraNear: {},
shadowCameraFar: {}
} }, } },
pointShadowMap: { value: [] }, pointShadowMap: { value: [] },
......
...@@ -63,7 +63,9 @@ function WebGLLights() { ...@@ -63,7 +63,9 @@ function WebGLLights() {
shadow: false, shadow: false,
shadowBias: 0, shadowBias: 0,
shadowRadius: 1, shadowRadius: 1,
shadowMapSize: new Vector2() shadowMapSize: new Vector2(),
shadowCameraNear: 1,
shadowCameraFar: 1000
}; };
break; break;
......
...@@ -273,7 +273,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) { ...@@ -273,7 +273,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
}; };
function getDepthMaterial( object, material, isPointLight, lightPositionWorld ) { function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) {
var geometry = object.geometry; var geometry = object.geometry;
...@@ -389,6 +389,8 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) { ...@@ -389,6 +389,8 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
if ( isPointLight && result.uniforms.lightPos !== undefined ) { if ( isPointLight && result.uniforms.lightPos !== undefined ) {
result.uniforms.lightPos.value.copy( lightPositionWorld ); result.uniforms.lightPos.value.copy( lightPositionWorld );
result.uniforms.shadowCameraNear.value = shadowCameraNear;
result.uniforms.shadowCameraFar.value = shadowCameraFar;
} }
...@@ -422,7 +424,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) { ...@@ -422,7 +424,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
if ( groupMaterial && groupMaterial.visible ) { if ( groupMaterial && groupMaterial.visible ) {
var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld ); var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
} }
...@@ -431,7 +433,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) { ...@@ -431,7 +433,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
} else if ( material.visible ) { } else if ( material.visible ) {
var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld ); var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册