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

Merge pull request #11764 from WestLangley/dev-point_shadow

Fix PointLight shadowmapping DistanceRGBA shader
......@@ -58,8 +58,8 @@
var pointLight = new THREE.PointLight( color, 1, 30 );
pointLight.castShadow = true;
pointLight.shadow.camera.near = 1;
pointLight.shadow.camera.far = 30;
pointLight.shadow.bias = 0.01;
pointLight.shadow.camera.far = 60;
pointLight.shadow.bias = - 0.005; // reduces self-shadowing on double-sided objects
var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
var material = new THREE.MeshBasicMaterial( { color: color } );
......@@ -97,6 +97,7 @@
torusKnot = new THREE.Mesh( geometry, material );
torusKnot.position.set( 0, 5, 0 );
torusKnot.castShadow = true;
torusKnot.receiveShadow = true;
scene.add( torusKnot );
// custom distance material
......
......@@ -2418,6 +2418,8 @@ function WebGLRenderer( parameters ) {
uniforms.shadowBias = shadow.bias;
uniforms.shadowRadius = shadow.radius;
uniforms.shadowMapSize = shadow.mapSize;
uniforms.shadowCameraNear = shadow.camera.near;
uniforms.shadowCameraFar = shadow.camera.far;
}
......
......@@ -51,6 +51,8 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
float shadowCameraNear;
float shadowCameraFar;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
......
......@@ -32,7 +32,7 @@ IncidentLight directLight;
getPointDirectLightIrradiance( pointLight, geometry, directLight );
#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
RE_Direct( directLight, geometry, material, reflectedLight );
......
......@@ -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 ) );
// 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;
// dp = normalized distance from light to fragment position
float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); // need to clamp?
dp += shadowBias;
// bd3D = base direction 3D
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 )
......
......@@ -37,7 +37,7 @@ float getShadowMask() {
for ( int i = 0; i < NUM_POINT_LIGHTS; 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 = {
UniformsLib.common,
UniformsLib.displacementmap,
{
lightPos: { value: new Vector3() }
lightPos: { value: new Vector3() },
shadowCameraNear: { value: 1 },
shadowCameraFar: { value: 1000 }
}
] ),
......
uniform vec3 lightPos;
uniform float shadowCameraNear;
uniform float shadowCameraFar;
varying vec4 vWorldPosition;
#include <common>
......@@ -18,6 +20,10 @@ void main () {
#include <alphamap_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 = {
shadow: {},
shadowBias: {},
shadowRadius: {},
shadowMapSize: {}
shadowMapSize: {},
shadowCameraNear: {},
shadowCameraFar: {}
} },
pointShadowMap: { value: [] },
......
......@@ -63,7 +63,9 @@ function WebGLLights() {
shadow: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
shadowMapSize: new Vector2(),
shadowCameraNear: 1,
shadowCameraFar: 1000
};
break;
......
......@@ -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;
......@@ -389,6 +389,8 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
if ( isPointLight && result.uniforms.lightPos !== undefined ) {
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 ) {
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 );
}
......@@ -431,7 +433,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
} 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 );
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册