提交 ae2357a0 编写于 作者: A alteredq

Added handling of multiple shadows. Added matrix4 array and texture array uniform types.

上级 3ce4e909
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -103,11 +103,11 @@ THREE.WebGLRenderer = function ( parameters ) {
this.shadowCameraFar = 5000;
this.shadowCameraFov = 50;
this.shadowMap = null;
this.shadowMap = [];
this.shadowMapEnabled = false;
var _cameraLight,
_shadowMatrix = new THREE.Matrix4();
_shadowMatrix = [];
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
......@@ -2567,8 +2567,13 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( uniforms.shadowMatrix ) {
uniforms.shadowMatrix.value.copy( _shadowMatrix );
uniforms.shadowMap.texture = _this.shadowMap;
for ( var i = 0; i < _shadowMatrix.length; i ++ ) {
uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];
}
uniforms.shadowDarkness.value = _this.shadowMapDarkness;
uniforms.shadowBias.value = _this.shadowMapBias;
......@@ -2579,7 +2584,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.initMaterial = function ( material, lights, fog, object ) {
var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
if ( material instanceof THREE.MeshDepthMaterial ) {
......@@ -2626,6 +2631,8 @@ THREE.WebGLRenderer = function ( parameters ) {
maxLightCount = allocateLights( lights, 4 );
maxShadows = allocateShadows( lights );
maxBones = allocateBones( object );
parameters = {
......@@ -2638,7 +2645,8 @@ THREE.WebGLRenderer = function ( parameters ) {
maxMorphTargets: this.maxMorphTargets,
maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
maxBones: maxBones,
shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow
shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
maxShadows: maxShadows
};
......@@ -3464,7 +3472,6 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function painterSort( a, b ) {
return b.z - a.z;
......@@ -3474,6 +3481,8 @@ THREE.WebGLRenderer = function ( parameters ) {
function renderShadowMap( scene, camera ) {
var i, il, light,
j = 0,
shadowMap, shadowMatrix,
oil,
material,
o, ol, webglObject, object,
......@@ -3486,20 +3495,28 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( ! _this.shadowMap ) {
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
//var pars = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
_this.shadowMap = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
}
for ( i = 0, il = lights.length; i < il; i ++ ) {
light = lights[ i ];
if ( light instanceof THREE.SpotLight && light.castShadow ) {
if ( ! _this.shadowMap[ j ] ) {
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
_this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
}
if ( ! _shadowMatrix[ j ] ) {
_shadowMatrix[ j ] = new THREE.Matrix4();
}
shadowMap = _this.shadowMap[ j ];
shadowMatrix = _shadowMatrix[ j ];
_cameraLight.position.copy( light.position );
_cameraLight.target.position.copy( light.target.position );
......@@ -3509,13 +3526,13 @@ THREE.WebGLRenderer = function ( parameters ) {
// compute shadow matrix
_shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0 );
shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0 );
_shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
_shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
// render shadow map
......@@ -3527,7 +3544,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_this.initWebGLObjects( scene );
setRenderTarget( _this.shadowMap );
setRenderTarget( shadowMap );
// using arbitrary clear color in depth pass
// creates variance in shadows
......@@ -3625,6 +3642,8 @@ THREE.WebGLRenderer = function ( parameters ) {
//_gl.cullFace( _gl.BACK );
j ++;
}
}
......@@ -5041,6 +5060,8 @@ THREE.WebGLRenderer = function ( parameters ) {
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
"#define MAX_SHADOWS " + parameters.maxShadows,
"#define MAX_BONES " + parameters.maxBones,
parameters.map ? "#define USE_MAP" : "",
......@@ -5108,6 +5129,8 @@ THREE.WebGLRenderer = function ( parameters ) {
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
"#define MAX_SHADOWS " + parameters.maxShadows,
parameters.fog ? "#define USE_FOG" : "",
parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
......@@ -5205,7 +5228,7 @@ THREE.WebGLRenderer = function ( parameters ) {
function loadUniformsGeneric( program, uniforms ) {
var u, uniform, value, type, location, texture;
var u, uniform, value, type, location, texture, i, il;
for( u in uniforms ) {
......@@ -5256,6 +5279,22 @@ THREE.WebGLRenderer = function ( parameters ) {
value.flattenToArray( uniform._array );
_gl.uniformMatrix4fv( location, false, uniform._array );
} else if( type == "m4v" ) {
if ( ! uniform._array ) {
uniform._array = new Float32Array( 16 * value.length );
}
for ( i = 0, il = value.length; i < il; i ++ ) {
value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
}
_gl.uniformMatrix4fv( location, false, uniform._array );
} else if( type == "c" ) {
_gl.uniform3f( location, value.r, value.g, value.b );
......@@ -5278,6 +5317,32 @@ THREE.WebGLRenderer = function ( parameters ) {
}
} else if( type == "tv" ) {
if ( ! uniform._array ) {
uniform._array = [];
for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
uniform._array[ i ] = value + i;
}
}
_gl.uniform1iv( location, uniform._array );
for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
texture = uniform.texture[ i ];
if ( !texture ) continue;
setTexture( texture, uniform._array[ i ] );
}
}
}
......@@ -5864,9 +5929,9 @@ THREE.WebGLRenderer = function ( parameters ) {
light = lights[ l ];
if ( light instanceof THREE.SpotLight ) dirLights++; // hack, not a proper spotlight
if ( light instanceof THREE.DirectionalLight ) dirLights++;
if ( light instanceof THREE.PointLight ) pointLights++;
if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
if ( light instanceof THREE.DirectionalLight ) dirLights ++;
if ( light instanceof THREE.PointLight ) pointLights ++;
}
......@@ -5886,6 +5951,24 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function allocateShadows( lights ) {
var l, ll, light,
maxShadows = 0;
for ( l = 0, ll = lights.length; l < ll; l++ ) {
light = lights[ l ];
if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;
}
return maxShadows;
};
/* DEBUG
function getGLParams() {
......
......@@ -107,7 +107,7 @@ THREE.ShaderChunk = {
"#ifdef USE_ENVMAP",
"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
"vec3 nWorld = mat3( objectMatrix[ 0 ].xyz, objectMatrix[ 1 ].xyz, objectMatrix[ 2 ].xyz ) * normal;",
"if ( useRefract ) {",
......@@ -275,7 +275,7 @@ THREE.ShaderChunk = {
"#if MAX_DIR_LIGHTS > 0",
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );",
......@@ -287,7 +287,7 @@ THREE.ShaderChunk = {
"#if MAX_POINT_LIGHTS > 0",
"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
......@@ -369,7 +369,7 @@ THREE.ShaderChunk = {
"vec4 dirDiffuse = vec4( 0.0 );",
"vec4 dirSpecular = vec4( 0.0 );" ,
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
......@@ -536,12 +536,12 @@ THREE.ShaderChunk = {
"#ifdef USE_SHADOWMAP",
"uniform sampler2D shadowMap;",
"uniform sampler2D shadowMap[ MAX_SHADOWS ];",
"uniform float shadowDarkness;",
"uniform float shadowBias;",
"varying vec4 vShadowCoord;",
"varying vec4 vShadowCoord[ MAX_SHADOWS ];",
"float unpackDepth( const in vec4 rgba_depth ) {",
......@@ -559,18 +559,30 @@ THREE.ShaderChunk = {
"#ifdef USE_SHADOWMAP",
"vec3 shadowCoord = vShadowCoord.xyz / vShadowCoord.w;",
"vec4 shadowColor = vec4( 1.0 );",
"vec4 rgbaDepth = texture2D( shadowMap, shadowCoord.xy );",
"float fDepth = unpackDepth( rgbaDepth );",
"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
"if ( fDepth < ( shadowCoord.z + shadowBias ) && ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) )",
"gl_FragColor = gl_FragColor * vec4( vec3( shadowDarkness ), 1.0 );",
"vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
// uncomment to see light frustum boundaries
//"if ( !( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) )",
// "gl_FragColor = gl_FragColor * vec4( 1.0, 0.0, 0.0, 1.0 );",
"vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
"float fDepth = unpackDepth( rgbaDepth );",
"if ( fDepth < ( shadowCoord.z + shadowBias ) && ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) )",
// spot with multiple shadows is darker
"shadowColor = shadowColor * vec4( vec3( shadowDarkness ), 1.0 );",
// spot with multiple shadows has the same color as single shadow spot
//"shadowColor = min( shadowColor, vec4( vec3( shadowDarkness ), 1.0 ) );",
// uncomment to see light frustum boundaries
//"if ( !( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) )",
// "gl_FragColor = gl_FragColor * vec4( 1.0, 0.0, 0.0, 1.0 );",
"}",
"gl_FragColor = gl_FragColor * shadowColor;",
"#endif"
......@@ -580,8 +592,8 @@ THREE.ShaderChunk = {
"#ifdef USE_SHADOWMAP",
"varying vec4 vShadowCoord;",
"uniform mat4 shadowMatrix;",
"varying vec4 vShadowCoord[ MAX_SHADOWS ];",
"uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
"#endif"
......@@ -591,7 +603,11 @@ THREE.ShaderChunk = {
"#ifdef USE_SHADOWMAP",
"vShadowCoord = shadowMatrix * objectMatrix * vec4( position, 1.0 );",
"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
"vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );",
"}",
"#endif"
......@@ -722,8 +738,8 @@ THREE.UniformsLib = {
shadowmap: {
"shadowMap": { type: "t", value: 3, texture: null },
"shadowMatrix" : { type: "m4", value: new THREE.Matrix4() },
"shadowMap": { type: "tv", value: 3, texture: [] },
"shadowMatrix" : { type: "m4v", value: [] },
"shadowBias" : { type: "f", value: 0.0039 },
"shadowDarkness": { type: "f", value: 0.2 }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册