提交 538ce768 编写于 作者: M Mr.doob

More ShadowMaps refactoring.

上级 4cc5a1af
......@@ -12,7 +12,7 @@ THREE.LightShadow = function ( camera ) {
this.mapSize = new THREE.Vector2( 512, 512 );
this.map = null;
this.matrix = null;
this.matrix = new THREE.Matrix4();
};
......
......@@ -119,8 +119,11 @@ THREE.WebGLRenderer = function ( parameters ) {
ambient: [ 0, 0, 0 ],
directional: [],
point: [],
directionalShadow: [],
spot: [],
spotShadow: [],
point: [],
pointShadow: [],
hemi: [],
shadows: [],
......@@ -1520,8 +1523,11 @@ THREE.WebGLRenderer = function ( parameters ) {
uniforms.ambientLightColor.value = _lights.ambient;
uniforms.directionalLights.value = _lights.directional;
uniforms.pointLights.value = _lights.point;
uniforms.directionalLightsShadowMap.value = _lights.directionalShadow;
uniforms.spotLights.value = _lights.spot;
uniforms.spotLightsShadowMap.value = _lights.spotShadow;
uniforms.pointLights.value = _lights.point;
uniforms.pointLightsShadowMap.value = _lights.pointShadow;
uniforms.hemisphereLights.value = _lights.hemi;
}
......@@ -1814,16 +1820,6 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( shadowMap.enabled ) {
if ( object.receiveShadow && ! material._shadowPass ) {
refreshUniformsShadow( m_uniforms, camera );
}
}
// load common uniforms
loadUniformsGeneric( materialProperties.uniformsList );
......@@ -2151,39 +2147,6 @@ THREE.WebGLRenderer = function ( parameters ) {
}
function refreshUniformsShadow ( uniforms, camera ) {
if ( uniforms.shadowMatrix ) {
var shadows = _lights.shadows;
for ( var i = 0, l = shadows.length; i < l; i ++ ) {
var light = shadows[ i ];
var shadow = light.shadow;
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();
shadow.matrix.identity().setPosition( _vector3 );
}
uniforms.shadowBias.value[ i ] = shadow.bias;
uniforms.shadowRadius.value[ i ] = shadow.radius;
uniforms.shadowMap.value[ i ] = shadow.map;
uniforms.shadowMapSize.value[ i ] = shadow.mapSize;
uniforms.shadowMatrix.value[ i ] = shadow.matrix;
}
}
}
// Uniforms (load to GPU)
function loadUniformsMatrices ( uniforms, object ) {
......@@ -2397,6 +2360,9 @@ THREE.WebGLRenderer = function ( parameters ) {
case 'c':
_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
break;
case 'm4':
_gl.uniformMatrix4fv( locationProperty, false, valueProperty.elements );
break;
}
}
......@@ -2697,78 +2663,87 @@ THREE.WebGLRenderer = function ( parameters ) {
uniforms.direction.transformDirection( viewMatrix );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.shadowEnabled = light.castShadow;
if ( light.castShadow ) {
uniforms.shadow = shadowsLength;
uniforms.shadowBias = light.shadow.bias;
uniforms.shadowRadius = light.shadow.radius;
uniforms.shadowMapSize = light.shadow.mapSize;
uniforms.shadowMatrix = light.shadow.matrix;
_lights.shadows[ shadowsLength ++ ] = light;
} else {
uniforms.shadow = - 1;
_lights.directionalShadow[ directionalLength ] = light.shadow.map;
}
_lights.directional[ directionalLength ++ ] = uniforms;
} else if ( light instanceof THREE.PointLight ) {
} else if ( light instanceof THREE.SpotLight ) {
var uniforms = lightCache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.distance = light.distance;
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.distance = distance;
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
_vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( _vector3 );
uniforms.direction.transformDirection( viewMatrix );
uniforms.angleCos = Math.cos( light.angle );
uniforms.exponent = light.exponent;
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
uniforms.shadowEnabled = light.castShadow;
if ( light.castShadow ) {
uniforms.shadow = shadowsLength;
uniforms.shadowBias = light.shadow.bias;
uniforms.shadowRadius = light.shadow.radius;
uniforms.shadowMapSize = light.shadow.mapSize;
uniforms.shadowMatrix = light.shadow.matrix;
_lights.shadows[ shadowsLength ++ ] = light;
_lights.shadowsPointLight ++;
} else {
uniforms.shadow = - 1;
_lights.spotShadow[ spotLength ] = light.shadow.map;
}
_lights.point[ pointLength ++ ] = uniforms;
_lights.spot[ spotLength ++ ] = uniforms;
} else if ( light instanceof THREE.SpotLight ) {
} else if ( light instanceof THREE.PointLight ) {
var uniforms = lightCache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.distance = distance;
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
_vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( _vector3 );
uniforms.direction.transformDirection( viewMatrix );
uniforms.angleCos = Math.cos( light.angle );
uniforms.exponent = light.exponent;
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.distance = light.distance;
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
if ( light.castShadow ) {
uniforms.shadowEnabled = light.castShadow;
uniforms.shadow = shadowsLength;
if ( light.castShadow ) {
_lights.shadows[ shadowsLength ++ ] = light;
uniforms.shadowBias = light.shadow.bias;
uniforms.shadowRadius = light.shadow.radius;
uniforms.shadowMapSize = light.shadow.mapSize;
} else {
// 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();
uniforms.shadowMatrix.identity().setPosition( _vector3 );
uniforms.shadow = - 1;
_lights.shadows[ shadowsLength ++ ] = light;
_lights.pointShadow[ pointLength ] = light.shadow.map;
}
_lights.spot[ spotLength ++ ] = uniforms;
_lights.point[ pointLength ++ ] = uniforms;
} else if ( light instanceof THREE.HemisphereLight ) {
......
......@@ -3,7 +3,12 @@
struct DirectionalLight {
vec3 direction;
vec3 color;
int shadow;
bool shadowEnabled;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
mat4 shadowMatrix;
};
uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
......@@ -29,7 +34,12 @@
vec3 color;
float distance;
float decay;
int shadow;
bool shadowEnabled;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
mat4 shadowMatrix;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
......@@ -61,7 +71,12 @@
float decay;
float angleCos;
float exponent;
int shadow;
bool shadowEnabled;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
mat4 shadowMatrix;
};
uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
......
......@@ -28,7 +28,9 @@ geometry.viewDir = normalize( vViewPosition );
IncidentLight directLight = getPointDirectLight( pointLight, geometry );
#ifdef USE_SHADOWMAP
directLight.color *= getPointShadowById( pointLight.shadow );
if ( pointLight.shadowEnabled ) {
directLight.color *= getPointShadow( pointLightsShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] );
}
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
......@@ -46,7 +48,9 @@ geometry.viewDir = normalize( vViewPosition );
IncidentLight directLight = getSpotDirectLight( spotLight, geometry );
#ifdef USE_SHADOWMAP
directLight.color *= getShadowById( spotLight.shadow );
if ( spotLight.shadowEnabled ) {
directLight.color *= getShadow( spotLightsShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] );
}
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
......@@ -64,7 +68,9 @@ geometry.viewDir = normalize( vViewPosition );
IncidentLight directLight = getDirectionalDirectLight( directionalLight, geometry );
#ifdef USE_SHADOWMAP
directLight.color *= getShadowById( directionalLight.shadow );
if ( directionalLight.shadowEnabled ) {
directLight.color *= getShadow( directionalLightsShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] );
}
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
......
#ifdef USE_SHADOWMAP
uniform float shadowBias[ NUM_SHADOWS ];
uniform float shadowRadius[ NUM_SHADOWS ];
#if NUM_DIR_LIGHTS > 0
uniform sampler2D shadowMap[ NUM_SHADOWS ];
uniform vec2 shadowMapSize[ NUM_SHADOWS ];
uniform sampler2D directionalLightsShadowMap[ NUM_DIR_LIGHTS ];
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];
varying vec4 vShadowCoord[ NUM_SHADOWS ];
#endif
#if NUM_SPOT_LIGHTS > 0
uniform sampler2D spotLightsShadowMap[ NUM_SPOT_LIGHTS ];
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];
#endif
#if NUM_POINT_LIGHTS > 0
uniform sampler2D pointLightsShadowMap[ NUM_POINT_LIGHTS ];
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];
#endif
float unpackDepth( const in vec4 rgba_depth ) {
......@@ -43,9 +56,9 @@
}
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 vShadowCoord ) {
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
vec3 shadowCoord = vShadowCoord.xyz / vShadowCoord.w;
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z += shadowBias;
// if ( something && something ) breaks ATI OpenGL shader compiler
......@@ -114,18 +127,6 @@
}
float getShadowById( const int i ) {
if ( i == - 1 ) return 1.0;
for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
if ( j == i ) {
return getShadow( shadowMap[ j ], shadowMapSize[ j ], shadowBias[ j ], shadowRadius[ j ], vShadowCoord[ j ] );
}
}
}
// cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
// vector suitable for 2D texture mapping. This code uses the following layout for the
// 2D texture:
......@@ -197,13 +198,13 @@
}
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 vShadowCoord ) {
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
// for point lights, the uniform @vShadowCoord is re-purposed to hold
// the distance from the light to the world-space position of the fragment.
vec3 lightToPosition = vShadowCoord.xyz;
vec3 lightToPosition = shadowCoord.xyz;
// bd3D = base direction 3D
vec3 bd3D = normalize( lightToPosition );
......@@ -246,16 +247,4 @@
}
float getPointShadowById( const int i ) {
if ( i == - 1 ) return 1.0;
for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
if ( j == i ) {
return getPointShadow( shadowMap[ j ], shadowMapSize[ j ], shadowBias[ j ], shadowRadius[ j ], vShadowCoord[ j ] );
}
}
}
#endif
#ifdef USE_SHADOWMAP
uniform mat4 shadowMatrix[ NUM_SHADOWS ];
varying vec4 vShadowCoord[ NUM_SHADOWS ];
#if NUM_DIR_LIGHTS > 0
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];
#endif
#if NUM_SPOT_LIGHTS > 0
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];
#endif
#if NUM_POINT_LIGHTS > 0
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];
#endif
#endif
#ifdef USE_SHADOWMAP
for ( int i = 0; i < NUM_SHADOWS; i ++ ) {
#if NUM_DIR_LIGHTS > 0
vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
}
vDirectionalShadowCoord[ i ] = directionalLights[ i ].shadowMatrix * worldPosition;
}
#endif
#if NUM_SPOT_LIGHTS > 0
for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
vSpotShadowCoord[ i ] = spotLights[ i ].shadowMatrix * worldPosition;
}
#endif
#if NUM_POINT_LIGHTS > 0
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
vPointShadowCoord[ i ] = pointLights[ i ].shadowMatrix * worldPosition;
}
#endif
#endif
......@@ -15,8 +15,7 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "aomap" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "shadowmap" ]
THREE.UniformsLib[ "fog" ]
] ),
......@@ -26,6 +25,8 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "uv_pars_vertex" ],
THREE.ShaderChunk[ "uv2_pars_vertex" ],
THREE.ShaderChunk[ "envmap_pars_vertex" ],
THREE.ShaderChunk[ "bsdfs" ],
THREE.ShaderChunk[ "lights_pars" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
......@@ -130,7 +131,6 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "ambient" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }
......@@ -286,7 +286,6 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "ambient" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
......@@ -313,6 +312,8 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "uv2_pars_vertex" ],
THREE.ShaderChunk[ "displacementmap_pars_vertex" ],
THREE.ShaderChunk[ "envmap_pars_vertex" ],
THREE.ShaderChunk[ "bsdfs" ],
THREE.ShaderChunk[ "lights_pars" ],
THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
......@@ -440,7 +441,6 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "ambient" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
......@@ -468,6 +468,8 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "uv2_pars_vertex" ],
THREE.ShaderChunk[ "displacementmap_pars_vertex" ],
THREE.ShaderChunk[ "envmap_pars_vertex" ],
THREE.ShaderChunk[ "bsdfs" ],
THREE.ShaderChunk[ "lights_pars" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
......@@ -595,8 +597,7 @@ THREE.ShaderLib = {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ "points" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "shadowmap" ]
THREE.UniformsLib[ "fog" ]
] ),
......@@ -606,6 +607,8 @@ THREE.ShaderLib = {
"uniform float scale;",
THREE.ShaderChunk[ "common" ],
THREE.ShaderChunk[ "bsdfs" ],
THREE.ShaderChunk[ "lights_pars" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
......
......@@ -96,32 +96,53 @@ THREE.UniformsLib = {
"directionalLights": { type: "sa", value: [], properties: {
"direction": { type: "v3" },
"color": { type: "c" },
"shadow": { type: "i" }
"shadowEnabled": { type: "i" },
"shadowBias": { type: "f" },
"shadowRadius": { type: "f" },
"shadowMapSize": { type: "v2" },
"shadowMatrix": { type: "m4" }
} },
"hemisphereLights": { type: "sa", value: [], properties: {
"directionalLightsShadowMap": { type: "tv", value: [] },
"spotLights": { type: "sa", value: [], properties: {
"color": { type: "c" },
"position": { type: "v3" },
"direction": { type: "v3" },
"skyColor": { type: "c" },
"groundColor": { type: "c" }
"distance": { type: "f" },
"angleCos": { type: "f" },
"exponent": { type: "f" },
"decay": { type: "f" },
"shadowEnabled": { type: "i" },
"shadowBias": { type: "f" },
"shadowRadius": { type: "f" },
"shadowMapSize": { type: "v2" },
"shadowMatrix": { type: "m4" }
} },
"spotLightsShadowMap": { type: "tv", value: [] },
"pointLights": { type: "sa", value: [], properties: {
"color": { type: "c" },
"position": { type: "v3" },
"decay": { type: "f" },
"distance": { type: "f" },
"shadow": { type: "i" }
"shadowEnabled": { type: "i" },
"shadowBias": { type: "f" },
"shadowRadius": { type: "f" },
"shadowMapSize": { type: "v2" },
"shadowMatrix": { type: "m4" }
} },
"spotLights": { type: "sa", value: [], properties: {
"color": { type: "c" },
"position": { type: "v3" },
"pointLightsShadowMap": { type: "tv", value: [] },
"hemisphereLights": { type: "sa", value: [], properties: {
"direction": { type: "v3" },
"distance": { type: "f" },
"angleCos": { type: "f" },
"exponent": { type: "f" },
"decay": { type: "f" },
"shadow": { type: "i" }
"skyColor": { type: "c" },
"groundColor": { type: "c" }
} }
},
......@@ -135,17 +156,6 @@ THREE.UniformsLib = {
"map": { type: "t", value: null },
"offsetRepeat": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
},
shadowmap: {
"shadowBias": { type: "fv1", value: [] },
"shadowRadius": { type: "fv1", value: [] },
"shadowMap": { type: "tv", value: [] },
"shadowMapSize": { type: "v2v", value: [] },
"shadowMatrix": { type: "m4v", value: [] }
}
};
......@@ -18,19 +18,34 @@ THREE.WebGLLights = function () {
switch ( light.type ) {
case 'HemisphereLight':
case 'DirectionalLight':
uniforms = {
direction: new THREE.Vector3(),
skyColor: new THREE.Color(),
groundColor: new THREE.Color()
color: new THREE.Color(),
shadowEnabled: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new THREE.Vector2(),
shadowMatrix: new THREE.Matrix4()
};
break;
case 'DirectionalLight':
case 'SpotLight':
uniforms = {
position: new THREE.Vector3(),
direction: new THREE.Vector3(),
color: new THREE.Color(),
shadow: - 1
distance: 0,
angleCos: 0,
exponent: 0,
decay: 0,
shadowEnabled: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new THREE.Vector2(),
shadowMatrix: new THREE.Matrix4()
};
break;
......@@ -40,20 +55,20 @@ THREE.WebGLLights = function () {
color: new THREE.Color(),
distance: 0,
decay: 0,
shadow: - 1
shadowEnabled: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new THREE.Vector2(),
shadowMatrix: new THREE.Matrix4()
};
break;
case 'SpotLight':
case 'HemisphereLight':
uniforms = {
position: new THREE.Vector3(),
direction: new THREE.Vector3(),
color: new THREE.Color(),
distance: 0,
angleCos: 0,
exponent: 0,
decay: 0,
shadow: - 1
skyColor: new THREE.Color(),
groundColor: new THREE.Color()
};
break;
......
......@@ -171,7 +171,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
shadow.map = new THREE.WebGLRenderTarget( shadowMapSize.x, shadowMapSize.y, pars );
shadow.matrix = new THREE.Matrix4();
//
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册