Skip to content

Commit

Permalink
WebGLDeferredRenderer: added hemisphere light support.
Browse files Browse the repository at this point in the history
  • Loading branch information
alteredq committed Dec 20, 2012
1 parent 94bc3fd commit 1f6ebe7
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 0 deletions.
98 changes: 98 additions & 0 deletions examples/js/ShaderDeferred.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,104 @@ THREE.ShaderDeferred = {

},

"hemisphereLight" : {

uniforms: {

samplerNormalDepth: { type: "t", value: null },
samplerColor: { type: "t", value: null },
matProjInverse: { type: "m4", value: new THREE.Matrix4() },
viewWidth: { type: "f", value: 800 },
viewHeight: { type: "f", value: 600 },

lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
lightColorSky: { type: "c", value: new THREE.Color( 0x000000 ) },
lightColorGround: { type: "c", value: new THREE.Color( 0x000000 ) },
lightIntensity: { type: "f", value: 1.0 }

},

fragmentShader : [

"uniform sampler2D samplerColor;",
"uniform sampler2D samplerNormalDepth;",

"uniform float lightRadius;",
"uniform float lightIntensity;",
"uniform float viewHeight;",
"uniform float viewWidth;",

"uniform vec3 lightColorSky;",
"uniform vec3 lightColorGround;",
"uniform vec3 lightDirectionVS;",

"uniform mat4 matProjInverse;",

THREE.DeferredShaderChunk[ "unpackFloat" ],

"void main() {",

THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
THREE.DeferredShaderChunk[ "computeNormal" ],
THREE.DeferredShaderChunk[ "unpackColorMap" ],

// compute light

"vec3 lightVector = lightDirectionVS;",

// diffuse

"float dotProduct = dot( normal, lightVector );",
"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",

"vec3 hemiColor = mix( lightColorGround, lightColorSky, hemiDiffuseWeight );",

"vec3 diffuse = hemiColor;",

// specular (sky light)

"vec3 hemiHalfVectorSky = normalize( lightVector - vertexPositionVS.xyz );",
"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
"float hemiSpecularWeightSky = max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",

// specular (ground light)

"vec3 lVectorGround = -lightVector;",

"vec3 hemiHalfVectorGround = normalize( lVectorGround - vertexPositionVS.xyz );",
"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
"float hemiSpecularWeightGround = max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",

"float dotProductGround = dot( normal, lVectorGround );",

"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",

"vec3 schlickSky = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, hemiHalfVectorSky ), 5.0 );",
"vec3 schlickGround = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
"vec3 specular = hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",

// combine

"gl_FragColor = vec4( lightIntensity * ( albedo * diffuse + specular ), 1.0 );",

"}"

].join("\n"),

vertexShader : [

"void main() { ",

// full screen quad proxy

"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",

"}"

].join("\n")

},

"emissiveLight" : {

uniforms: {
Expand Down
78 changes: 78 additions & 0 deletions examples/js/renderers/WebGLDeferredRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var pointLightShader = THREE.ShaderDeferred[ "pointLight" ];
var spotLightShader = THREE.ShaderDeferred[ "spotLight" ];
var directionalLightShader = THREE.ShaderDeferred[ "directionalLight" ];
var hemisphereLightShader = THREE.ShaderDeferred[ "hemisphereLight" ];

var compositeShader = THREE.ShaderDeferred[ "composite" ];

Expand Down Expand Up @@ -545,6 +546,72 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {

};

var updateHemisphereLightProxy = function ( lightProxy ) {

var light = lightProxy.properties.originalLight;
var uniforms = lightProxy.material.uniforms;

directionVS.copy( light.matrixWorld.getPosition() );
directionVS.normalize();
camera.matrixWorldInverse.rotateAxis( directionVS );

uniforms[ "lightDirectionVS" ].value.copy( directionVS );

// linear space colors

var intensity = light.intensity * light.intensity;

uniforms[ "lightIntensity" ].value = intensity;
uniforms[ "lightColorSky" ].value.copyGammaToLinear( light.color );
uniforms[ "lightColorGround" ].value.copyGammaToLinear( light.groundColor );

};

var createDeferredHemisphereLight = function ( light ) {

// setup light material

var uniforms = THREE.UniformsUtils.clone( hemisphereLightShader.uniforms );

var materialLight = new THREE.ShaderMaterial( {

uniforms: uniforms,
vertexShader: hemisphereLightShader.vertexShader,
fragmentShader: hemisphereLightShader.fragmentShader,

blending: THREE.AdditiveBlending,
depthWrite: false,
depthTest: false,
transparent: true

} );

uniforms[ "viewWidth" ].value = scaledWidth;
uniforms[ "viewHeight" ].value = scaledHeight;

uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;

// create light proxy mesh

var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );

// keep reference for color and intensity updates

meshLight.properties.originalLight = light;

// keep reference for size reset

resizableMaterials.push( materialLight );

// sync proxy uniforms to the original light

updateHemisphereLightProxy( meshLight );

return meshLight;

};

var createDeferredEmissiveLight = function () {

// setup light material
Expand Down Expand Up @@ -607,6 +674,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var meshLight = createDeferredDirectionalLight( object );
lightSceneFullscreen.add( meshLight );

} else if ( object instanceof THREE.HemisphereLight ) {

var meshLight = createDeferredHemisphereLight( object );
lightSceneFullscreen.add( meshLight );

}

object.properties.deferredInitialized = true;
Expand Down Expand Up @@ -733,6 +805,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {

if ( originalLight ) {

lightProxy.visible = originalLight.visible;

if ( originalLight instanceof THREE.PointLight ) {

updatePointLightProxy( lightProxy );
Expand All @@ -745,6 +819,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {

updateDirectionalLightProxy( lightProxy );

} else if ( originalLight instanceof THREE.HemisphereLight ) {

updateHemisphereLightProxy( lightProxy );

}

}
Expand Down

0 comments on commit 1f6ebe7

Please sign in to comment.