提交 72dae739 编写于 作者: A alteredq

WebGLDeferredRenderer: refactored spotlights.

Moved view space light direction and position computations out of the shader.

These are constant for every pixel affected by the light, so computation can be done just once per light in JS and then passed in as uniform.
上级 133895ce
...@@ -536,12 +536,11 @@ THREE.ShaderDeferred = { ...@@ -536,12 +536,11 @@ THREE.ShaderDeferred = {
samplerNormalDepth: { type: "t", value: null }, samplerNormalDepth: { type: "t", value: null },
samplerColor: { type: "t", value: null }, samplerColor: { type: "t", value: null },
matView: { type: "m4", value: new THREE.Matrix4() },
matProjInverse: { type: "m4", value: new THREE.Matrix4() }, matProjInverse: { type: "m4", value: new THREE.Matrix4() },
viewWidth: { type: "f", value: 800 }, viewWidth: { type: "f", value: 800 },
viewHeight: { type: "f", value: 600 }, viewHeight: { type: "f", value: 600 },
lightPositionWS:{ type: "v3", value: new THREE.Vector3( 0, 1, 0 ) }, lightPositionVS :{ type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
lightTargetWS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) }, lightDirectionVS:{ type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
lightColor: { type: "c", value: new THREE.Color( 0x000000 ) }, lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
lightIntensity: { type: "f", value: 1.0 }, lightIntensity: { type: "f", value: 1.0 },
lightDistance: { type: "f", value: 1.0 }, lightDistance: { type: "f", value: 1.0 },
...@@ -551,6 +550,9 @@ THREE.ShaderDeferred = { ...@@ -551,6 +550,9 @@ THREE.ShaderDeferred = {
fragmentShader : [ fragmentShader : [
"uniform vec3 lightPositionVS;",
"uniform vec3 lightDirectionVS;",
"uniform sampler2D samplerColor;", "uniform sampler2D samplerColor;",
"uniform sampler2D samplerNormalDepth;", "uniform sampler2D samplerNormalDepth;",
...@@ -563,9 +565,6 @@ THREE.ShaderDeferred = { ...@@ -563,9 +565,6 @@ THREE.ShaderDeferred = {
"uniform mat4 matProjInverse;", "uniform mat4 matProjInverse;",
"varying vec3 vLightPositionVS;",
"varying vec3 vLightDirectionVS;",
"vec3 float_to_vec3( float data ) {", "vec3 float_to_vec3( float data ) {",
"vec3 uncompressed;", "vec3 uncompressed;",
...@@ -610,10 +609,10 @@ THREE.ShaderDeferred = { ...@@ -610,10 +609,10 @@ THREE.ShaderDeferred = {
// //
"vec3 surfToLight = normalize( vLightPositionVS.xyz - positionVS.xyz );", "vec3 surfToLight = normalize( lightPositionVS.xyz - positionVS.xyz );",
"float dotProduct = max( dot( normal, surfToLight ), 0.0 );", "float dotProduct = max( dot( normal, surfToLight ), 0.0 );",
"float rho = dot( vLightDirectionVS, -surfToLight );", "float rho = dot( lightDirectionVS, surfToLight );",
"float rhoMax = cos( lightAngle * 0.5 );", "float rhoMax = cos( lightAngle * 0.5 );",
"if ( rho > rhoMax ) {", "if ( rho > rhoMax ) {",
...@@ -674,23 +673,9 @@ THREE.ShaderDeferred = { ...@@ -674,23 +673,9 @@ THREE.ShaderDeferred = {
vertexShader : [ vertexShader : [
"uniform vec3 lightPositionWS;",
"uniform vec3 lightTargetWS;",
"uniform mat4 matView;",
"varying vec3 vLightPositionVS;",
"varying vec3 vLightDirectionVS;",
"void main() { ", "void main() { ",
"vec4 quadPosition = vec4( sign( position.xy ), 0.0, 1.0 );", "gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
"gl_Position = quadPosition;",
"vLightPositionVS = vec3( matView * vec4( lightPositionWS, 1.0 ) );",
"vec3 lightDirectionWS = lightTargetWS - lightPositionWS;"+
"vLightDirectionVS = normalize( mat3( matView ) * lightDirectionWS );",
"}" "}"
......
...@@ -37,6 +37,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { ...@@ -37,6 +37,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
// //
var positionVS = new THREE.Vector3();
var directionVS = new THREE.Vector3();
var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 ); var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
var geometryLightPlane = new THREE.PlaneGeometry( 2, 2 ); var geometryLightPlane = new THREE.PlaneGeometry( 2, 2 );
...@@ -384,9 +387,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { ...@@ -384,9 +387,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
// setup light material // setup light material
var uniforms = THREE.UniformsUtils.clone( spotLightShader.uniforms );
var materialLight = new THREE.ShaderMaterial( { var materialLight = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.clone( spotLightShader.uniforms ), uniforms: uniforms,
vertexShader: spotLightShader.vertexShader, vertexShader: spotLightShader.vertexShader,
fragmentShader: spotLightShader.fragmentShader, fragmentShader: spotLightShader.fragmentShader,
...@@ -401,18 +406,27 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { ...@@ -401,18 +406,27 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var intensity = light.intensity * light.intensity; var intensity = light.intensity * light.intensity;
materialLight.uniforms[ "lightPositionWS" ].value.copy( light.matrixWorld.getPosition() ); positionVS.copy( light.matrixWorld.getPosition() );
materialLight.uniforms[ "lightTargetWS" ].value.copy( light.target.matrixWorld.getPosition() ); camera.matrixWorldInverse.multiplyVector3( positionVS );
materialLight.uniforms[ "lightIntensity" ].value = intensity;
materialLight.uniforms[ "lightAngle" ].value = light.angle;
materialLight.uniforms[ "lightDistance" ].value = light.distance;
materialLight.uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
materialLight.uniforms[ "viewWidth" ].value = scaledWidth; directionVS.copy( light.matrixWorld.getPosition() );
materialLight.uniforms[ "viewHeight" ].value = scaledHeight; directionVS.subSelf( light.target.matrixWorld.getPosition() );
directionVS.normalize();
camera.matrixWorldInverse.rotateAxis( directionVS );
materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2; uniforms[ "lightPositionVS" ].value.copy( positionVS );
materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2; uniforms[ "lightDirectionVS" ].value.copy( directionVS );
uniforms[ "lightIntensity" ].value = intensity;
uniforms[ "lightAngle" ].value = light.angle;
uniforms[ "lightDistance" ].value = light.distance;
uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
uniforms[ "viewWidth" ].value = scaledWidth;
uniforms[ "viewHeight" ].value = scaledHeight;
uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
// create light proxy mesh // create light proxy mesh
...@@ -693,8 +707,16 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { ...@@ -693,8 +707,16 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
} else if ( originalLight instanceof THREE.SpotLight ) { } else if ( originalLight instanceof THREE.SpotLight ) {
uniforms[ "lightPositionWS" ].value.copy( originalLight.matrixWorld.getPosition() ); positionVS.copy( originalLight.matrixWorld.getPosition() );
uniforms[ "lightTargetWS" ].value.copy( originalLight.target.matrixWorld.getPosition() ); camera.matrixWorldInverse.multiplyVector3( positionVS );
directionVS.copy( originalLight.matrixWorld.getPosition() );
directionVS.subSelf( originalLight.target.matrixWorld.getPosition() );
directionVS.normalize();
camera.matrixWorldInverse.rotateAxis( directionVS );
uniforms[ "lightPositionVS" ].value.copy( positionVS );
uniforms[ "lightDirectionVS" ].value.copy( directionVS );
uniforms[ "lightAngle" ].value = originalLight.angle; uniforms[ "lightAngle" ].value = originalLight.angle;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册