提交 72670aef 编写于 作者: M mkkellogg

Unrolled loop in calculation of PCF shadow maps for point lights.

上级 83e2794a
......@@ -49,37 +49,44 @@
if( isPointLight ) {
float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
vec3 baseDirection3D = normalize( lightToPosition );
vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
initGridSamplingDisk();
float diskRadius = 1.25;
float numSamples = 1.0;
shadow = 0.0;
vec3 baseDirection = normalize( lightToPosition );
float curDistance = length( lightToPosition );
float dist = unpack1K( texture2D( shadowMap[ i ], baseDirection2D ) ) + 0.1;
if ( curDistance >= dist )
shadow += 1.0;
// evaluate each sampling direction
for( int s = 0; s < 20; s++ ) {
vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
vec3 adjustedBaseDirection3D = baseDirection3D + offset;
vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
dist = unpack1K( texture2D( shadowMap[ i ], adjustedBaseDirection2D ) ) + shadowBias[ i ];
if ( curDistance >= dist )
shadow += 1.0;
numSamples += 1.0;
}
shadow /= numSamples;
// bd3D = base direction 3D
vec3 bd3D = normalize( lightToPosition );
// dp = distance from light to fragment position
float dp = length( lightToPosition );
shadow = 0.0;
// base measurement
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
// dr = disk radius
const float dr = 1.25;
// os = offset scale
float os = dr * 2.0 * texelSizeY;
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
shadow /= 21.0;
} else {
......@@ -157,37 +164,44 @@
if( isPointLight ) {
float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
vec3 baseDirection3D = normalize( lightToPosition );
vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
initGridSamplingDisk();
float diskRadius = 2.25;
float numSamples = 1.0;
shadow = 0.0;
vec3 baseDirection = normalize( lightToPosition );
float curDistance = length( lightToPosition );
float dist = unpack1K( texture2D( shadowMap[ i ], baseDirection2D ) ) + 0.1;
if ( curDistance >= dist )
shadow += 1.0;
// evaluate each sampling direction
for( int s = 0; s < 20; s++ ) {
vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
vec3 adjustedBaseDirection3D = baseDirection3D + offset;
vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
dist = unpack1K( texture2D( shadowMap[ i ], adjustedBaseDirection2D ) ) + shadowBias[ i ];
if ( curDistance >= dist )
shadow += 1.0;
numSamples += 1.0;
}
shadow /= numSamples;
// bd3D = base direction 3D
vec3 bd3D = normalize( lightToPosition );
// dp = distance from light to fragment position
float dp = length( lightToPosition );
shadow = 0.0;
// base measurement
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
// dr = disk radius
const float dr = 2.25;
// os = offset scale
float os = dr * 2.0 * texelSizeY;
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
shadow /= 21.0;
} else {
......@@ -257,12 +271,14 @@
if( isPointLight ) {
vec3 baseDirection3D = normalize( lightToPosition );
vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
vec4 data = texture2D( shadowMap[ i ], baseDirection2D );
float dist = unpack1K( data ) + shadowBias[ i ];
if ( length( lightToPosition ) >= dist)
shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness );
vec3 bd3D = normalize( lightToPosition );
float dp = length( lightToPosition );
float shadow = 0.0;
adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness * shadow );
} else {
......
......@@ -18,10 +18,15 @@
#if defined(POINT_LIGHT_SHADOWS)
float unpack1K ( vec4 color ) {
// adjustShadowValue1K() upacks the depth value stored in @textureData, adds @bias to it, and then
// comapres the result with @testDepth. If @testDepth is larger than or equal to that result, then
// @shadowValue is incremented by 1.0.
const vec4 bitSh = vec4( 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0 );
return dot( color, bitSh ) * 1000.0;
void adjustShadowValue1K( const float testDepth, const vec4 textureData, const float bias, inout float shadowValue ) {
const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
if( testDepth >= dot( textureData, bitSh ) * 1000.0 + bias )
shadowValue += 1.0;
}
......@@ -96,41 +101,29 @@
}
vec3 gridSamplingDisk[ 20 ];
bool gridSamplingInitialized = false;
void initGridSamplingDisk() {
if( gridSamplingInitialized ) {
return;
}
gridSamplingDisk[0] = vec3(1, 1, 1);
gridSamplingDisk[1] = vec3(1, -1, 1);
gridSamplingDisk[2] = vec3(-1, -1, 1);
gridSamplingDisk[3] = vec3(-1, 1, 1);
gridSamplingDisk[4] = vec3(1, 1, -1);
gridSamplingDisk[5] = vec3(1, -1, -1);
gridSamplingDisk[6] = vec3(-1, -1, -1);
gridSamplingDisk[7] = vec3(-1, 1, -1);
gridSamplingDisk[8] = vec3(1, 1, 0);
gridSamplingDisk[9] = vec3(1, -1, 0);
gridSamplingDisk[10] = vec3(-1, -1, 0);
gridSamplingDisk[11] = vec3(-1, 1, 0);
gridSamplingDisk[12] = vec3(1, 0, 1);
gridSamplingDisk[13] = vec3(-1, 0, 1);
gridSamplingDisk[14] = vec3(1, 0, -1);
gridSamplingDisk[15] = vec3(-1, 0, -1);
gridSamplingDisk[16] = vec3(0, 1, 1);
gridSamplingDisk[17] = vec3(0, -1, 1);
gridSamplingDisk[18] = vec3(0, -1, -1);
gridSamplingDisk[19] = vec3(0, 1, -1);
gridSamplingInitialized = true;
}
// gsdXX = grid sampling disk XX
// these values are used when rendering PCF shadow maps for point lights
const vec3 gsd0 = vec3( 1, 1, 1 );
const vec3 gsd1 = vec3( 1, - 1, 1 );
const vec3 gsd2 = vec3( - 1, - 1, 1 );
const vec3 gsd3 = vec3( - 1, 1, 1 );
const vec3 gsd4 = vec3( 1, 1, - 1 );
const vec3 gsd5 = vec3( 1, - 1, - 1 );
const vec3 gsd6 = vec3( - 1, - 1, - 1 );
const vec3 gsd7 = vec3( -1, 1, - 1 );
const vec3 gsd8 = vec3( 1, 1, 0 );
const vec3 gsd9 = vec3( 1, - 1, 0 );
const vec3 gsd10 = vec3( - 1, - 1, 0 );
const vec3 gsd11 = vec3( - 1, 1, 0 );
const vec3 gsd12 = vec3( 1, 0, 1 );
const vec3 gsd13 = vec3( - 1, 0, 1 );
const vec3 gsd14 = vec3( 1, 0, - 1 );
const vec3 gsd15 = vec3( - 1, 0, - 1 );
const vec3 gsd16 = vec3( 0, 1, 1 );
const vec3 gsd17 = vec3( 0, - 1, 1 );
const vec3 gsd18 = vec3( 0, - 1, - 1 );
const vec3 gsd19 = vec3( 0, 1, - 1 );
#endif
......
......@@ -322,6 +322,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
}
_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
}
// restore GL state
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册