From ea9cfe0cfee0b99cba71687bc88daf32f64fbaff Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 15:05:33 -0400 Subject: [PATCH 01/64] attempt to simplify the phong shaders and lights. --- src/renderers/shaders/ShaderChunk/common.glsl | 73 ++++++------ .../ShaderChunk/lights_phong_fragment.glsl | 107 +++++++----------- .../lights_phong_pars_fragment.glsl | 58 ++++++++-- 3 files changed, 127 insertions(+), 111 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index c7f7d3c0e36f66..21be06acb4a2e5 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -1,5 +1,6 @@ #define PI 3.14159 #define PI2 6.28318 +#define RECIPROCAL_PI 0.31830988618 #define RECIPROCAL_PI2 0.15915494 #define LOG2 1.442695 #define EPSILON 1e-6 @@ -52,6 +53,41 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } +vec3 inputToLinear( in vec3 a ) { + + #ifdef GAMMA_INPUT + + return pow( a, vec3( float( GAMMA_FACTOR ) ) ); + + #else + + return a; + + #endif + +} + +vec3 linearToOutput( in vec3 a ) { + + #ifdef GAMMA_OUTPUT + + return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); + + #else + + return a; + + #endif + +} + + +vec3 BRDF_Lambert( in vec3 diffuseColor, in float dotLN ) { + + return diffuseColor * ( dotLN * RECIPROCAL_PI ); + +} + vec3 F_Schlick( in vec3 specularColor, in float dotLH ) { // Original approximation by Christophe Schlick '94 @@ -80,49 +116,14 @@ float D_BlinnPhong( in float shininess, in float dotNH ) { } -vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in vec3 normal, in vec3 lightDir, in vec3 viewDir ) { - - vec3 halfDir = normalize( lightDir + viewDir ); - - //float dotNL = saturate( dot( normal, lightDir ) ); - //float dotNV = saturate( dot( normal, viewDir ) ); - float dotNH = saturate( dot( normal, halfDir ) ); - float dotLH = saturate( dot( lightDir, halfDir ) ); +vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, in float dotLH ) { vec3 F = F_Schlick( specularColor, dotLH ); - float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); - float D = D_BlinnPhong( shininess, dotNH ); return F * G * D; } -vec3 inputToLinear( in vec3 a ) { - - #ifdef GAMMA_INPUT - - return pow( a, vec3( float( GAMMA_FACTOR ) ) ); - - #else - - return a; - - #endif -} - -vec3 linearToOutput( in vec3 a ) { - - #ifdef GAMMA_OUTPUT - - return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); - - #else - - return a; - - #endif - -} diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 8bdb5f731a7b19..ec69efa0bc2c41 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,34 +1,33 @@ vec3 viewDir = normalize( vViewPosition ); -vec3 totalDiffuseLight = vec3( 0.0 ); -vec3 totalSpecularLight = vec3( 0.0 ); +vec3 totalReflectedLight = vec3( 0.0 ); -#if MAX_POINT_LIGHTS > 0 - - for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - - vec3 lightColor = pointLightColor[ i ]; - - vec3 lightPosition = pointLightPosition[ i ]; - vec3 lVector = lightPosition + vViewPosition.xyz; - vec3 lightDir = normalize( lVector ); +#ifdef METAL - // attenuation + diffuseColor.rgb = diffuseColor.rgb * specular; - float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); +#endif - // diffuse +#if MAX_POINT_LIGHTS > 0 - float cosineTerm = saturate( dot( normal, lightDir ) ); + for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - totalDiffuseLight += lightColor * attenuation * cosineTerm; + vec3 lightDir, lightIntensity; + getSpotLight( i, lightDir, lightIntensity ); - // specular + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir ); + vec3 halfDir = normalize( lightDir + viewDir ); + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + float dotLH = saturate( dot( lightDir, halfDir ) ); - totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm; + totalReflectedLight += ( + BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) + ) * lightIntensity; + } } @@ -38,35 +37,20 @@ vec3 totalSpecularLight = vec3( 0.0 ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightColor = spotLightColor[ i ]; - - vec3 lightPosition = spotLightPosition[ i ]; - vec3 lVector = lightPosition + vViewPosition.xyz; - vec3 lightDir = normalize( lVector ); - - float spotEffect = dot( spotLightDirection[ i ], lightDir ); - - if ( spotEffect > spotLightAngleCos[ i ] ) { - - spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) ); - - // attenuation + vec3 lightDir, lightIntensity; + getSpotLight( i, lightDir, lightIntensity ); - float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - attenuation *= spotEffect; + vec3 halfDir = normalize( lightDir + viewDir ); + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + float dotLH = saturate( dot( lightDir, halfDir ) ); - // diffuse - - float cosineTerm = saturate( dot( normal, lightDir ) ); - - totalDiffuseLight += lightColor * attenuation * cosineTerm; - - // specular - - vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir ); - - totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm; + totalReflectedLight += ( + BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) + ) * lightIntensity; } @@ -78,32 +62,25 @@ vec3 totalSpecularLight = vec3( 0.0 ); for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightColor = directionalLightColor[ i ]; - - vec3 lightDir = directionalLightDirection[ i ]; - - // diffuse - - float cosineTerm = saturate( dot( normal, lightDir ) ); + vec3 lightDir, lightIntensity; + getDirLight( i, lightDir, lightIntensity ); - totalDiffuseLight += lightColor * cosineTerm; + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - // specular + vec3 halfDir = normalize( lightDir + viewDir ); + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + float dotLH = saturate( dot( lightDir, halfDir ) ); - vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir ); + totalReflectedLight += ( + BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) + ) * lightIntensity; - totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm; + } } #endif -#ifdef METAL - - outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) * specular + totalSpecularLight + totalEmissiveLight; - -#else - - outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight; - -#endif +outgoingLight += totalReflectedLight + totalEmissiveLight; diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 043485f1efd8da..205b868309c24e 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -1,10 +1,31 @@ uniform vec3 ambientLightColor; +#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP ) + + varying vec3 vWorldPosition; + +#endif + +varying vec3 vViewPosition; + +#ifndef FLAT_SHADED + + varying vec3 vNormal; + +#endif + #if MAX_DIR_LIGHTS > 0 uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; + #define getDirLight( directionalIndex, lightDir, lightIntensity ) { + + lightDir = directionalLightDirection[ directionalIndex ]; + lightIntensity = directionalLightColor[ directionalIndex ]; + + } + #endif #if MAX_HEMI_LIGHTS > 0 @@ -18,11 +39,22 @@ uniform vec3 ambientLightColor; #if MAX_POINT_LIGHTS > 0 uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; + #define getPointLight( pointIndex, lightDir, lightIntensity ) { + + vec3 lightPosition = pointLightPosition[ pointIndex ]; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + lightIntensity = pointLightColor[ pointIndex ]; + lightIntensity *= calcLightAttenuation( length( lVector ), pointLightDistance[ pointIndex ], pointLightDecay[ pointIndex ] ); + + } + #endif #if MAX_SPOT_LIGHTS > 0 @@ -35,18 +67,24 @@ uniform vec3 ambientLightColor; uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; -#endif - -#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP ) - - varying vec3 vWorldPosition; + #define getSpotLight( spotIndex, lightDir, lightIntensity ) { + + vec3 lightPosition = spotLightPosition[ spotIndex ]; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + float spotEffect = dot( spotLightDirection[ spotIndex ], lightDir ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ spotIndex ] ) ); + + lightIntensity = spotLightColor[ spotIndex ]; + lightIntensity *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLightDistance[ spotIndex ], spotLightDecay[ spotIndex ] ) ); + + } #endif -varying vec3 vViewPosition; -#ifndef FLAT_SHADED - varying vec3 vNormal; -#endif + From d74476069fe23e7e56634fb05c14c976ac75fbcb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 15:13:00 -0400 Subject: [PATCH 02/64] cleaner use of diffuse. --- .../shaders/ShaderChunk/lights_phong_fragment.glsl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index ec69efa0bc2c41..1378d2e9497d93 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -2,9 +2,11 @@ vec3 viewDir = normalize( vViewPosition ); vec3 totalReflectedLight = vec3( 0.0 ); +var diffuse = diffuseColor.rgb; + #ifdef METAL - diffuseColor.rgb = diffuseColor.rgb * specular; + diffuse *= specular; #endif @@ -23,7 +25,7 @@ vec3 totalReflectedLight = vec3( 0.0 ); float dotLH = saturate( dot( lightDir, halfDir ) ); totalReflectedLight += ( - BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_Lambert( diffuse, dotNL ) + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) ) * lightIntensity; @@ -48,7 +50,7 @@ vec3 totalReflectedLight = vec3( 0.0 ); float dotLH = saturate( dot( lightDir, halfDir ) ); totalReflectedLight += ( - BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_Lambert( diffuse, dotNL ) + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) ) * lightIntensity; @@ -73,7 +75,7 @@ vec3 totalReflectedLight = vec3( 0.0 ); float dotLH = saturate( dot( lightDir, halfDir ) ); totalReflectedLight += ( - BRDF_Lambert( diffuseColor.rgb, dotNL ) + + BRDF_Lambert( diffuse, dotNL ) + BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) ) * lightIntensity; From ad75704cd820913b2a32002faddd0b92d5155abf Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 21:36:51 -0400 Subject: [PATCH 03/64] debugging uniforms. --- .../shaders/ShaderChunk/light_pars.glsl | 111 ++++++++++++++++++ .../lights_lambert_pars_vertex.glsl | 36 ------ .../lights_phong_pars_fragment.glsl | 75 ------------ 3 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 src/renderers/shaders/ShaderChunk/light_pars.glsl diff --git a/src/renderers/shaders/ShaderChunk/light_pars.glsl b/src/renderers/shaders/ShaderChunk/light_pars.glsl new file mode 100644 index 00000000000000..529414a0e88ef3 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/light_pars.glsl @@ -0,0 +1,111 @@ + +#if MAX_DIR_LIGHTS > 0 + + //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; + //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; + + struct DirectionalLight { + vec3 color; + vec3 direction; + }; + + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; + + void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { + + lightDir = directionalLight.direction; + lightColor = directionalLight.color; + + } + +#endif + +#if MAX_HEMI_LIGHTS > 0 + + //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; + + struct HemisphericLight { + vec3 skyColor; + vec3 groundColor; + vec3 direction; + }; + + uniform HemisphericLight hemisphericLights[ MAX_HEMI_LIGHTS ]; + +#endif + +#if MAX_POINT_LIGHTS > 0 + + //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; + //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; + + struct PointLight { + vec3 color; + vec3 position; + float decay; + float cutoffDistance; + }; + + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; + + void getPointLight( const in pointLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = pointLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + lightColor = pointLight.color[ pointIndex ]; + lightColor *= calcLightAttenuation( length( lVector ), pointLight.cutoffDistance, pointLight.decay ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; + + struct SpotLight { + vec3 color; + vec3 position; + vec3 direction; + float angleCos; + float exponent; + float cutoffDistance; + float decay; + }; + + uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; + + void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = spotLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + float spotEffect = dot( spotLight.direction, lightDir ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); + + lightColor = spotLight.color; + lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + + } + +#endif + + + + + diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index 47d1a0dd5511d6..7024ef54773439 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -1,37 +1 @@ uniform vec3 ambientLightColor; - -#if MAX_DIR_LIGHTS > 0 - - uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; - uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; - uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; - uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; - uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; - uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; - uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; - uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; - -#endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 205b868309c24e..109bc9fc7c23ba 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -13,78 +13,3 @@ varying vec3 vViewPosition; varying vec3 vNormal; #endif - -#if MAX_DIR_LIGHTS > 0 - - uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; - uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; - - #define getDirLight( directionalIndex, lightDir, lightIntensity ) { - - lightDir = directionalLightDirection[ directionalIndex ]; - lightIntensity = directionalLightColor[ directionalIndex ]; - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; - uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; - uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; - uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; - - #define getPointLight( pointIndex, lightDir, lightIntensity ) { - - vec3 lightPosition = pointLightPosition[ pointIndex ]; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - lightIntensity = pointLightColor[ pointIndex ]; - lightIntensity *= calcLightAttenuation( length( lVector ), pointLightDistance[ pointIndex ], pointLightDecay[ pointIndex ] ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; - uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; - uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; - uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; - uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; - - #define getSpotLight( spotIndex, lightDir, lightIntensity ) { - - vec3 lightPosition = spotLightPosition[ spotIndex ]; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - float spotEffect = dot( spotLightDirection[ spotIndex ], lightDir ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ spotIndex ] ) ); - - lightIntensity = spotLightColor[ spotIndex ]; - lightIntensity *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLightDistance[ spotIndex ], spotLightDecay[ spotIndex ] ) ); - - } - -#endif - - - - - From 74d3aa3f12120c906d190e621cb1260e88932757 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 22:32:27 -0400 Subject: [PATCH 04/64] parse arrays of struct uniforms, code cleanup. --- .../shaders/ShaderChunk/light_pars.glsl | 4 +- .../lights_lambert_pars_vertex.glsl | 112 ++++++++++++++++++ .../ShaderChunk/lights_phong_fragment.glsl | 8 +- .../lights_phong_pars_fragment.glsl | 112 ++++++++++++++++++ src/renderers/shaders/ShaderLib.js | 2 + src/renderers/webgl/WebGLProgram.js | 35 +++++- 6 files changed, 263 insertions(+), 10 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/light_pars.glsl b/src/renderers/shaders/ShaderChunk/light_pars.glsl index 529414a0e88ef3..94bf30e1057a3a 100644 --- a/src/renderers/shaders/ShaderChunk/light_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/light_pars.glsl @@ -26,13 +26,13 @@ //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - struct HemisphericLight { + struct HemisphereLight { vec3 skyColor; vec3 groundColor; vec3 direction; }; - uniform HemisphericLight hemisphericLights[ MAX_HEMI_LIGHTS ]; + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index 7024ef54773439..67a333fedb6c7b 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -1 +1,113 @@ uniform vec3 ambientLightColor; + + +#if MAX_DIR_LIGHTS > 0 + + //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; + //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; + + struct DirectionalLight { + vec3 color; + vec3 direction; + }; + + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; + + void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { + + lightDir = directionalLight.direction; + lightColor = directionalLight.color; + + } + +#endif + +#if MAX_HEMI_LIGHTS > 0 + + //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; + + struct HemisphereLight { + vec3 skyColor; + vec3 groundColor; + vec3 direction; + }; + + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + +#endif + +#if MAX_POINT_LIGHTS > 0 + + //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; + //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; + + struct PointLight { + vec3 color; + vec3 position; + float decay; + float distance; + }; + + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; + + void getPointLight( const in PointLight pointLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = pointLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + lightColor = pointLight.color; + lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; + + struct SpotLight { + vec3 color; + vec3 position; + vec3 direction; + float angleCos; + float exponent; + float distance; + float decay; + }; + + uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; + + void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = spotLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + float spotEffect = dot( spotLight.direction, lightDir ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); + + lightColor = spotLight.color; + lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + + } + +#endif + + + + + diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 1378d2e9497d93..6d6dc100c27493 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -2,7 +2,7 @@ vec3 viewDir = normalize( vViewPosition ); vec3 totalReflectedLight = vec3( 0.0 ); -var diffuse = diffuseColor.rgb; +vec3 diffuse = diffuseColor.rgb; #ifdef METAL @@ -15,7 +15,7 @@ var diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getSpotLight( i, lightDir, lightIntensity ); + getPointLight( pointLights[i], lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { @@ -40,7 +40,7 @@ var diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getSpotLight( i, lightDir, lightIntensity ); + getSpotLight( spotLights[i], lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { @@ -65,7 +65,7 @@ var diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getDirLight( i, lightDir, lightIntensity ); + getDirLight( directionalLights[i], lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 109bc9fc7c23ba..88ff4a1db0a1b0 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -13,3 +13,115 @@ varying vec3 vViewPosition; varying vec3 vNormal; #endif + + +#if MAX_DIR_LIGHTS > 0 + + //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; + //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; + + struct DirectionalLight { + vec3 color; + vec3 direction; + }; + + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; + + void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { + + lightDir = directionalLight.direction; + lightColor = directionalLight.color; + + } + +#endif + +#if MAX_HEMI_LIGHTS > 0 + + //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; + //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; + + struct HemisphereLight { + vec3 skyColor; + vec3 groundColor; + vec3 direction; + }; + + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + +#endif + +#if MAX_POINT_LIGHTS > 0 + + //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; + //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; + //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; + + struct PointLight { + vec3 color; + vec3 position; + float decay; + float distance; + }; + + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; + + void getPointLight( const in PointLight pointLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = pointLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + lightColor = pointLight.color; + lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; + //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; + //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; + + struct SpotLight { + vec3 color; + vec3 position; + vec3 direction; + float angleCos; + float exponent; + float distance; + float decay; + }; + + uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; + + void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = spotLight.position; + + vec3 lVector = lightPosition + vViewPosition.xyz; + lightDir = normalize( lVector ); + + float spotEffect = dot( spotLight.direction, lightDir ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); + + lightColor = spotLight.color; + lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + + } + +#endif + + + + + diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 4f342cfc90f4cc..ade58560d9b164 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -143,6 +143,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "uv2_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], THREE.ShaderChunk[ "lights_lambert_pars_vertex" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "color_pars_vertex" ], THREE.ShaderChunk[ "morphtarget_pars_vertex" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], @@ -347,6 +348,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "envmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], THREE.ShaderChunk[ "normalmap_pars_fragment" ], diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index cae2e52d420022..a79730ca5942cb 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -25,6 +25,9 @@ THREE.WebGLProgram = ( function () { var uniforms = {}; var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); + + var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; + var arrayRe = /^([\w\d_]+)\[0\]$/; for ( var i = 0; i < n; i ++ ) { @@ -32,19 +35,43 @@ THREE.WebGLProgram = ( function () { var name = info.name; var location = gl.getUniformLocation( program, name ); - // console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); + console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); - var suffixPos = name.lastIndexOf( '[0]' ); - if ( suffixPos !== - 1 && suffixPos === name.length - 3 ) { + var matches = arrayStructRe.exec(name); + if( matches ) { - uniforms[ name.substr( 0, suffixPos ) ] = location; + var arrayName = matches[1]; + var arrayIndex = matches[2]; + var arrayProperty = matches[3]; + var uniformsArray = uniforms[ arrayName ]; + if( ! uniformsArray ) { + uniformsArray = uniforms[ arrayName ] = []; + } + var uniformsArrayIndex = uniformsArray[ arrayIndex ]; + if( ! uniformsArrayIndex ) { + uniformsArrayIndex = uniformsArray[ arrayIndex ] = {}; + } + uniformsArrayIndex[ arrayProperty ] = location; + + continue; + } + + matches = arrayRe.exec(name) + if( matches ) { + + var arrayName = matches[1]; + + uniforms[ arrayName ] = location; + + continue; } uniforms[ name ] = location; } + console.log("uniforms", uniforms); return uniforms; } From e889e6b980cc411a72a6fd3bba787323b106d97c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 22:57:14 -0400 Subject: [PATCH 05/64] add support for structs not in arrays in WebGLProgram. --- .../ShaderChunk/lights_phong_fragment.glsl | 3 +- .../lights_phong_pars_fragment.glsl | 5 +++ src/renderers/shaders/UniformsLib.js | 32 +++++++++---------- src/renderers/webgl/WebGLProgram.js | 20 +++++++++++- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 6d6dc100c27493..7fe00dff9af115 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -19,7 +19,8 @@ vec3 diffuse = diffuseColor.rgb; if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - vec3 halfDir = normalize( lightDir + viewDir ); + + vec3 halfDir = normalize( lightDir + viewDir ) * singleTestPointLight.distance; float dotNL = saturate( dot( normal, lightDir ) ); float dotNH = saturate( dot( normal, halfDir ) ); float dotLH = saturate( dot( lightDir, halfDir ) ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 88ff4a1db0a1b0..c9ae40a9e24d5d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -25,6 +25,8 @@ varying vec3 vViewPosition; vec3 direction; }; + uniform DirectionalLight singleTestDirLight; + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { @@ -66,6 +68,9 @@ varying vec3 vViewPosition; float distance; }; + + uniform PointLight singleTestPointLight; + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; void getPointLight( const in PointLight pointLight, out vec3 lightDir, out vec3 lightColor ) { diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index aae6c21f471738..519de435b497ca 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -80,22 +80,22 @@ THREE.UniformsLib = { "directionalLightDirection" : { type: "fv", value: [] }, "directionalLightColor" : { type: "fv", value: [] }, - "hemisphereLightDirection" : { type: "fv", value: [] }, - "hemisphereLightSkyColor" : { type: "fv", value: [] }, - "hemisphereLightGroundColor" : { type: "fv", value: [] }, - - "pointLightColor" : { type: "fv", value: [] }, - "pointLightPosition" : { type: "fv", value: [] }, - "pointLightDistance" : { type: "fv1", value: [] }, - "pointLightDecay" : { type: "fv1", value: [] }, - - "spotLightColor" : { type: "fv", value: [] }, - "spotLightPosition" : { type: "fv", value: [] }, - "spotLightDirection" : { type: "fv", value: [] }, - "spotLightDistance" : { type: "fv1", value: [] }, - "spotLightAngleCos" : { type: "fv1", value: [] }, - "spotLightExponent" : { type: "fv1", value: [] }, - "spotLightDecay" : { type: "fv1", value: [] } + "hemisphereLightDirection" : { type: "fv", value: [], array: 'hemisphereLights', property: 'direction' }, + "hemisphereLightSkyColor" : { type: "fv", value: [], array: 'hemisphereLights', property: 'skyColor' }, + "hemisphereLightGroundColor" : { type: "fv", value: [], array: 'hemisphereLights', property: 'groundColor' }, + + "pointLightColor" : { type: "fv", value: [], array: 'pointLights', property: 'color' }, + "pointLightPosition" : { type: "fv", value: [], array: 'pointLights', property: 'position' }, + "pointLightDistance" : { type: "fv1", value: [], array: 'pointLights', property: 'distance' }, + "pointLightDecay" : { type: "fv1", value: [], array: 'pointLights', property: 'decay' }, + + "spotLightColor" : { type: "fv", value: [], array: 'spotLights', property: 'color' }, + "spotLightPosition" : { type: "fv", value: [], array: 'spotLights', property: 'position' }, + "spotLightDirection" : { type: "fv", value: [], array: 'spotLights', property: 'direction' }, + "spotLightDistance" : { type: "fv1", value: [], array: 'spotLights', property: 'distance' }, + "spotLightAngleCos" : { type: "fv1", value: [], array: 'spotLights', property: 'angleCos' }, + "spotLightExponent" : { type: "fv1", value: [], array: 'spotLights', property: 'exponent' }, + "spotLightDecay" : { type: "fv1", value: [], array: 'spotLights', property: 'decay' } }, diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index a79730ca5942cb..6483fa94c34cdc 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -26,6 +26,9 @@ THREE.WebGLProgram = ( function () { var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); + + // TODO: Combine. + var structRe = /^([\w\d_]+)\.([\w\d_]+)$/; var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; var arrayRe = /^([\w\d_]+)\[0\]$/; @@ -37,7 +40,22 @@ THREE.WebGLProgram = ( function () { console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); - var matches = arrayStructRe.exec(name); + var matches = structRe.exec(name); + if( matches ) { + + var structName = matches[1]; + var structProperty = matches[2]; + + var uniformsStruct = uniforms[ structName ]; + if( ! uniformsStruct ) { + uniformsStruct = uniforms[ structName ] = {}; + } + uniformsStruct[ structProperty ] = location; + + continue; + } + + matches = arrayStructRe.exec(name); if( matches ) { var arrayName = matches[1]; From c1df1730d3296940c25531606fcdb13569a36bae Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 22:57:49 -0400 Subject: [PATCH 06/64] ways to define ThreeJS "uniforms" for structs and struct arrays. ways to set those values. still missing some glue code. --- src/renderers/WebGLRenderer.js | 76 ++++++++++++++++++++++++++++ src/renderers/shaders/UniformsLib.js | 38 +++++++------- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 66e775ce6748cb..0433ea10504fc7 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2140,6 +2140,82 @@ THREE.WebGLRenderer = function ( parameters ) { break; + case 'fs': + + _gl.uniform1f( location[ uniform.property ], value ); + + break; + + case 'v2s': + + _gl.uniform2f( location[ uniform.property ], value.x, value.y ); + + break; + + case 'v3s': + + _gl.uniform3f( location[ uniform.property ], value.x, value.y, value.z ); + + break; + + case 'v4s': + + _gl.uniform4f( location[ uniform.property ], value.x, value.y, value.z, value.w ); + + break; + + case 'cs': + + _gl.uniform3f( location[ uniform.property ], value.r, value.g, value.b ); + + break; + + case 'fsa': + + for( var i = 0; i < value.length; i ++ ) { + + _gl.uniform1f( location[ i ][ uniform.property ], value ); + + } + + break; + + case 'v2sa': + + for( var i = 0; i < value.length; i ++ ) { + + _gl.uniform2f( location[ i ][ uniform.property ], value.x, value.y ); + + } + break; + + case 'v3sa': + + for( var i = 0; i < value.length; i ++ ) { + + _gl.uniform3f( location[ i ][ uniform.property ], value.x, value.y, value.z ); + + } + break; + + case 'v4sa': + + for( var i = 0; i < value.length; i ++ ) { + + _gl.uniform4f( location[ i ][ uniform.property ], value.x, value.y, value.z, value.w ); + + } + break; + + case 'csa': + + for( var i = 0; i < value.length; i ++ ) { + + _gl.uniform3f( location[ i ][ uniform.property ], value.r, value.g, value.b ); + + } + break; + case 'iv1': // flat array of integers (JS or typed array) diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index 519de435b497ca..bfa7bfd76ddbc3 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -77,25 +77,25 @@ THREE.UniformsLib = { "ambientLightColor" : { type: "fv", value: [] }, - "directionalLightDirection" : { type: "fv", value: [] }, - "directionalLightColor" : { type: "fv", value: [] }, - - "hemisphereLightDirection" : { type: "fv", value: [], array: 'hemisphereLights', property: 'direction' }, - "hemisphereLightSkyColor" : { type: "fv", value: [], array: 'hemisphereLights', property: 'skyColor' }, - "hemisphereLightGroundColor" : { type: "fv", value: [], array: 'hemisphereLights', property: 'groundColor' }, - - "pointLightColor" : { type: "fv", value: [], array: 'pointLights', property: 'color' }, - "pointLightPosition" : { type: "fv", value: [], array: 'pointLights', property: 'position' }, - "pointLightDistance" : { type: "fv1", value: [], array: 'pointLights', property: 'distance' }, - "pointLightDecay" : { type: "fv1", value: [], array: 'pointLights', property: 'decay' }, - - "spotLightColor" : { type: "fv", value: [], array: 'spotLights', property: 'color' }, - "spotLightPosition" : { type: "fv", value: [], array: 'spotLights', property: 'position' }, - "spotLightDirection" : { type: "fv", value: [], array: 'spotLights', property: 'direction' }, - "spotLightDistance" : { type: "fv1", value: [], array: 'spotLights', property: 'distance' }, - "spotLightAngleCos" : { type: "fv1", value: [], array: 'spotLights', property: 'angleCos' }, - "spotLightExponent" : { type: "fv1", value: [], array: 'spotLights', property: 'exponent' }, - "spotLightDecay" : { type: "fv1", value: [], array: 'spotLights', property: 'decay' } + "directionalLightDirection" : { type: "v3sa", value: [], name: 'hemisphereLights', property: 'direction' }, + "directionalLightColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'direction' }, + + "hemisphereLightDirection" : { type: "v3sa", value: [], name: 'hemisphereLights', property: 'direction' }, + "hemisphereLightSkyColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'skyColor' }, + "hemisphereLightGroundColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'groundColor' }, + + "pointLightColor" : { type: "csa", value: [], name: 'pointLights', property: 'color' }, + "pointLightPosition" : { type: "v3sa", value: [], name: 'pointLights', property: 'position' }, + "pointLightDistance" : { type: "fsa", value: [], name: 'pointLights', property: 'distance' }, + "pointLightDecay" : { type: "fsa", value: [], name: 'pointLights', property: 'decay' }, + + "spotLightColor" : { type: "csa", value: [], name: 'spotLights', property: 'color' }, + "spotLightPosition" : { type: "v3sa", value: [], name: 'spotLights', property: 'position' }, + "spotLightDirection" : { type: "v3sa", value: [], name: 'spotLights', property: 'direction' }, + "spotLightDistance" : { type: "fsa", value: [], name: 'spotLights', property: 'distance' }, + "spotLightAngleCos" : { type: "fsa", value: [], name: 'spotLights', property: 'angleCos' }, + "spotLightExponent" : { type: "fsa", value: [], name: 'spotLights', property: 'exponent' }, + "spotLightDecay" : { type: "fsa", value: [], name: 'spotLights', property: 'decay' } }, From 7985c8b0abf91dc81eb528756f6692abb43cbee3 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 9 Oct 2015 23:43:43 -0400 Subject: [PATCH 07/64] more work on supporting struct and struct uniform types. --- src/renderers/WebGLRenderer.js | 265 ++++++++++----------------- src/renderers/shaders/UniformsLib.js | 47 +++-- 2 files changed, 120 insertions(+), 192 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 0433ea10504fc7..29a4a1e838761e 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1915,26 +1915,13 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.ambientLightColor.value = lights.ambient; - uniforms.directionalLightColor.value = lights.directional.colors; - uniforms.directionalLightDirection.value = lights.directional.positions; - - uniforms.pointLightColor.value = lights.point.colors; - uniforms.pointLightPosition.value = lights.point.positions; - uniforms.pointLightDistance.value = lights.point.distances; - uniforms.pointLightDecay.value = lights.point.decays; - - uniforms.spotLightColor.value = lights.spot.colors; - uniforms.spotLightPosition.value = lights.spot.positions; - uniforms.spotLightDistance.value = lights.spot.distances; - uniforms.spotLightDirection.value = lights.spot.directions; - uniforms.spotLightAngleCos.value = lights.spot.anglesCos; - uniforms.spotLightExponent.value = lights.spot.exponents; - uniforms.spotLightDecay.value = lights.spot.decays; - - uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors; - uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors; - uniforms.hemisphereLightDirection.value = lights.hemi.positions; + uniforms.directionalLights.value = lights.directional; + uniforms.pointLights.value = lights.point; + + uniforms.spotLights.value = lights.spot; + + uniforms.hemisphereLights.value = lights.hemi; } // If uniforms are marked as clean, they don't need to be loaded to the GPU. @@ -2140,80 +2127,68 @@ THREE.WebGLRenderer = function ( parameters ) { break; - case 'fs': - - _gl.uniform1f( location[ uniform.property ], value ); - - break; - - case 'v2s': - - _gl.uniform2f( location[ uniform.property ], value.x, value.y ); - - break; - - case 'v3s': - - _gl.uniform3f( location[ uniform.property ], value.x, value.y, value.z ); - - break; - - case 'v4s': - - _gl.uniform4f( location[ uniform.property ], value.x, value.y, value.z, value.w ); - - break; - - case 'cs': - - _gl.uniform3f( location[ uniform.property ], value.r, value.g, value.b ); - - break; - - case 'fsa': - - for( var i = 0; i < value.length; i ++ ) { - - _gl.uniform1f( location[ i ][ uniform.property ], value ); + case 's': + + // TODO: Optimize this. + for( var j = 0; j < uniform.properties.length; j ++ ) { + + var property = uniform.properties[j]; + var uniformProperty = location[ property ]; + var valueProperty = values[ property ]; + switch( property.type ) { + case 'f': + _gl.uniform1f( uniformProperty, valueProperty ); + break; + case 'v2': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y ); + break; + case 'v3': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z ); + break; + case 'v4': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); + break; + case 'c': + _gl.uniform1f( uniformProperty, valueProperty.r, valueProperty.g, valueProperty.b ); + break; + }; } break; - case 'v2sa': + case 'sa': + // TODO: Optimize this. for( var i = 0; i < value.length; i ++ ) { - - _gl.uniform2f( location[ i ][ uniform.property ], value.x, value.y ); - - } - break; - case 'v3sa': - - for( var i = 0; i < value.length; i ++ ) { + for( var j = 0; j < uniform.properties.length; j ++ ) { + + var property = uniform.properties[j]; + var uniformProperty = location[ i ][ property ]; + var valueProperty = value[i][ property ]; + switch( property.type ) { + case 'f': + _gl.uniform1f( uniformProperty, valueProperty ); + break; + case 'v2': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y ); + break; + case 'v3': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z ); + break; + case 'v4': + _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); + break; + case 'c': + _gl.uniform1f( uniformProperty, valueProperty.r, valueProperty.g, valueProperty.b ); + break; + }; - _gl.uniform3f( location[ i ][ uniform.property ], value.x, value.y, value.z ); + } } - break; - - case 'v4sa': - - for( var i = 0; i < value.length; i ++ ) { - - _gl.uniform4f( location[ i ][ uniform.property ], value.x, value.y, value.z, value.w ); - } - break; - - case 'csa': - - for( var i = 0; i < value.length; i ++ ) { - - _gl.uniform3f( location[ i ][ uniform.property ], value.r, value.g, value.b ); - - } break; case 'iv1': @@ -2455,40 +2430,17 @@ THREE.WebGLRenderer = function ( parameters ) { viewMatrix = camera.matrixWorldInverse, - dirColors = zlights.directional.colors, - dirPositions = zlights.directional.positions, - - pointColors = zlights.point.colors, - pointPositions = zlights.point.positions, - pointDistances = zlights.point.distances, - pointDecays = zlights.point.decays, - - spotColors = zlights.spot.colors, - spotPositions = zlights.spot.positions, - spotDistances = zlights.spot.distances, - spotDirections = zlights.spot.directions, - spotAnglesCos = zlights.spot.anglesCos, - spotExponents = zlights.spot.exponents, - spotDecays = zlights.spot.decays, - - hemiSkyColors = zlights.hemi.skyColors, - hemiGroundColors = zlights.hemi.groundColors, - hemiPositions = zlights.hemi.positions, - - dirLength = 0, - pointLength = 0, - spotLength = 0, - hemiLength = 0, - - dirCount = 0, - pointCount = 0, - spotCount = 0, - hemiCount = 0, - - dirOffset = 0, - pointOffset = 0, - spotOffset = 0, - hemiOffset = 0; + function adjustArray( array, newLength ) { + if( array.length !== newLength ) { + return Array( newLength ); + } + return array; + } + + var directionalLights = adjustArray( zlights.directional ); + var pointLights = adjustArray( zlights.point ); + var spotLights = adjustArray( zlights.spot ); + var hemisphereLights = adjustArray( zlights.hemi ); for ( l = 0, ll = lights.length; l < ll; l ++ ) { @@ -2510,103 +2462,70 @@ THREE.WebGLRenderer = function ( parameters ) { } else if ( light instanceof THREE.DirectionalLight ) { - dirCount += 1; + var directionalLight = directionalLights[i]; - if ( ! light.visible ) continue; + if ( ! light.visible ) { + directionlLight.color = new THREE.Color( 0x000000 ); + continue; + } _direction.setFromMatrixPosition( light.matrixWorld ); _vector3.setFromMatrixPosition( light.target.matrixWorld ); _direction.sub( _vector3 ); _direction.transformDirection( viewMatrix ); - dirOffset = dirLength * 3; - - dirPositions[ dirOffset + 0 ] = _direction.x; - dirPositions[ dirOffset + 1 ] = _direction.y; - dirPositions[ dirOffset + 2 ] = _direction.z; - - setColorLinear( dirColors, dirOffset, color, intensity ); - - dirLength += 1; + directionlLight.position = _direction.clone(); + directionlLight.color = color.clone().multiplyScalar( intensity ); + directionlLight.distance = distance; } else if ( light instanceof THREE.PointLight ) { - pointCount += 1; - if ( ! light.visible ) continue; - pointOffset = pointLength * 3; - - setColorLinear( pointColors, pointOffset, color, intensity ); - _vector3.setFromMatrixPosition( light.matrixWorld ); _vector3.applyMatrix4( viewMatrix ); - pointPositions[ pointOffset + 0 ] = _vector3.x; - pointPositions[ pointOffset + 1 ] = _vector3.y; - pointPositions[ pointOffset + 2 ] = _vector3.z; + var pointLight = pointLights[i]; - // distance is 0 if decay is 0, because there is no attenuation at all. - pointDistances[ pointLength ] = distance; - pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; - - pointLength += 1; + pointLight.position = _vector3.clone(); + pointLight.color = color.clone().multiplyScalar( intensity ); + pointLight.distance = distance; + pointLight.decay = ( light.distance === 0 ) ? 0.0 : light.decay; } else if ( light instanceof THREE.SpotLight ) { - spotCount += 1; - if ( ! light.visible ) continue; - spotOffset = spotLength * 3; - - setColorLinear( spotColors, spotOffset, color, intensity ); + var spotLight = spotLights[i]; _direction.setFromMatrixPosition( light.matrixWorld ); _vector3.copy( _direction ).applyMatrix4( viewMatrix ); - spotPositions[ spotOffset + 0 ] = _vector3.x; - spotPositions[ spotOffset + 1 ] = _vector3.y; - spotPositions[ spotOffset + 2 ] = _vector3.z; - - spotDistances[ spotLength ] = distance; + spotLight.position = _vector3.clone(); + spotLight.color = color.clone().multiplyScalar( intensity ); + spotLight.distance = distance; _vector3.setFromMatrixPosition( light.target.matrixWorld ); _direction.sub( _vector3 ); _direction.transformDirection( viewMatrix ); - spotDirections[ spotOffset + 0 ] = _direction.x; - spotDirections[ spotOffset + 1 ] = _direction.y; - spotDirections[ spotOffset + 2 ] = _direction.z; - - spotAnglesCos[ spotLength ] = Math.cos( light.angle ); - spotExponents[ spotLength ] = light.exponent; - spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay; - - spotLength += 1; + spotLight.direction = _direction.clone(); + spotLight.angleCos = Math.cos( light.angle ); + spotLight.exponent = light.exponent; + spotLight.decay = ( light.distance === 0 ) ? 0.0 : light.decay; } else if ( light instanceof THREE.HemisphereLight ) { - hemiCount += 1; - if ( ! light.visible ) continue; _direction.setFromMatrixPosition( light.matrixWorld ); _direction.transformDirection( viewMatrix ); - hemiOffset = hemiLength * 3; - - hemiPositions[ hemiOffset + 0 ] = _direction.x; - hemiPositions[ hemiOffset + 1 ] = _direction.y; - hemiPositions[ hemiOffset + 2 ] = _direction.z; - - skyColor = light.color; - groundColor = light.groundColor; - - setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); - setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); + var hemisphereLight = hemisphereLights[i]; - hemiLength += 1; + spotLight.position = _direction.clone(); + spotLight.skyColor = light.color.clone().multiplyScalar( intensity ); + spotLight.groundColor = light.groundColor.clone().multiplyScalar( intensity ); } diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index bfa7bfd76ddbc3..30eb7de09679e8 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -77,25 +77,34 @@ THREE.UniformsLib = { "ambientLightColor" : { type: "fv", value: [] }, - "directionalLightDirection" : { type: "v3sa", value: [], name: 'hemisphereLights', property: 'direction' }, - "directionalLightColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'direction' }, - - "hemisphereLightDirection" : { type: "v3sa", value: [], name: 'hemisphereLights', property: 'direction' }, - "hemisphereLightSkyColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'skyColor' }, - "hemisphereLightGroundColor" : { type: "csa", value: [], name: 'hemisphereLights', property: 'groundColor' }, - - "pointLightColor" : { type: "csa", value: [], name: 'pointLights', property: 'color' }, - "pointLightPosition" : { type: "v3sa", value: [], name: 'pointLights', property: 'position' }, - "pointLightDistance" : { type: "fsa", value: [], name: 'pointLights', property: 'distance' }, - "pointLightDecay" : { type: "fsa", value: [], name: 'pointLights', property: 'decay' }, - - "spotLightColor" : { type: "csa", value: [], name: 'spotLights', property: 'color' }, - "spotLightPosition" : { type: "v3sa", value: [], name: 'spotLights', property: 'position' }, - "spotLightDirection" : { type: "v3sa", value: [], name: 'spotLights', property: 'direction' }, - "spotLightDistance" : { type: "fsa", value: [], name: 'spotLights', property: 'distance' }, - "spotLightAngleCos" : { type: "fsa", value: [], name: 'spotLights', property: 'angleCos' }, - "spotLightExponent" : { type: "fsa", value: [], name: 'spotLights', property: 'exponent' }, - "spotLightDecay" : { type: "fsa", value: [], name: 'spotLights', property: 'decay' } + "directionalLights" : { type: "sa", value: [], properties: { + "direction": { type: "v3" }, + "color": { type: "c" } + } }; + + "hemisphereLights" : { type: "sa", value: [], properties: { + "direction": { type: "v3" }, + "skyColor": { type: "v3" }, + "groundColor": { type: "v3" } + } }; + + "pointLights" : { type: "sa", value: [], properties: { + "color": { type: "c" }, + "position": { type: "v3" }, + "direction": { type: "v3" }, + "distance": { type: "f" } + } }; + + "spotLights" : { type: "sa", value: [], properties: { + "color": { type: "c" }, + "position": { type: "v3" }, + "direction": { type: "v3" }, + "distance": { type: "f" }, + "angleCos": { type: "f" }, + "exponent": { type: "f" }, + "decay": { type: "f" } + } }; + }, From 8c5bc5281928ffa88fec1c64a292b0b6a2323922 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 00:09:28 -0400 Subject: [PATCH 08/64] cleaner and more GC efficient. --- src/renderers/WebGLRenderer.js | 130 +++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 53 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 29a4a1e838761e..ec1c2adaebaf77 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2422,7 +2422,7 @@ THREE.WebGLRenderer = function ( parameters ) { var l, ll, light, r = 0, g = 0, b = 0, - color, skyColor, groundColor, + color, intensity, distance, @@ -2430,17 +2430,10 @@ THREE.WebGLRenderer = function ( parameters ) { viewMatrix = camera.matrixWorldInverse, - function adjustArray( array, newLength ) { - if( array.length !== newLength ) { - return Array( newLength ); - } - return array; - } - - var directionalLights = adjustArray( zlights.directional ); - var pointLights = adjustArray( zlights.point ); - var spotLights = adjustArray( zlights.spot ); - var hemisphereLights = adjustArray( zlights.hemi ); + zlights.directional = []; + zlights.point = []; + zlights.spot = []; + zlights.hemi = []; for ( l = 0, ll = lights.length; l < ll; l ++ ) { @@ -2462,10 +2455,18 @@ THREE.WebGLRenderer = function ( parameters ) { } else if ( light instanceof THREE.DirectionalLight ) { - var directionalLight = directionalLights[i]; + if( ! light.__webglUniforms ) { + light.__webglUniforms = { + position: new THREE.Vector3(), + color: new THREE.Color(), + distance: 0 + } + } + + var lightUniforms = directionalLights[i] = light.__webglUniforms; if ( ! light.visible ) { - directionlLight.color = new THREE.Color( 0x000000 ); + lightUniforms.color.setRGB( 0, 0, 0 ); continue; } @@ -2474,77 +2475,100 @@ THREE.WebGLRenderer = function ( parameters ) { _direction.sub( _vector3 ); _direction.transformDirection( viewMatrix ); - directionlLight.position = _direction.clone(); - directionlLight.color = color.clone().multiplyScalar( intensity ); - directionlLight.distance = distance; + lightUniforms.position.copy( _direction ); + lightUniforms.color.copy( color ).multiplyScalar( intensity ); + lightUniforms.distance = distance; } else if ( light instanceof THREE.PointLight ) { - if ( ! light.visible ) continue; + if( ! light.__webglUniforms ) { + light.__webglUniforms = { + position: new THREE.Vector3(), + color: new THREE.Color(), + distance: 0, + decay: 0 + } + } + + var lightUniforms = pointLights[i] = light.__webglUniforms; + + if ( ! light.visible ) { + lightUniforms.color.setRGB( 0, 0, 0 ); + continue; + } _vector3.setFromMatrixPosition( light.matrixWorld ); _vector3.applyMatrix4( viewMatrix ); - var pointLight = pointLights[i]; - - pointLight.position = _vector3.clone(); - pointLight.color = color.clone().multiplyScalar( intensity ); - pointLight.distance = distance; - pointLight.decay = ( light.distance === 0 ) ? 0.0 : light.decay; + lightUniforms.position.copy( _vector3 ); + lightUniforms.color.copy( color ).multiplyScalar( intensity ); + lightUniforms.distance = distance; + lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; } else if ( light instanceof THREE.SpotLight ) { - if ( ! light.visible ) continue; + if( ! light.__webglUniforms ) { + light.__webglUniforms = { + position: new THREE.Vector3(), + direction: new THREE.Vector3(), + color: new THREE.Color(), + distance: 0, + decay: 0, + angleCos: 0 + } + } + + var lightUniforms = spotLights[i] = light.__webglUniforms; - var spotLight = spotLights[i]; + if ( ! light.visible ) { + lightUniforms.color.setRGB( 0, 0, 0 ); + continue; + } _direction.setFromMatrixPosition( light.matrixWorld ); _vector3.copy( _direction ).applyMatrix4( viewMatrix ); - spotLight.position = _vector3.clone(); - spotLight.color = color.clone().multiplyScalar( intensity ); - spotLight.distance = distance; + lightUniforms.position.copy( _vector3 ); + lightUniforms.color.copy( color ).multiplyScalar( intensity ); + lightUniforms.distance = distance; _vector3.setFromMatrixPosition( light.target.matrixWorld ); _direction.sub( _vector3 ); _direction.transformDirection( viewMatrix ); - spotLight.direction = _direction.clone(); - spotLight.angleCos = Math.cos( light.angle ); - spotLight.exponent = light.exponent; - spotLight.decay = ( light.distance === 0 ) ? 0.0 : light.decay; + lightUniforms.direction.copy( _direction); + lightUniforms.angleCos = Math.cos( light.angle ); + lightUniforms.exponent = light.exponent; + lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; } else if ( light instanceof THREE.HemisphereLight ) { - if ( ! light.visible ) continue; + if( ! light.__webglUniforms ) { + light.__webglUniforms = { + position: new THREE.Vector3(), + skyColor: new THREE.Color(), + groundColor: new THREE.Color() + } + } + + var lightUniforms = hemisphereLights[i] = light.__webglUniforms; + + if ( ! light.visible ) { + lightUniforms.skyColor.setRGB( 0, 0, 0 ); + continue; + } _direction.setFromMatrixPosition( light.matrixWorld ); _direction.transformDirection( viewMatrix ); - var hemisphereLight = hemisphereLights[i]; - - spotLight.position = _direction.clone(); - spotLight.skyColor = light.color.clone().multiplyScalar( intensity ); - spotLight.groundColor = light.groundColor.clone().multiplyScalar( intensity ); + lightUniforms.position.copy( _direction); + lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); + lightUniforms.groundColor.copy( groundColor ).multiplyScalar( intensity ); } } - // null eventual remains from removed lights - // (this is to avoid if in shader) - - for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0; - for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0; - for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0; - for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0; - for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0; - - zlights.directional.length = dirLength; - zlights.point.length = pointLength; - zlights.spot.length = spotLength; - zlights.hemi.length = hemiLength; - zlights.ambient[ 0 ] = r; zlights.ambient[ 1 ] = g; zlights.ambient[ 2 ] = b; From 223c383b1456bc49c1f422d397a5288d099c35cc Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 00:19:34 -0400 Subject: [PATCH 09/64] reduce the need for temporaries, cleanup code. --- src/renderers/WebGLRenderer.js | 28 +++++++-------- .../lights_phong_pars_fragment.glsl | 35 ++++--------------- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index ec1c2adaebaf77..d88a01ea16bcad 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2470,12 +2470,11 @@ THREE.WebGLRenderer = function ( parameters ) { continue; } - _direction.setFromMatrixPosition( light.matrixWorld ); + lightUniforms.direction.setFromMatrixPosition( light.matrixWorld ); _vector3.setFromMatrixPosition( light.target.matrixWorld ); - _direction.sub( _vector3 ); - _direction.transformDirection( viewMatrix ); + lightUniforms.direction.sub( _vector3 ); + lightUniforms.direction.transformDirection( viewMatrix ); - lightUniforms.position.copy( _direction ); lightUniforms.color.copy( color ).multiplyScalar( intensity ); lightUniforms.distance = distance; @@ -2497,10 +2496,9 @@ THREE.WebGLRenderer = function ( parameters ) { continue; } - _vector3.setFromMatrixPosition( light.matrixWorld ); - _vector3.applyMatrix4( viewMatrix ); + lightUniforms.position.setFromMatrixPosition( light.matrixWorld ); + lightUniforms.position.applyMatrix4( viewMatrix ); - lightUniforms.position.copy( _vector3 ); lightUniforms.color.copy( color ).multiplyScalar( intensity ); lightUniforms.distance = distance; lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; @@ -2525,18 +2523,17 @@ THREE.WebGLRenderer = function ( parameters ) { continue; } - _direction.setFromMatrixPosition( light.matrixWorld ); - _vector3.copy( _direction ).applyMatrix4( viewMatrix ); + lightUniforms.position.setFromMatrixPosition( light.matrixWorld ); + lightUniforms.position.applyMatrix4( viewMatrix ); - lightUniforms.position.copy( _vector3 ); lightUniforms.color.copy( color ).multiplyScalar( intensity ); lightUniforms.distance = distance; + lightUniforms.direction.setFromMatrixPosition( light.matrixWorld ); _vector3.setFromMatrixPosition( light.target.matrixWorld ); - _direction.sub( _vector3 ); - _direction.transformDirection( viewMatrix ); + lightUniforms.direction.sub( _vector3 ); + lightUniforms.direction.transformDirection( viewMatrix ); - lightUniforms.direction.copy( _direction); lightUniforms.angleCos = Math.cos( light.angle ); lightUniforms.exponent = light.exponent; lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; @@ -2558,10 +2555,9 @@ THREE.WebGLRenderer = function ( parameters ) { continue; } - _direction.setFromMatrixPosition( light.matrixWorld ); - _direction.transformDirection( viewMatrix ); + lightUniforms.position.setFromMatrixPosition( light.matrixWorld ); + lightUniforms.position.transformDirection( viewMatrix ); - lightUniforms.position.copy( _direction); lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); lightUniforms.groundColor.copy( groundColor ).multiplyScalar( intensity ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index c9ae40a9e24d5d..5ad30ec9d52397 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -17,12 +17,9 @@ varying vec3 vViewPosition; #if MAX_DIR_LIGHTS > 0 - //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; - //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; - struct DirectionalLight { - vec3 color; vec3 direction; + vec3 color; }; uniform DirectionalLight singleTestDirLight; @@ -40,14 +37,10 @@ varying vec3 vViewPosition; #if MAX_HEMI_LIGHTS > 0 - //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - struct HemisphereLight { + vec3 direction; vec3 skyColor; vec3 groundColor; - vec3 direction; }; uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; @@ -56,19 +49,13 @@ varying vec3 vViewPosition; #if MAX_POINT_LIGHTS > 0 - //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; - struct PointLight { - vec3 color; vec3 position; - float decay; + vec3 color; float distance; + float decay; }; - uniform PointLight singleTestPointLight; uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; @@ -89,22 +76,14 @@ varying vec3 vViewPosition; #if MAX_SPOT_LIGHTS > 0 - //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; - struct SpotLight { - vec3 color; vec3 position; vec3 direction; - float angleCos; - float exponent; + vec3 color; float distance; float decay; + float angleCos; + float exponent; }; uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; From 3f4a94685e7f4c302938b208a8cb9d52af7b9593 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 00:25:56 -0400 Subject: [PATCH 10/64] more code removal --- src/renderers/WebGLRenderer.js | 39 +++++++++++----------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d88a01ea16bcad..6a81bfaf9a4de5 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1914,13 +1914,9 @@ THREE.WebGLRenderer = function ( parameters ) { function refreshUniformsLights ( uniforms, lights ) { uniforms.ambientLightColor.value = lights.ambient; - uniforms.directionalLights.value = lights.directional; - uniforms.pointLights.value = lights.point; - uniforms.spotLights.value = lights.spot; - uniforms.hemisphereLights.value = lights.hemi; } @@ -1930,25 +1926,10 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.ambientLightColor.needsUpdate = value; - uniforms.directionalLightColor.needsUpdate = value; - uniforms.directionalLightDirection.needsUpdate = value; - - uniforms.pointLightColor.needsUpdate = value; - uniforms.pointLightPosition.needsUpdate = value; - uniforms.pointLightDistance.needsUpdate = value; - uniforms.pointLightDecay.needsUpdate = value; - - uniforms.spotLightColor.needsUpdate = value; - uniforms.spotLightPosition.needsUpdate = value; - uniforms.spotLightDistance.needsUpdate = value; - uniforms.spotLightDirection.needsUpdate = value; - uniforms.spotLightAngleCos.needsUpdate = value; - uniforms.spotLightExponent.needsUpdate = value; - uniforms.spotLightDecay.needsUpdate = value; - - uniforms.hemisphereLightSkyColor.needsUpdate = value; - uniforms.hemisphereLightGroundColor.needsUpdate = value; - uniforms.hemisphereLightDirection.needsUpdate = value; + uniforms.directionalLights.needsUpdate = value; + uniforms.pointLights.needsUpdate = value; + uniforms.spotLights.needsUpdate = value; + uniforms.hemisphereLights.needsUpdate = value; } @@ -2463,7 +2444,8 @@ THREE.WebGLRenderer = function ( parameters ) { } } - var lightUniforms = directionalLights[i] = light.__webglUniforms; + var lightUniforms = light.__webglUniforms; + zlights.directional.push( lightUniforms ); if ( ! light.visible ) { lightUniforms.color.setRGB( 0, 0, 0 ); @@ -2489,7 +2471,8 @@ THREE.WebGLRenderer = function ( parameters ) { } } - var lightUniforms = pointLights[i] = light.__webglUniforms; + var lightUniforms = light.__webglUniforms; + zlights.point.push( lightUniforms ); if ( ! light.visible ) { lightUniforms.color.setRGB( 0, 0, 0 ); @@ -2516,7 +2499,8 @@ THREE.WebGLRenderer = function ( parameters ) { } } - var lightUniforms = spotLights[i] = light.__webglUniforms; + var lightUniforms = light.__webglUniforms; + zlights.spot.push( lightUniforms ); if ( ! light.visible ) { lightUniforms.color.setRGB( 0, 0, 0 ); @@ -2548,7 +2532,8 @@ THREE.WebGLRenderer = function ( parameters ) { } } - var lightUniforms = hemisphereLights[i] = light.__webglUniforms; + var lightUniforms = light.__webglUniforms; + zlights.hemi.push( lightUniforms ); if ( ! light.visible ) { lightUniforms.skyColor.setRGB( 0, 0, 0 ); From 339e4d3ef188ab5dd8f6709e7d622149b8b39bf7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 00:31:10 -0400 Subject: [PATCH 11/64] more code removal --- src/renderers/WebGLRenderer.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 6a81bfaf9a4de5..c53c996477e92e 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2391,14 +2391,6 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setColorLinear( array, offset, color, intensity ) { - - array[ offset + 0 ] = color.r * intensity; - array[ offset + 1 ] = color.g * intensity; - array[ offset + 2 ] = color.b * intensity; - - } - function setupLights ( lights, camera ) { var l, ll, light, From bbace72b72b0de82f499786fc0e5ace6677050e7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 10:19:00 -0400 Subject: [PATCH 12/64] structs barely work. --- src/renderers/WebGLRenderer.js | 66 ++++++++++--------- src/renderers/shaders/ShaderChunk/common.glsl | 6 +- src/renderers/shaders/UniformsLib.js | 8 +-- src/renderers/webgl/WebGLProgram.js | 3 +- 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index c53c996477e92e..bf8b974defaae5 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2110,66 +2110,74 @@ THREE.WebGLRenderer = function ( parameters ) { case 's': + //console.log( "uniform s", uniform, location ); // TODO: Optimize this. - for( var j = 0; j < uniform.properties.length; j ++ ) { - - var property = uniform.properties[j]; - var uniformProperty = location[ property ]; - var valueProperty = values[ property ]; + for( var propertyName in uniform.properties ) { + var property = uniform.properties[ propertyName ]; + var locationProperty = location[ propertyName ]; + var valueProperty = value[ propertyName ]; + //console.log( "uniformProperty", property, valueProperty ); + switch( property.type ) { case 'f': - _gl.uniform1f( uniformProperty, valueProperty ); + _gl.uniform1f( locationProperty, valueProperty ); break; case 'v2': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y ); + _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y ); break; case 'v3': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z ); + _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z ); break; case 'v4': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); + _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); break; case 'c': - _gl.uniform1f( uniformProperty, valueProperty.r, valueProperty.g, valueProperty.b ); + _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b ); break; }; } + debugger; break; case 'sa': + //console.log( "uniform sa", uniform, location ); // TODO: Optimize this. for( var i = 0; i < value.length; i ++ ) { - for( var j = 0; j < uniform.properties.length; j ++ ) { - - var property = uniform.properties[j]; - var uniformProperty = location[ i ][ property ]; - var valueProperty = value[i][ property ]; + //console.log( "uniformIndex", i ); + for( var propertyName in uniform.properties ) { + + var property = uniform.properties[ propertyName ]; + var locationProperty = location[ i ][ propertyName ]; + var valueProperty = value[i][ propertyName ]; + //console.log( "uniformProperty", property, valueProperty, i ); + switch( property.type ) { case 'f': - _gl.uniform1f( uniformProperty, valueProperty ); + _gl.uniform1f( locationProperty, valueProperty ); break; case 'v2': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y ); + _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y ); break; case 'v3': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z ); + _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z ); break; case 'v4': - _gl.uniform1f( uniformProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); + _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); break; case 'c': - _gl.uniform1f( uniformProperty, valueProperty.r, valueProperty.g, valueProperty.b ); + _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b ); break; }; } } - + debugger; + break; case 'iv1': @@ -2401,7 +2409,7 @@ THREE.WebGLRenderer = function ( parameters ) { zlights = _lights, - viewMatrix = camera.matrixWorldInverse, + viewMatrix = camera.matrixWorldInverse; zlights.directional = []; zlights.point = []; @@ -2430,9 +2438,8 @@ THREE.WebGLRenderer = function ( parameters ) { if( ! light.__webglUniforms ) { light.__webglUniforms = { - position: new THREE.Vector3(), - color: new THREE.Color(), - distance: 0 + direction: new THREE.Vector3(), + color: new THREE.Color() } } @@ -2449,8 +2456,7 @@ THREE.WebGLRenderer = function ( parameters ) { lightUniforms.direction.sub( _vector3 ); lightUniforms.direction.transformDirection( viewMatrix ); - lightUniforms.color.copy( color ).multiplyScalar( intensity ); - lightUniforms.distance = distance; + lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity ); } else if ( light instanceof THREE.PointLight ) { @@ -2474,8 +2480,8 @@ THREE.WebGLRenderer = function ( parameters ) { lightUniforms.position.setFromMatrixPosition( light.matrixWorld ); lightUniforms.position.applyMatrix4( viewMatrix ); - lightUniforms.color.copy( color ).multiplyScalar( intensity ); - lightUniforms.distance = distance; + lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity ); + lightUniforms.distance = light.distance; lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; } else if ( light instanceof THREE.SpotLight ) { @@ -2536,7 +2542,7 @@ THREE.WebGLRenderer = function ( parameters ) { lightUniforms.position.transformDirection( viewMatrix ); lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); - lightUniforms.groundColor.copy( groundColor ).multiplyScalar( intensity ); + lightUniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); } diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 21be06acb4a2e5..5bb321fb1824d8 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -102,7 +102,7 @@ vec3 F_Schlick( in vec3 specularColor, in float dotLH ) { float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { - // geometry term is (nâ‹…l)(nâ‹…v) / 4(nâ‹…l)(nâ‹…v) + // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) return 0.25; @@ -124,6 +124,4 @@ vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, return F * G * D; -} - - +} \ No newline at end of file diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index 30eb7de09679e8..aeaf694dec6d70 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -80,20 +80,20 @@ THREE.UniformsLib = { "directionalLights" : { type: "sa", value: [], properties: { "direction": { type: "v3" }, "color": { type: "c" } - } }; + } }, "hemisphereLights" : { type: "sa", value: [], properties: { "direction": { type: "v3" }, "skyColor": { type: "v3" }, "groundColor": { type: "v3" } - } }; + } }, "pointLights" : { type: "sa", value: [], properties: { "color": { type: "c" }, "position": { type: "v3" }, "direction": { type: "v3" }, "distance": { type: "f" } - } }; + } }, "spotLights" : { type: "sa", value: [], properties: { "color": { type: "c" }, @@ -103,7 +103,7 @@ THREE.UniformsLib = { "angleCos": { type: "f" }, "exponent": { type: "f" }, "decay": { type: "f" } - } }; + } } }, diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 6483fa94c34cdc..e595520305d309 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -38,7 +38,7 @@ THREE.WebGLProgram = ( function () { var name = info.name; var location = gl.getUniformLocation( program, name ); - console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); + //console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); var matches = structRe.exec(name); if( matches ) { @@ -89,7 +89,6 @@ THREE.WebGLProgram = ( function () { } - console.log("uniforms", uniforms); return uniforms; } From 28754cf13c1aa9e0ec8c785121cddb989e375479 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 10:55:47 -0400 Subject: [PATCH 13/64] lambert lighting works, defining light helpers only once in common.glsl --- src/renderers/WebGLRenderer.js | 2 - src/renderers/shaders/ShaderChunk/common.glsl | 102 +++++++++++++++- .../lights_lambert_pars_vertex.glsl | 112 ------------------ .../ShaderChunk/lights_lambert_vertex.glsl | 83 +++++-------- .../ShaderChunk/lights_phong_fragment.glsl | 6 +- .../lights_phong_pars_fragment.glsl | 95 --------------- 6 files changed, 131 insertions(+), 269 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index bf8b974defaae5..eeb14f69391221 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2137,7 +2137,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; } - debugger; break; @@ -2176,7 +2175,6 @@ THREE.WebGLRenderer = function ( parameters ) { } } - debugger; break; diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 5bb321fb1824d8..66241d7abe7e48 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -124,4 +124,104 @@ vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, return F * G * D; -} \ No newline at end of file +} + +#if MAX_DIR_LIGHTS > 0 + + struct DirectionalLight { + vec3 direction; + vec3 color; + }; + + uniform DirectionalLight singleTestDirLight; + + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; + + void getDirLightDirect( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { + + lightDir = directionalLight.direction; + lightColor = directionalLight.color; + + } + +#endif + +#if MAX_POINT_LIGHTS > 0 + + struct PointLight { + vec3 position; + vec3 color; + float distance; + float decay; + }; + + uniform PointLight singleTestPointLight; + + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; + + void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = pointLight.position; + + vec3 lVector = lightPosition - position; + lightDir = normalize( lVector ); + + lightColor = pointLight.color; + lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + struct SpotLight { + vec3 position; + vec3 direction; + vec3 color; + float distance; + float decay; + float angleCos; + float exponent; + }; + + uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; + + void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out vec3 lightDir, out vec3 lightColor ) { + + vec3 lightPosition = spotLight.position; + + vec3 lVector = lightPosition - position; + lightDir = normalize( lVector ); + + float spotEffect = dot( spotLight.direction, lightDir ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); + + lightColor = spotLight.color; + lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + + } + +#endif + + +#if MAX_HEMI_LIGHTS > 0 + + struct HemisphereLight { + vec3 direction; + vec3 skyColor; + vec3 groundColor; + }; + + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + + vec3 getHemisphereLightIndirect( const in HemisphereLight hemiLight, in vec3 normal ) { + + float dotNL = dot( normal, hemiLight.direction ); + + float hemiDiffuseWeight = 0.5 * dotNL + 0.5; + + return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + } + +#endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl index 67a333fedb6c7b..7024ef54773439 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl @@ -1,113 +1 @@ uniform vec3 ambientLightColor; - - -#if MAX_DIR_LIGHTS > 0 - - //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; - //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; - - struct DirectionalLight { - vec3 color; - vec3 direction; - }; - - uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - - void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { - - lightDir = directionalLight.direction; - lightColor = directionalLight.color; - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - - struct HemisphereLight { - vec3 skyColor; - vec3 groundColor; - vec3 direction; - }; - - uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; - - struct PointLight { - vec3 color; - vec3 position; - float decay; - float distance; - }; - - uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - - void getPointLight( const in PointLight pointLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = pointLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - lightColor = pointLight.color; - lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; - - struct SpotLight { - vec3 color; - vec3 position; - vec3 direction; - float angleCos; - float exponent; - float distance; - float decay; - }; - - uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - - void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = spotLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - float spotEffect = dot( spotLight.direction, lightDir ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - - lightColor = spotLight.color; - lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); - - } - -#endif - - - - - diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 8ae9d3d308534c..7c76cfbf5d72a8 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -12,26 +12,21 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightColor = pointLightColor[ i ]; + vec3 lightDir, lightIntensity; + getPointLight( pointLights[i], -vViewPosition, lightDir, lightIntensity ); - vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz; - vec3 lightDir = normalize( lVector ); + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - // attenuation + float dotNL = dot( normal, lightDir ); - float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); + vLightFront += lightIntensity * saturate( dotNL ); - // diffuse - - float dotProduct = dot( normal, lightDir ); - - vLightFront += lightColor * attenuation * saturate( dotProduct ); - - #ifdef DOUBLE_SIDED + #ifdef DOUBLE_SIDED - vLightBack += lightColor * attenuation * saturate( - dotProduct ); + vLightBack += lightIntensity * saturate( - dotNL ); - #endif + #endif + } } @@ -41,33 +36,18 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightColor = spotLightColor[ i ]; - - vec3 lightPosition = spotLightPosition[ i ]; - vec3 lVector = lightPosition - mvPosition.xyz; - vec3 lightDir = normalize( lVector ); - - float spotEffect = dot( spotLightDirection[ i ], lightDir ); - - if ( spotEffect > spotLightAngleCos[ i ] ) { - - spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) ); - - // attenuation + vec3 lightDir, lightIntensity; + getSpotLight( spotLights[i], -vViewPosition, lightDir, lightIntensity ); - float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - attenuation *= spotEffect; + float dotNL = saturate( dot( normal, lightDir ) ); - // diffuse - - float dotProduct = dot( normal, lightDir ); - - vLightFront += lightColor * attenuation * saturate( dotProduct ); + vLightFront += lightIntensity * saturate( dotNL ); #ifdef DOUBLE_SIDED - vLightBack += lightColor * attenuation * saturate( - dotProduct ); + vLightBack += lightIntensity * saturate( - dotNL ); #endif @@ -81,21 +61,22 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightColor = directionalLightColor[ i ]; + vec3 lightDir, lightIntensity; + getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); - vec3 lightDir = directionalLightDirection[ i ]; + if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - // diffuse + float dotNL = dot( normal, lightDir ); - float dotProduct = dot( normal, lightDir ); + vLightFront += lightIntensity * saturate( dotNL ); - vLightFront += lightColor * saturate( dotProduct ); + #ifdef DOUBLE_SIDED - #ifdef DOUBLE_SIDED + vLightBack += lightIntensity * saturate( - dotNL ); - vLightBack += lightColor * saturate( - dotProduct ); + #endif - #endif + } } @@ -105,21 +86,11 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vec3 lightDir = hemisphereLightDirection[ i ]; - - // diffuse - - float dotProduct = dot( normal, lightDir ); - - float hemiDiffuseWeight = 0.5 * dotProduct + 0.5; - - vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); + vLightFront += getHemisphereLightIndirect( hemisphereLights[ i ], normal ); #ifdef DOUBLE_SIDED - - float hemiDiffuseWeightBack = - 0.5 * dotProduct + 0.5; - - vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack ); + + vLightBack += getHemisphereLightIndirect( hemisphereLights[ i ], -normal ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 7fe00dff9af115..b3e05c5af30244 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -15,7 +15,7 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getPointLight( pointLights[i], lightDir, lightIntensity ); + getPointLightDirect( pointLights[i], -vViewPosition, lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { @@ -41,7 +41,7 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getSpotLight( spotLights[i], lightDir, lightIntensity ); + getSpotLightDirect( spotLights[i], -vViewPosition, lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { @@ -66,7 +66,7 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getDirLight( directionalLights[i], lightDir, lightIntensity ); + getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); if( dot( lightIntensity, lightIntensity ) > 0.0 ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 5ad30ec9d52397..da6edd47d26a5c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -14,98 +14,3 @@ varying vec3 vViewPosition; #endif - -#if MAX_DIR_LIGHTS > 0 - - struct DirectionalLight { - vec3 direction; - vec3 color; - }; - - uniform DirectionalLight singleTestDirLight; - - uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - - void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { - - lightDir = directionalLight.direction; - lightColor = directionalLight.color; - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - struct HemisphereLight { - vec3 direction; - vec3 skyColor; - vec3 groundColor; - }; - - uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - struct PointLight { - vec3 position; - vec3 color; - float distance; - float decay; - }; - - uniform PointLight singleTestPointLight; - - uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - - void getPointLight( const in PointLight pointLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = pointLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - lightColor = pointLight.color; - lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - struct SpotLight { - vec3 position; - vec3 direction; - vec3 color; - float distance; - float decay; - float angleCos; - float exponent; - }; - - uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - - void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = spotLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - float spotEffect = dot( spotLight.direction, lightDir ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - - lightColor = spotLight.color; - lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); - - } - -#endif - - - - - From e21dd086f848d380a528dc7d022338e5cdc378b9 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 21:02:35 -0400 Subject: [PATCH 14/64] further cleanup to simplify usage, avoiding premature optimization. --- src/renderers/shaders/ShaderChunk/common.glsl | 21 ++++--- .../ShaderChunk/lights_lambert_vertex.glsl | 51 ++++++----------- .../ShaderChunk/lights_phong_fragment.glsl | 57 +++++-------------- src/renderers/shaders/UniformsLib.js | 2 +- 4 files changed, 44 insertions(+), 87 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 66241d7abe7e48..bf670d1aebdff6 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -4,7 +4,7 @@ #define RECIPROCAL_PI2 0.15915494 #define LOG2 1.442695 #define EPSILON 1e-6 - +#define PHYSICALLY_BASED_RENDERING #define saturate(a) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) @@ -82,13 +82,13 @@ vec3 linearToOutput( in vec3 a ) { } -vec3 BRDF_Lambert( in vec3 diffuseColor, in float dotLN ) { +vec3 BRDF_Lambert( const in vec3 incomingLight, const in vec3 diffuseColor, const in vec3 normal, const in vec3 lightDir ) { - return diffuseColor * ( dotLN * RECIPROCAL_PI ); + return incomingLight * diffuseColor * ( saturate( dot( normal, lightDir ) ) * RECIPROCAL_PI ); } -vec3 F_Schlick( in vec3 specularColor, in float dotLH ) { +vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { // Original approximation by Christophe Schlick '94 //;float fresnel = pow( 1.0 - dotLH, 5.0 ); @@ -96,7 +96,7 @@ vec3 F_Schlick( in vec3 specularColor, in float dotLH ) { // Optimized variant (presented by Epic at SIGGRAPH '13) float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH ); - return ( 1.0 - specularColor ) * fresnel + specularColor; + return F0 + ( 1.0 - F0 ) * fresnel; } @@ -108,7 +108,7 @@ float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { } -float D_BlinnPhong( in float shininess, in float dotNH ) { +float D_BlinnPhong( const in float shininess, const in float dotNH ) { // factor of 1/PI in distribution term omitted @@ -116,13 +116,17 @@ float D_BlinnPhong( in float shininess, in float dotNH ) { } -vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, in float dotLH ) { +vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, const in float shininess, const in vec3 normal, const in vec3 lightDir, const in vec3 viewDir ) { + + vec3 halfDir = normalize( lightDir + viewDir ) * singleTestPointLight.distance; + float dotNH = saturate( dot( normal, halfDir ) ); + float dotLH = saturate( dot( lightDir, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); float D = D_BlinnPhong( shininess, dotNH ); - return F * G * D; + return incomingLight * F * ( G * D ); } @@ -222,6 +226,7 @@ vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, float hemiDiffuseWeight = 0.5 * dotNL + 0.5; return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + } #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 7c76cfbf5d72a8..94396b981990e7 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -12,21 +12,16 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getPointLight( pointLights[i], -vViewPosition, lightDir, lightIntensity ); - - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { + vec3 lightDir, lightColor; + getPointLightDirect( pointLights[i], mvPosition.xyz, lightDir, lightColor ); - float dotNL = dot( normal, lightDir ); + vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); - vLightFront += lightIntensity * saturate( dotNL ); - - #ifdef DOUBLE_SIDED + #ifdef DOUBLE_SIDED - vLightBack += lightIntensity * saturate( - dotNL ); + vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); - #endif - } + #endif } @@ -37,21 +32,15 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { vec3 lightDir, lightIntensity; - getSpotLight( spotLights[i], -vViewPosition, lightDir, lightIntensity ); - - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - - float dotNL = saturate( dot( normal, lightDir ) ); - - vLightFront += lightIntensity * saturate( dotNL ); + getSpotLightDirect( spotLights[i], mvPosition.xyz, lightDir, lightIntensity ); - #ifdef DOUBLE_SIDED + vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); - vLightBack += lightIntensity * saturate( - dotNL ); + #ifdef DOUBLE_SIDED - #endif + vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); - } + #endif } @@ -64,19 +53,13 @@ vec3 normal = normalize( transformedNormal ); vec3 lightDir, lightIntensity; getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - - float dotNL = dot( normal, lightDir ); - - vLightFront += lightIntensity * saturate( dotNL ); + vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); - #ifdef DOUBLE_SIDED - - vLightBack += lightIntensity * saturate( - dotNL ); + #ifdef DOUBLE_SIDED - #endif + vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); - } + #endif } @@ -86,11 +69,11 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vLightFront += getHemisphereLightIndirect( hemisphereLights[ i ], normal ); + vLightFront += getHemisphereLightIndirect( hemisphereLights[ i ], normal ) * RECIPROCAL_PI; #ifdef DOUBLE_SIDED - vLightBack += getHemisphereLightIndirect( hemisphereLights[ i ], -normal ); + vLightBack += getHemisphereLightIndirect( hemisphereLights[ i ], -normal ) * RECIPROCAL_PI; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index b3e05c5af30244..d23f55576de04d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -14,23 +14,12 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getPointLightDirect( pointLights[i], -vViewPosition, lightDir, lightIntensity ); - - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - + vec3 lightDir, lightColor; + getPointLightDirect( pointLights[i], -vViewPosition, lightDir, lightColor ); - vec3 halfDir = normalize( lightDir + viewDir ) * singleTestPointLight.distance; - float dotNL = saturate( dot( normal, lightDir ) ); - float dotNH = saturate( dot( normal, halfDir ) ); - float dotLH = saturate( dot( lightDir, halfDir ) ); - - totalReflectedLight += ( - BRDF_Lambert( diffuse, dotNL ) + - BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) - ) * lightIntensity; - - } + totalReflectedLight += + BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + + BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); } @@ -40,22 +29,12 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getSpotLightDirect( spotLights[i], -vViewPosition, lightDir, lightIntensity ); - - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - - vec3 halfDir = normalize( lightDir + viewDir ); - float dotNL = saturate( dot( normal, lightDir ) ); - float dotNH = saturate( dot( normal, halfDir ) ); - float dotLH = saturate( dot( lightDir, halfDir ) ); - - totalReflectedLight += ( - BRDF_Lambert( diffuse, dotNL ) + - BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) - ) * lightIntensity; + vec3 lightDir, lightColor; + getSpotLightDirect( spotLights[i], -vViewPosition, lightDir, lightColor ); - } + totalReflectedLight += + BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + + BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); } @@ -68,19 +47,9 @@ vec3 diffuse = diffuseColor.rgb; vec3 lightDir, lightIntensity; getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); - if( dot( lightIntensity, lightIntensity ) > 0.0 ) { - - vec3 halfDir = normalize( lightDir + viewDir ); - float dotNL = saturate( dot( normal, lightDir ) ); - float dotNH = saturate( dot( normal, halfDir ) ); - float dotLH = saturate( dot( lightDir, halfDir ) ); - - totalReflectedLight += ( - BRDF_Lambert( diffuse, dotNL ) + - BRDF_BlinnPhong( specular, shininess, dotNH, dotLH ) - ) * lightIntensity; - - } + totalReflectedLight += + BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + + BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); } diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index aeaf694dec6d70..8534ef5717df3b 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -91,7 +91,7 @@ THREE.UniformsLib = { "pointLights" : { type: "sa", value: [], properties: { "color": { type: "c" }, "position": { type: "v3" }, - "direction": { type: "v3" }, + "decay": { type: "f" }, "distance": { type: "f" } } }, From d443359764e0f5b4596756426613c1730f8e3c2c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 21:05:11 -0400 Subject: [PATCH 15/64] remove unused code. --- .../shaders/ShaderChunk/light_pars.glsl | 111 ------------------ 1 file changed, 111 deletions(-) delete mode 100644 src/renderers/shaders/ShaderChunk/light_pars.glsl diff --git a/src/renderers/shaders/ShaderChunk/light_pars.glsl b/src/renderers/shaders/ShaderChunk/light_pars.glsl deleted file mode 100644 index 94bf30e1057a3a..00000000000000 --- a/src/renderers/shaders/ShaderChunk/light_pars.glsl +++ /dev/null @@ -1,111 +0,0 @@ - -#if MAX_DIR_LIGHTS > 0 - - //uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; - //uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; - - struct DirectionalLight { - vec3 color; - vec3 direction; - }; - - uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - - void getDirLight( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { - - lightDir = directionalLight.direction; - lightColor = directionalLight.color; - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - //uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; - //uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; - - struct HemisphereLight { - vec3 skyColor; - vec3 groundColor; - vec3 direction; - }; - - uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - -#endif - -#if MAX_POINT_LIGHTS > 0 - - //uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; - //uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; - //uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; - - struct PointLight { - vec3 color; - vec3 position; - float decay; - float cutoffDistance; - }; - - uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - - void getPointLight( const in pointLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = pointLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - lightColor = pointLight.color[ pointIndex ]; - lightColor *= calcLightAttenuation( length( lVector ), pointLight.cutoffDistance, pointLight.decay ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - //uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; - //uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; - //uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; - - struct SpotLight { - vec3 color; - vec3 position; - vec3 direction; - float angleCos; - float exponent; - float cutoffDistance; - float decay; - }; - - uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - - void getSpotLight( const in SpotLight spotLight, out vec3 lightDir, out vec3 lightColor ) { - - vec3 lightPosition = spotLight.position; - - vec3 lVector = lightPosition + vViewPosition.xyz; - lightDir = normalize( lVector ); - - float spotEffect = dot( spotLight.direction, lightDir ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - - lightColor = spotLight.color; - lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); - - } - -#endif - - - - - From faa1967ef4b87c8be7e4d82b0720f09fb5e93dc9 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 21:44:18 -0400 Subject: [PATCH 16/64] separation of light accumulators into diffuse/specular, direct/indirect --- src/renderers/shaders/ShaderChunk/common.glsl | 25 ++++---- .../ShaderChunk/hemilight_fragment.glsl | 18 ------ .../ShaderChunk/lights_lambert_vertex.glsl | 34 +++++----- .../ShaderChunk/lights_phong_fragment.glsl | 63 ++++++++++++++----- src/renderers/shaders/ShaderLib.js | 2 - 5 files changed, 79 insertions(+), 63 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index bf670d1aebdff6..b6b922d18c6458 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -82,10 +82,11 @@ vec3 linearToOutput( in vec3 a ) { } -vec3 BRDF_Lambert( const in vec3 incomingLight, const in vec3 diffuseColor, const in vec3 normal, const in vec3 lightDir ) { +vec3 BRDF_Lambert( const in vec3 lightColor, const in vec3 lightDir, const in vec3 normal, const in vec3 diffuseColor ) { - return incomingLight * diffuseColor * ( saturate( dot( normal, lightDir ) ) * RECIPROCAL_PI ); + return lightColor * diffuseColor * ( saturate( dot( normal, lightDir ) ) ); + // the above should be scaled by '' * RECIPROCAL_PI' } vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { @@ -116,9 +117,9 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, const in float shininess, const in vec3 normal, const in vec3 lightDir, const in vec3 viewDir ) { +vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess ) { - vec3 halfDir = normalize( lightDir + viewDir ) * singleTestPointLight.distance; + vec3 halfDir = normalize( lightDir + viewDir ); float dotNH = saturate( dot( normal, halfDir ) ); float dotLH = saturate( dot( lightDir, halfDir ) ); @@ -126,7 +127,7 @@ vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); float D = D_BlinnPhong( shininess, dotNH ); - return incomingLight * F * ( G * D ); + return lightColor * F * ( G * D ); } @@ -141,7 +142,7 @@ vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirLightDirect( const in DirectionalLight directionalLight, out vec3 lightDir, out vec3 lightColor ) { + void getDirLightDirect( const in DirectionalLight directionalLight, out vec3 lightColor, out vec3 lightDir ) { lightDir = directionalLight.direction; lightColor = directionalLight.color; @@ -159,11 +160,9 @@ vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, float decay; }; - uniform PointLight singleTestPointLight; - uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out vec3 lightDir, out vec3 lightColor ) { + void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out vec3 lightColor, out vec3 lightDir ) { vec3 lightPosition = pointLight.position; @@ -191,7 +190,7 @@ vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out vec3 lightDir, out vec3 lightColor ) { + void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out vec3 lightColor, out vec3 lightDir ) { vec3 lightPosition = spotLight.position; @@ -219,13 +218,15 @@ vec3 BRDF_BlinnPhong( const in vec3 incomingLight, const in vec3 specularColor, uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - vec3 getHemisphereLightIndirect( const in HemisphereLight hemiLight, in vec3 normal ) { + void getHemisphereLightIndirect( const in HemisphereLight hemiLight, const in vec3 normal, out vec3 lightColor, out vec3 lightDir ) { float dotNL = dot( normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + lightColor = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + + lightDir = normal; } diff --git a/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl b/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl index 50dffb8ab96df1..e69de29bb2d1d6 100644 --- a/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl @@ -1,18 +0,0 @@ -#if MAX_HEMI_LIGHTS > 0 - - for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - - vec3 lightDir = hemisphereLightDirection[ i ]; - - float dotProduct = dot( normal, lightDir ); - - float hemiDiffuseWeight = 0.5 * dotProduct + 0.5; - - vec3 lightColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); - - totalAmbientLight += lightColor; - - } - -#endif - diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 94396b981990e7..53aeeeeadc1f7e 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -7,19 +7,20 @@ vLightFront = vec3( 0.0 ); #endif vec3 normal = normalize( transformedNormal ); +vec3 diffuse = vec3( 1.0 ); #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightDir, lightColor; - getPointLightDirect( pointLights[i], mvPosition.xyz, lightDir, lightColor ); + vec3 lightColor, lightDir; + getPointLightDirect( pointLights[i], mvPosition.xyz, lightColor, lightDir ); - vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); + vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); + vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); #endif @@ -31,14 +32,14 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getSpotLightDirect( spotLights[i], mvPosition.xyz, lightDir, lightIntensity ); + vec3 lightColor, lightDir; + getSpotLightDirect( spotLights[i], mvPosition.xyz, lightColor, lightDir ); - vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); + vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); + vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); #endif @@ -50,14 +51,14 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); + vec3 lightColor, lightDir; + getDirLightDirect( directionalLights[i], lightColor, lightDir ); - vLightFront += BRDF_Lambert( lightColor, vec3( 1.0 ), normal, lightDir ); + vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, vec3( 1.0 ), -normal, lightDir ); + vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); #endif @@ -69,11 +70,16 @@ vec3 normal = normalize( transformedNormal ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vLightFront += getHemisphereLightIndirect( hemisphereLights[ i ], normal ) * RECIPROCAL_PI; + vec3 lightColor, lightDir; + getHemisphereLightIndirect( hemisphereLights[ i ], normal, lightColor, lightDir ); + + vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += getHemisphereLightIndirect( hemisphereLights[ i ], -normal ) * RECIPROCAL_PI; + getHemisphereLightIndirect( hemisphereLights[ i ], -normal, lightColor, lightDir ); + + vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index d23f55576de04d..e91f365248f3e3 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,6 +1,9 @@ vec3 viewDir = normalize( vViewPosition ); -vec3 totalReflectedLight = vec3( 0.0 ); +vec3 totalDirectReflectedSpecular = vec3( 0.0 ); +vec3 totalDirectReflectedDiffuse = vec3( 0.0 ); +vec3 totalIndirectReflectedSpecular = vec3( 0.0 ); +vec3 totalIndirectReflectedDiffuse = vec3( 0.0 ); vec3 diffuse = diffuseColor.rgb; @@ -14,12 +17,14 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightDir, lightColor; - getPointLightDirect( pointLights[i], -vViewPosition, lightDir, lightColor ); + vec3 lightColor, lightDir; + getPointLightDirect( pointLights[i], -vViewPosition, lightColor, lightDir ); - totalReflectedLight += - BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + - BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); + totalDirectReflectedDiffuse += + BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + + totalDirectReflectedSpecular += + BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); } @@ -29,12 +34,14 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightDir, lightColor; - getSpotLightDirect( spotLights[i], -vViewPosition, lightDir, lightColor ); + vec3 lightColor, lightDir; + getSpotLightDirect( spotLights[i], -vViewPosition, lightColor, lightDir ); + + totalDirectReflectedDiffuse += + BRDF_Lambert( lightColor, lightDir, normal, diffuse ); - totalReflectedLight += - BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + - BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); + totalDirectReflectedSpecular += + BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); } @@ -44,15 +51,37 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightDir, lightIntensity; - getDirLightDirect( directionalLights[i], lightDir, lightIntensity ); + vec3 lightColor, lightDir; + getDirLightDirect( directionalLights[i], lightColor, lightDir ); + + totalDirectReflectedDiffuse += + BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + + totalDirectReflectedSpecular += + BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); + + } + +#endif + +#if MAX_HEMI_LIGHTS > 0 - totalReflectedLight += - BRDF_Lambert( lightColor, diffuse, normal, lightDir ) + - BRDF_BlinnPhong( lightColor, specular, shininess, normal, lightDir, viewDir ); + for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { + + vec3 lightColor, lightDir; + getHemisphereLightIndirect( hemisphereLights[ i ], normal, lightColor, lightDir ); + + totalIndirectReflectedDiffuse += + BRDF_Lambert( lightColor, lightDir, normal, diffuse ); } #endif -outgoingLight += totalReflectedLight + totalEmissiveLight; + +outgoingLight += + totalDirectReflectedDiffuse + + totalDirectReflectedSpecular + + totalIndirectReflectedDiffuse + + totalIndirectReflectedSpecular + + totalEmissiveLight; diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index ade58560d9b164..4f342cfc90f4cc 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -143,7 +143,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "uv2_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], THREE.ShaderChunk[ "lights_lambert_pars_vertex" ], - THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "color_pars_vertex" ], THREE.ShaderChunk[ "morphtarget_pars_vertex" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], @@ -348,7 +347,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "envmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], - THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], THREE.ShaderChunk[ "normalmap_pars_fragment" ], From 56b64721b8136c9b0219df9a8879aeb22672ee21 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 21:59:05 -0400 Subject: [PATCH 17/64] remove debug console output. --- src/renderers/WebGLRenderer.js | 10 +++------- src/renderers/webgl/WebGLProgram.js | 11 +++++------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index eeb14f69391221..7d6e0354db668e 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2110,14 +2110,13 @@ THREE.WebGLRenderer = function ( parameters ) { case 's': - //console.log( "uniform s", uniform, location ); // TODO: Optimize this. for( var propertyName in uniform.properties ) { + var property = uniform.properties[ propertyName ]; var locationProperty = location[ propertyName ]; var valueProperty = value[ propertyName ]; - //console.log( "uniformProperty", property, valueProperty ); - + switch( property.type ) { case 'f': _gl.uniform1f( locationProperty, valueProperty ); @@ -2142,18 +2141,15 @@ THREE.WebGLRenderer = function ( parameters ) { case 'sa': - //console.log( "uniform sa", uniform, location ); // TODO: Optimize this. for( var i = 0; i < value.length; i ++ ) { - //console.log( "uniformIndex", i ); for( var propertyName in uniform.properties ) { var property = uniform.properties[ propertyName ]; var locationProperty = location[ i ][ propertyName ]; var valueProperty = value[i][ propertyName ]; - //console.log( "uniformProperty", property, valueProperty, i ); - + switch( property.type ) { case 'f': _gl.uniform1f( locationProperty, valueProperty ); diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index e595520305d309..f134e58d78e8d1 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -1,6 +1,11 @@ THREE.WebGLProgram = ( function () { var programIdCount = 0; + + // TODO: Combine the regex + var structRe = /^([\w\d_]+)\.([\w\d_]+)$/; + var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; + var arrayRe = /^([\w\d_]+)\[0\]$/; function generateDefines( defines ) { @@ -26,12 +31,6 @@ THREE.WebGLProgram = ( function () { var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); - - // TODO: Combine. - var structRe = /^([\w\d_]+)\.([\w\d_]+)$/; - var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; - var arrayRe = /^([\w\d_]+)\[0\]$/; - for ( var i = 0; i < n; i ++ ) { var info = gl.getActiveUniform( program, i ); From d8552f349f65d79e2fcfe644ffb54328010ee949 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sat, 10 Oct 2015 22:14:08 -0400 Subject: [PATCH 18/64] introduce IncidentLight struct --- src/renderers/shaders/ShaderChunk/common.glsl | 48 +++++++++++-------- .../ShaderChunk/lights_lambert_vertex.glsl | 34 ++++++------- .../ShaderChunk/lights_phong_fragment.glsl | 30 ++++++------ 3 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index b6b922d18c6458..8318e1529bfab3 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -82,9 +82,15 @@ vec3 linearToOutput( in vec3 a ) { } -vec3 BRDF_Lambert( const in vec3 lightColor, const in vec3 lightDir, const in vec3 normal, const in vec3 diffuseColor ) { +struct IncidentLight { + vec3 color; + vec3 direction; +}; - return lightColor * diffuseColor * ( saturate( dot( normal, lightDir ) ) ); + +vec3 BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor ) { + + return incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) ); // the above should be scaled by '' * RECIPROCAL_PI' } @@ -117,17 +123,17 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess ) { +vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess ) { - vec3 halfDir = normalize( lightDir + viewDir ); + vec3 halfDir = normalize( incidentLight.direction + viewDir ); float dotNH = saturate( dot( normal, halfDir ) ); - float dotLH = saturate( dot( lightDir, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); float D = D_BlinnPhong( shininess, dotNH ); - return lightColor * F * ( G * D ); + return incidentLight.color * F * ( G * D ); } @@ -142,10 +148,10 @@ vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirLightDirect( const in DirectionalLight directionalLight, out vec3 lightColor, out vec3 lightDir ) { + void getDirLightDirect( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) { - lightDir = directionalLight.direction; - lightColor = directionalLight.color; + incidentLight.color = directionalLight.color; + incidentLight.direction = directionalLight.direction; } @@ -162,15 +168,15 @@ vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out vec3 lightColor, out vec3 lightDir ) { + void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out IncidentLight incidentLight ) { vec3 lightPosition = pointLight.position; vec3 lVector = lightPosition - position; - lightDir = normalize( lVector ); + incidentLight.direction = normalize( lVector ); - lightColor = pointLight.color; - lightColor *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + incidentLight.color = pointLight.color; + incidentLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); } @@ -190,18 +196,18 @@ vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out vec3 lightColor, out vec3 lightDir ) { + void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out IncidentLight incidentLight ) { vec3 lightPosition = spotLight.position; vec3 lVector = lightPosition - position; - lightDir = normalize( lVector ); + incidentLight.direction = normalize( lVector ); - float spotEffect = dot( spotLight.direction, lightDir ); + float spotEffect = dot( spotLight.direction, incidentLight.direction ); spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - lightColor = spotLight.color; - lightColor *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + incidentLight.color = spotLight.color; + incidentLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); } @@ -218,15 +224,15 @@ vec3 BRDF_BlinnPhong( const in vec3 lightColor, const in vec3 lightDir, const in uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereLightIndirect( const in HemisphereLight hemiLight, const in vec3 normal, out vec3 lightColor, out vec3 lightDir ) { + void getHemisphereLightIndirect( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) { float dotNL = dot( normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - lightColor = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - lightDir = normal; + incidentLight.direction = normal; } diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 53aeeeeadc1f7e..18d507af13649b 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -13,14 +13,14 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getPointLightDirect( pointLights[i], mvPosition.xyz, lightColor, lightDir ); + IncidentLight incidentLight; + getPointLightDirect( pointLights[ i ], mvPosition.xyz, incidentLight ); - vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); + vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); #endif @@ -32,14 +32,14 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getSpotLightDirect( spotLights[i], mvPosition.xyz, lightColor, lightDir ); + IncidentLight incidentLight; + getSpotLightDirect( spotLights[ i ], mvPosition.xyz, incidentLight ); - vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); + vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); #endif @@ -51,14 +51,14 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getDirLightDirect( directionalLights[i], lightColor, lightDir ); + IncidentLight incidentLight; + getDirLightDirect( directionalLights[ i ], incidentLight ); - vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); + vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); #endif @@ -70,16 +70,16 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getHemisphereLightIndirect( hemisphereLights[ i ], normal, lightColor, lightDir ); + IncidentLight incidentLight; + getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); - vLightFront += BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); #ifdef DOUBLE_SIDED - getHemisphereLightIndirect( hemisphereLights[ i ], -normal, lightColor, lightDir ); + incidentLight = getHemisphereLightIndirect( hemisphereLights[ i ], -normal ); - vLightBack += BRDF_Lambert( lightColor, lightDir, -normal, diffuse ); + vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index e91f365248f3e3..e981fd67a29bac 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -17,14 +17,14 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getPointLightDirect( pointLights[i], -vViewPosition, lightColor, lightDir ); + IncidentLight incidentLight; + getPointLightDirect( pointLights[ i ], -vViewPosition, incidentLight ); totalDirectReflectedDiffuse += - BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse ); totalDirectReflectedSpecular += - BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -34,14 +34,14 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getSpotLightDirect( spotLights[i], -vViewPosition, lightColor, lightDir ); + IncidentLight incidentLight; + getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); totalDirectReflectedDiffuse += - BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse ); totalDirectReflectedSpecular += - BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -51,14 +51,14 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getDirLightDirect( directionalLights[i], lightColor, lightDir ); + IncidentLight incidentLight; + getDirLightDirect( directionalLights[ i ], incidentLight ); totalDirectReflectedDiffuse += - BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse ); totalDirectReflectedSpecular += - BRDF_BlinnPhong( lightColor, lightDir, normal, viewDir, specular, shininess ); + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -68,11 +68,11 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vec3 lightColor, lightDir; - getHemisphereLightIndirect( hemisphereLights[ i ], normal, lightColor, lightDir ); + IncidentLight incidentLight; + getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); totalIndirectReflectedDiffuse += - BRDF_Lambert( lightColor, lightDir, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse ); } From f25fd9b4f85672d25901ec8d9916e5ba8cd5736b Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 07:12:59 -0400 Subject: [PATCH 19/64] add ReflectedLight struct to pair with IncidentLight struct. --- src/renderers/shaders/ShaderChunk/common.glsl | 10 ++++-- .../ShaderChunk/lights_lambert_vertex.glsl | 1 + .../ShaderChunk/lights_phong_fragment.glsl | 31 ++++++++++--------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 8318e1529bfab3..0042736dd325ff 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -83,10 +83,16 @@ vec3 linearToOutput( in vec3 a ) { struct IncidentLight { - vec3 color; - vec3 direction; + vec3 color; + vec3 direction; }; +struct ReflectedLight { + vec3 directSpecular; + vec3 directDiffuse; + vec3 indirectSpecular; + vec3 indirectDiffuse; +}; vec3 BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 18d507af13649b..b3719a9878a877 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -9,6 +9,7 @@ vLightFront = vec3( 0.0 ); vec3 normal = normalize( transformedNormal ); vec3 diffuse = vec3( 1.0 ); + #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index e981fd67a29bac..d89402b8b3e21c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,9 +1,10 @@ vec3 viewDir = normalize( vViewPosition ); -vec3 totalDirectReflectedSpecular = vec3( 0.0 ); -vec3 totalDirectReflectedDiffuse = vec3( 0.0 ); -vec3 totalIndirectReflectedSpecular = vec3( 0.0 ); -vec3 totalIndirectReflectedDiffuse = vec3( 0.0 ); +ReflectedLight reflectedLight; +reflectedLight.directSpecular = vec3( 0.0 ); +reflectedLight.directDiffuse = vec3( 0.0 ); +reflectedLight.indirectSpecular = vec3( 0.0 ); +reflectedLight.indirectDiffuse = vec3( 0.0 ); vec3 diffuse = diffuseColor.rgb; @@ -20,10 +21,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getPointLightDirect( pointLights[ i ], -vViewPosition, incidentLight ); - totalDirectReflectedDiffuse += + reflectedLight.directDiffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - totalDirectReflectedSpecular += + reflectedLight.directSpecular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -37,10 +38,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); - totalDirectReflectedDiffuse += + reflectedLight.directDiffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - totalDirectReflectedSpecular += + reflectedLight.directSpecular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -54,10 +55,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getDirLightDirect( directionalLights[ i ], incidentLight ); - totalDirectReflectedDiffuse += + reflectedLight.directDiffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - totalDirectReflectedSpecular += + reflectedLight.directSpecular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -71,7 +72,7 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); - totalIndirectReflectedDiffuse += + reflectedLight.indirectDiffuse += BRDF_Lambert( incidentLight, normal, diffuse ); } @@ -80,8 +81,8 @@ vec3 diffuse = diffuseColor.rgb; outgoingLight += - totalDirectReflectedDiffuse + - totalDirectReflectedSpecular + - totalIndirectReflectedDiffuse + - totalIndirectReflectedSpecular + + reflectedLight.directSpecular + + reflectedLight.directDiffuse + + reflectedLight.indirectSpecular + + reflectedLight.indirectDiffuse + totalEmissiveLight; From c66fd070f3b8c7eb14013ffe2b7db3b32fe7a0d0 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 07:34:58 -0400 Subject: [PATCH 20/64] simplier definition of ReflectedLight. --- src/renderers/shaders/ShaderChunk/common.glsl | 10 +++---- .../ShaderChunk/lights_phong_fragment.glsl | 27 ++++++++----------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 0042736dd325ff..146478c92649b1 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -88,10 +88,8 @@ struct IncidentLight { }; struct ReflectedLight { - vec3 directSpecular; - vec3 directDiffuse; - vec3 indirectSpecular; - vec3 indirectDiffuse; + vec3 specular; + vec3 diffuse; }; vec3 BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor ) { @@ -150,8 +148,6 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal vec3 color; }; - uniform DirectionalLight singleTestDirLight; - uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; void getDirLightDirect( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) { @@ -228,7 +224,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal vec3 groundColor; }; - uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + layout(packed)uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; void getHemisphereLightIndirect( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index d89402b8b3e21c..9508880b76b71c 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,10 +1,7 @@ vec3 viewDir = normalize( vViewPosition ); -ReflectedLight reflectedLight; -reflectedLight.directSpecular = vec3( 0.0 ); -reflectedLight.directDiffuse = vec3( 0.0 ); -reflectedLight.indirectSpecular = vec3( 0.0 ); -reflectedLight.indirectDiffuse = vec3( 0.0 ); +ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); vec3 diffuse = diffuseColor.rgb; @@ -21,10 +18,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getPointLightDirect( pointLights[ i ], -vViewPosition, incidentLight ); - reflectedLight.directDiffuse += + directReflectedLight.diffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - reflectedLight.directSpecular += + directReflectedLight.specular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -38,10 +35,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); - reflectedLight.directDiffuse += + directReflectedLight.diffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - reflectedLight.directSpecular += + directReflectedLight.specular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -55,10 +52,10 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getDirLightDirect( directionalLights[ i ], incidentLight ); - reflectedLight.directDiffuse += + directReflectedLight.diffuse += BRDF_Lambert( incidentLight, normal, diffuse ); - reflectedLight.directSpecular += + directReflectedLight.specular += BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -72,7 +69,7 @@ vec3 diffuse = diffuseColor.rgb; IncidentLight incidentLight; getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); - reflectedLight.indirectDiffuse += + indirectReflectedLight.diffuse += BRDF_Lambert( incidentLight, normal, diffuse ); } @@ -81,8 +78,6 @@ vec3 diffuse = diffuseColor.rgb; outgoingLight += - reflectedLight.directSpecular + - reflectedLight.directDiffuse + - reflectedLight.indirectSpecular + - reflectedLight.indirectDiffuse + + directReflectedLight.specular + directReflectedLight.diffuse + + indirectReflectedLight.specular + indirectReflectedLight.diffuse + totalEmissiveLight; From fb5472824851cd0f8ef8deae07cfc8ad6530d1b9 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 07:36:55 -0400 Subject: [PATCH 21/64] declare reused variable only once. --- .../shaders/ShaderChunk/lights_phong_fragment.glsl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 9508880b76b71c..df3af3074fbb99 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -11,11 +11,12 @@ vec3 diffuse = diffuseColor.rgb; #endif +IncidentLight incidentLight; + #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - IncidentLight incidentLight; getPointLightDirect( pointLights[ i ], -vViewPosition, incidentLight ); directReflectedLight.diffuse += @@ -32,7 +33,6 @@ vec3 diffuse = diffuseColor.rgb; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - IncidentLight incidentLight; getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); directReflectedLight.diffuse += @@ -49,7 +49,6 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - IncidentLight incidentLight; getDirLightDirect( directionalLights[ i ], incidentLight ); directReflectedLight.diffuse += @@ -66,7 +65,6 @@ vec3 diffuse = diffuseColor.rgb; for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - IncidentLight incidentLight; getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); indirectReflectedLight.diffuse += From 8d0d4542a63d179ea3a60f3e3942b006edb38e47 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 08:37:58 -0400 Subject: [PATCH 22/64] cleaner design. --- src/renderers/shaders/ShaderChunk/common.glsl | 16 ++++---- .../ShaderChunk/lights_lambert_vertex.glsl | 37 ++++++++++--------- .../ShaderChunk/lights_phong_fragment.glsl | 28 ++++++-------- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 146478c92649b1..0e1a0f7a01c2e8 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -92,9 +92,9 @@ struct ReflectedLight { vec3 diffuse; }; -vec3 BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor ) { +void BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - return incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) ); + reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) ); // the above should be scaled by '' * RECIPROCAL_PI' } @@ -127,7 +127,7 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess ) { +void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { vec3 halfDir = normalize( incidentLight.direction + viewDir ); float dotNH = saturate( dot( normal, halfDir ) ); @@ -137,7 +137,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); float D = D_BlinnPhong( shininess, dotNH ); - return incidentLight.color * F * ( G * D ); + reflectedLight.specular += incidentLight.color * F * ( G * D ); } @@ -150,7 +150,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirLightDirect( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) { + void getDirIncidentLight( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) { incidentLight.color = directionalLight.color; incidentLight.direction = directionalLight.direction; @@ -170,7 +170,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointLightDirect( const in PointLight pointLight, const in vec3 position, out IncidentLight incidentLight ) { + void getPointIncidentLight( const in PointLight pointLight, const in vec3 position, out IncidentLight incidentLight ) { vec3 lightPosition = pointLight.position; @@ -198,7 +198,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotLightDirect( const in SpotLight spotLight, const in vec3 position, out IncidentLight incidentLight ) { + void getSpotIncidentLight( const in SpotLight spotLight, const in vec3 position, out IncidentLight incidentLight ) { vec3 lightPosition = spotLight.position; @@ -226,7 +226,7 @@ vec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal layout(packed)uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereLightIndirect( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) { + void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) { float dotNL = dot( normal, hemiLight.direction ); diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index b3719a9878a877..22dd3d2b0b32c7 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -9,19 +9,23 @@ vLightFront = vec3( 0.0 ); vec3 normal = normalize( transformedNormal ); vec3 diffuse = vec3( 1.0 ); +IncidentLight incidentLight; +ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + +vec3 backNormal = -normal; #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - IncidentLight incidentLight; - getPointLightDirect( pointLights[ i ], mvPosition.xyz, incidentLight ); + getPointIncidentLight( pointLights[ i ], mvPosition.xyz, incidentLight ); - vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); + BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); #endif @@ -33,14 +37,13 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - IncidentLight incidentLight; - getSpotLightDirect( spotLights[ i ], mvPosition.xyz, incidentLight ); + getSpotIncidentLight( spotLights[ i ], mvPosition.xyz, incidentLight ); - vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); + BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); #endif @@ -52,14 +55,13 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - IncidentLight incidentLight; - getDirLightDirect( directionalLights[ i ], incidentLight ); + getDirIncidentLight( directionalLights[ i ], incidentLight ); - vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); + vLightFront += BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); + BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); #endif @@ -71,16 +73,15 @@ vec3 diffuse = vec3( 1.0 ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - IncidentLight incidentLight; getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); - vLightFront += BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - incidentLight = getHemisphereLightIndirect( hemisphereLights[ i ], -normal ); + getHemisphereIncidentLight( hemisphereLights[ i ], backNormal, incidentLight ); - vLightBack += BRDF_Lambert( incidentLight, -normal, diffuse ); + BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); #endif @@ -88,10 +89,10 @@ vec3 diffuse = vec3( 1.0 ); #endif -vLightFront += ambientLightColor; +vLightFront += ambientLightColor + frontReflectedLight.diffuse; #ifdef DOUBLE_SIDED - vLightBack += ambientLightColor; + vLightBack += ambientLightColor + backReflectedLight.diffuse; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index df3af3074fbb99..dbf65cc677611d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -17,13 +17,12 @@ IncidentLight incidentLight; for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointLightDirect( pointLights[ i ], -vViewPosition, incidentLight ); + getPointIncidentLight( pointLights[ i ], -vViewPosition, incidentLight ); - directReflectedLight.diffuse += - BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); + + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); - directReflectedLight.specular += - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); } @@ -35,11 +34,9 @@ IncidentLight incidentLight; getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); - directReflectedLight.diffuse += - BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); - directReflectedLight.specular += - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); } @@ -49,13 +46,11 @@ IncidentLight incidentLight; for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirLightDirect( directionalLights[ i ], incidentLight ); + getDirIncidentLight( directionalLights[ i ], incidentLight ); - directReflectedLight.diffuse += - BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); - directReflectedLight.specular += - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess ); + BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); } @@ -65,10 +60,9 @@ IncidentLight incidentLight; for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); + getHemisphereIncidentLight( hemisphereLights[ i ], normal, incidentLight ); - indirectReflectedLight.diffuse += - BRDF_Lambert( incidentLight, normal, diffuse ); + BRDF_Lambert( incidentLight, normal, diffuse, indirectReflectedLight ); } From b10172933174870821f776fe9be30b3c46fd3b80 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 21:21:38 -0400 Subject: [PATCH 23/64] add energy perserving rgb/monochrome modes. add BRDF_OrenNayar. --- src/renderers/shaders/ShaderChunk/common.glsl | 30 +++++++++++++++++-- .../ShaderChunk/lights_lambert_vertex.glsl | 19 ++++-------- .../ShaderChunk/lights_phong_fragment.glsl | 26 ++++++++++++---- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 0e1a0f7a01c2e8..7db3c09237bc7d 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -8,6 +8,16 @@ #define saturate(a) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) +float luminance( const in vec3 color ) { + const vec3 W = vec3(0.2125, 0.7154, 0.0721); + return dot( color, W ); +} + +float average( const in vec3 color ) { + const vec3 W = vec3(0.3333, 0.3333, 0.3333); + return dot( color, W ); +} + vec3 transformDirection( in vec3 normal, in mat4 matrix ) { return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); @@ -94,11 +104,27 @@ struct ReflectedLight { void BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) ); + reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) * RECIPROCAL_PI ); + +} + +void BRDF_OrenNayar( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { + + vec3 halfDir = normalize( incidentLight.direction + viewDir ); + float dotVH = saturate( dot( viewDir, halfDir ) ); + float dotNV = saturate( dot( normal, viewDir ) ); + float dotNL = saturate( dot( normal, incidentLight.direction ) ); + + float m2 = roughness * roughness; + float termA = 1.0 - 0.5 * m2 / (m2 + 0.33); + float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; + float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); + + reflectedLight.diffuse = incidentLight.color * diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); - // the above should be scaled by '' * RECIPROCAL_PI' } + vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { // Original approximation by Christophe Schlick '94 diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 22dd3d2b0b32c7..28718cc6d3da0a 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -1,19 +1,12 @@ -vLightFront = vec3( 0.0 ); - -#ifdef DOUBLE_SIDED - - vLightBack = vec3( 0.0 ); - -#endif - vec3 normal = normalize( transformedNormal ); +vec3 backNormal = -normal; + vec3 diffuse = vec3( 1.0 ); IncidentLight incidentLight; ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -vec3 backNormal = -normal; #if MAX_POINT_LIGHTS > 0 @@ -57,7 +50,7 @@ vec3 backNormal = -normal; getDirIncidentLight( directionalLights[ i ], incidentLight ); - vLightFront += BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED @@ -89,10 +82,10 @@ vec3 backNormal = -normal; #endif -vLightFront += ambientLightColor + frontReflectedLight.diffuse; +vLightFront = ambientLightColor + frontReflectedLight.diffuse; #ifdef DOUBLE_SIDED - vLightBack += ambientLightColor + backReflectedLight.diffuse; + vLightBack = ambientLightColor + backReflectedLight.diffuse; -#endif +#endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index dbf65cc677611d..dd47c8fb46334d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,17 +1,28 @@ vec3 viewDir = normalize( vViewPosition ); -ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - vec3 diffuse = diffuseColor.rgb; #ifdef METAL - diffuse *= specular; + diffuse = vec3( 0.0 ); + +#endif + +#define ENERGY_PRESERVING_MONOCHROME + +#ifdef ENERGY_PRESERVING_RGB + + diffuse *= whiteCompliment( specular ); + +#elif defined( ENERGY_PRESERVING_MONOCHROME ) + + diffuse *= whiteCompliment( luminance( specular ) ); #endif IncidentLight incidentLight; +ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); #if MAX_POINT_LIGHTS > 0 @@ -20,10 +31,10 @@ IncidentLight incidentLight; getPointIncidentLight( pointLights[ i ], -vViewPosition, incidentLight ); BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); - } #endif @@ -32,9 +43,10 @@ IncidentLight incidentLight; for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotLightDirect( spotLights[ i ], -vViewPosition, incidentLight ); + getSpotIncidentLight( spotLights[ i ], -vViewPosition, incidentLight ); BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); @@ -49,6 +61,7 @@ IncidentLight incidentLight; getDirIncidentLight( directionalLights[ i ], incidentLight ); BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); @@ -63,6 +76,7 @@ IncidentLight incidentLight; getHemisphereIncidentLight( hemisphereLights[ i ], normal, incidentLight ); BRDF_Lambert( incidentLight, normal, diffuse, indirectReflectedLight ); + //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, indirectReflectedLight ); } From ea903ed02ff4dd17a3de3eda411e19279c30f75c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Sun, 11 Oct 2015 22:15:22 -0400 Subject: [PATCH 24/64] introducing the GeometricContext struct, broken hemisphere lights. --- examples/webgl_animation_skinning_morph.html | 2 + examples/webgl_lights_pointlights.html | 2 +- examples/webgl_morphnormals.html | 2 +- src/renderers/WebGLRenderer.js | 9 ++-- src/renderers/shaders/ShaderChunk/common.glsl | 44 +++++++++++-------- .../ShaderChunk/lights_lambert_vertex.glsl | 30 +++++++------ .../ShaderChunk/lights_phong_fragment.glsl | 32 +++++++------- 7 files changed, 67 insertions(+), 54 deletions(-) diff --git a/examples/webgl_animation_skinning_morph.html b/examples/webgl_animation_skinning_morph.html index cb5b938a224fb4..c3d95df390271f 100644 --- a/examples/webgl_animation_skinning_morph.html +++ b/examples/webgl_animation_skinning_morph.html @@ -158,6 +158,8 @@ var loader = new THREE.JSONLoader(); loader.load( "models/skinned/knight.js", function ( geometry, materials ) { + console.log( 'materials', materials ); + createScene( geometry, materials, 0, FLOOR, -300, 60 ) } ); diff --git a/examples/webgl_lights_pointlights.html b/examples/webgl_lights_pointlights.html index f40066ccde64ef..1c89b477973882 100644 --- a/examples/webgl_lights_pointlights.html +++ b/examples/webgl_lights_pointlights.html @@ -72,7 +72,7 @@ var callback = function( geometry ) { - object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffffff, shininess: 50 } ) ); + object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0x111111, shininess: 50 } ) ); object.scale.x = object.scale.y = object.scale.z = 0.80; scene.add( object ); diff --git a/examples/webgl_morphnormals.html b/examples/webgl_morphnormals.html index a2cad7278ad742..66dd6db32726cc 100644 --- a/examples/webgl_morphnormals.html +++ b/examples/webgl_morphnormals.html @@ -114,7 +114,7 @@ geometry.computeVertexNormals(); geometry.computeMorphNormals(); - var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } ); + var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } ); var mesh = new THREE.Mesh( geometry, material ); mesh.scale.set( 1.5, 1.5, 1.5 ); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 7d6e0354db668e..a5fde248edc645 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2518,7 +2518,7 @@ THREE.WebGLRenderer = function ( parameters ) { if( ! light.__webglUniforms ) { light.__webglUniforms = { - position: new THREE.Vector3(), + direction: new THREE.Vector3(), skyColor: new THREE.Color(), groundColor: new THREE.Color() } @@ -2532,10 +2532,11 @@ THREE.WebGLRenderer = function ( parameters ) { continue; } - lightUniforms.position.setFromMatrixPosition( light.matrixWorld ); - lightUniforms.position.transformDirection( viewMatrix ); + lightUniforms.direction.setFromMatrixPosition( light.matrixWorld ); + lightUniforms.direction.transformDirection( viewMatrix ); + lightUniforms.direction.normalize(); - lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); + lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); lightUniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); } diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 7db3c09237bc7d..e3427d7e21ce4f 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -102,18 +102,24 @@ struct ReflectedLight { vec3 diffuse; }; -void BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { +struct GeometricContext { + vec3 position; + vec3 normal; + vec3 viewDir; +}; + +void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) * RECIPROCAL_PI ); + reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( geometryContext.normal, incidentLight.direction ) ) * RECIPROCAL_PI ); } -void BRDF_OrenNayar( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { +void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { - vec3 halfDir = normalize( incidentLight.direction + viewDir ); - float dotVH = saturate( dot( viewDir, halfDir ) ); - float dotNV = saturate( dot( normal, viewDir ) ); - float dotNL = saturate( dot( normal, incidentLight.direction ) ); + vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); + float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); + float dotNV = saturate( dot( geometryContext.normal, geometryContext.viewDir ) ); + float dotNL = saturate( dot( geometryContext.normal, incidentLight.direction ) ); float m2 = roughness * roughness; float termA = 1.0 - 0.5 * m2 / (m2 + 0.33); @@ -153,10 +159,10 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { +void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { - vec3 halfDir = normalize( incidentLight.direction + viewDir ); - float dotNH = saturate( dot( normal, halfDir ) ); + vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); + float dotNH = saturate( dot( geometryContext.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); @@ -176,7 +182,7 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirIncidentLight( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) { + void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { incidentLight.color = directionalLight.color; incidentLight.direction = directionalLight.direction; @@ -196,11 +202,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointIncidentLight( const in PointLight pointLight, const in vec3 position, out IncidentLight incidentLight ) { + void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { vec3 lightPosition = pointLight.position; - vec3 lVector = lightPosition - position; + vec3 lVector = lightPosition - geometryContext.position; incidentLight.direction = normalize( lVector ); incidentLight.color = pointLight.color; @@ -224,11 +230,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotIncidentLight( const in SpotLight spotLight, const in vec3 position, out IncidentLight incidentLight ) { + void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { vec3 lightPosition = spotLight.position; - vec3 lVector = lightPosition - position; + vec3 lVector = lightPosition - geometryContext.position; incidentLight.direction = normalize( lVector ); float spotEffect = dot( spotLight.direction, incidentLight.direction ); @@ -250,17 +256,17 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal vec3 groundColor; }; - layout(packed)uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) { + void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { - float dotNL = dot( normal, hemiLight.direction ); + float dotNL = dot( geometryContext.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - incidentLight.direction = normal; + incidentLight.direction = geometryContext.normal; } diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 28718cc6d3da0a..1b3eb663c8b2a2 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -1,5 +1,5 @@ +vec3 viewDir = normalize( -mvPosition.xyz ); vec3 normal = normalize( transformedNormal ); -vec3 backNormal = -normal; vec3 diffuse = vec3( 1.0 ); @@ -7,18 +7,20 @@ IncidentLight incidentLight; ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +GeometricContext geometricContext = GeometricContext( mvPosition.xyz, normal, viewDir ); +GeometricContext backGeometricContext = GeometricContext( mvPosition.xyz, -normal, viewDir ); #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], mvPosition.xyz, incidentLight ); + getPointIncidentLight( pointLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); #endif @@ -30,13 +32,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], mvPosition.xyz, incidentLight ); + getSpotIncidentLight( spotLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); #endif @@ -48,13 +50,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], incidentLight ); + getDirIncidentLight( directionalLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); #endif @@ -66,15 +68,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereLightIndirect( hemisphereLights[ i ], normal, incidentLight ); + getHemisphereLightIndirect( hemisphereLights[ i ], geometricContext, , incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, , diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - getHemisphereIncidentLight( hemisphereLights[ i ], backNormal, incidentLight ); + getHemisphereIncidentLight( hemisphereLights[ i ], backGeometricContext, incidentLight ); - BRDF_Lambert( incidentLight, backNormal, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index dd47c8fb46334d..e56b6f257c521e 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -24,16 +24,18 @@ IncidentLight incidentLight; ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +GeometricContext geometricContext = GeometricContext( -vViewPosition, normal, viewDir ); + #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], -vViewPosition, incidentLight ); + getPointIncidentLight( pointLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); } @@ -43,12 +45,12 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], -vViewPosition, incidentLight ); + getSpotIncidentLight( spotLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); } @@ -58,12 +60,12 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], incidentLight ); + getDirIncidentLight( directionalLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, normal, viewDir, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); } @@ -73,10 +75,10 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereIncidentLight( hemisphereLights[ i ], normal, incidentLight ); + getHemisphereIncidentLight( hemisphereLights[ i ], geometricContext, incidentLight ); - BRDF_Lambert( incidentLight, normal, diffuse, indirectReflectedLight ); - //BRDF_OrenNayar( incidentLight, normal, viewDir, diffuse, 0.5, indirectReflectedLight ); + BRDF_Lambert( incidentLight, geometricContext, diffuse, indirectReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, indirectReflectedLight ); } From ea9f26a98183b3c0e509fff8dd5472c4ea9db181 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 07:24:23 -0400 Subject: [PATCH 25/64] hemisphere lights work again. --- examples/webgl_lights_hemisphere.html | 2 +- src/renderers/shaders/UniformsLib.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/webgl_lights_hemisphere.html b/examples/webgl_lights_hemisphere.html index 939bdc73fa3e9c..12dfdfae30218f 100644 --- a/examples/webgl_lights_hemisphere.html +++ b/examples/webgl_lights_hemisphere.html @@ -203,7 +203,7 @@ morphColorsToFaceColors( geometry ); - var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 20, morphTargets: true, vertexColors: THREE.FaceColors, shading: THREE.FlatShading } ); + var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 20, morphTargets: true, vertexColors: THREE.FaceColors, shading: THREE.FlatShading } ); var mesh = new THREE.Mesh( geometry, material ); var s = 0.35; diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index 8534ef5717df3b..0a74f55ff5ebe0 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -84,8 +84,8 @@ THREE.UniformsLib = { "hemisphereLights" : { type: "sa", value: [], properties: { "direction": { type: "v3" }, - "skyColor": { type: "v3" }, - "groundColor": { type: "v3" } + "skyColor": { type: "c" }, + "groundColor": { type: "c" } } }, "pointLights" : { type: "sa", value: [], properties: { From 27dc0ad0770c1955a0ee9b1be0edddc72984b302 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 07:33:59 -0400 Subject: [PATCH 26/64] unify energy conservating with correct diffuse lambertian reflectance --- src/renderers/shaders/ShaderChunk/common.glsl | 13 ++++++++++++- .../shaders/ShaderChunk/lights_lambert_vertex.glsl | 1 + .../shaders/ShaderChunk/lights_phong_fragment.glsl | 4 +--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index e3427d7e21ce4f..6d5ebfccba7dc3 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -91,6 +91,8 @@ vec3 linearToOutput( in vec3 a ) { } +//#define ENERGY_PRESERVING_MONOCHROME + struct IncidentLight { vec3 color; @@ -108,9 +110,18 @@ struct GeometricContext { vec3 viewDir; }; + void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( geometryContext.normal, incidentLight.direction ) ) * RECIPROCAL_PI ); + float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); + + #if defined( ENERGY_PRESERVING_MONOCHROME ) || defined( ENERGY_PRESERVING_RGB ) + + lambertianReflectance *= RECIPROCAL_PI; + + #endif + + reflectedLight.diffuse += incidentLight.color * diffuseColor * lambertianReflectance; } diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 1b3eb663c8b2a2..06b8f7c79c97b5 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -3,6 +3,7 @@ vec3 normal = normalize( transformedNormal ); vec3 diffuse = vec3( 1.0 ); + IncidentLight incidentLight; ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index e56b6f257c521e..af66c374665061 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -8,9 +8,7 @@ vec3 diffuse = diffuseColor.rgb; #endif -#define ENERGY_PRESERVING_MONOCHROME - -#ifdef ENERGY_PRESERVING_RGB +#if defined( ENERGY_PRESERVING_RGB ) diffuse *= whiteCompliment( specular ); From 9bc5094ad5801700776fcf7be8ac525ee0733d9d Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 07:40:58 -0400 Subject: [PATCH 27/64] geometryContext -> geometry. --- .../ShaderChunk/lights_lambert_vertex.glsl | 37 +++++++++---------- .../ShaderChunk/lights_phong_fragment.glsl | 37 +++++++++---------- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 06b8f7c79c97b5..eb82b52ef5019d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -1,27 +1,24 @@ -vec3 viewDir = normalize( -mvPosition.xyz ); -vec3 normal = normalize( transformedNormal ); - vec3 diffuse = vec3( 1.0 ); - IncidentLight incidentLight; + +GeometricContext geometry = GeometricContext( mvPosition.xyz, normalize( transformedNormal ), normalize( -mvPosition.xyz ) ); +GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.normal, geometry.viewDir ); + ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -GeometricContext geometricContext = GeometricContext( mvPosition.xyz, normal, viewDir ); -GeometricContext backGeometricContext = GeometricContext( mvPosition.xyz, -normal, viewDir ); - #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], geometricContext, incidentLight ); + getPointIncidentLight( pointLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -33,13 +30,13 @@ GeometricContext backGeometricContext = GeometricContext( mvPosition.xyz, -norma for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], geometricContext, incidentLight ); + getSpotIncidentLight( spotLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -51,13 +48,13 @@ GeometricContext backGeometricContext = GeometricContext( mvPosition.xyz, -norma for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], geometricContext, incidentLight ); + getDirIncidentLight( directionalLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -69,15 +66,15 @@ GeometricContext backGeometricContext = GeometricContext( mvPosition.xyz, -norma for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereLightIndirect( hemisphereLights[ i ], geometricContext, , incidentLight ); + getHemisphereLightIndirect( hemisphereLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, , diffuse, frontReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - getHemisphereIncidentLight( hemisphereLights[ i ], backGeometricContext, incidentLight ); + getHemisphereIncidentLight( hemisphereLights[ i ], backGeometry, incidentLight ); - BRDF_Lambert( incidentLight, backGeometricContext, diffuse, backReflectedLight ); + BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index af66c374665061..4c042f66cb506d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,5 +1,3 @@ -vec3 viewDir = normalize( vViewPosition ); - vec3 diffuse = diffuseColor.rgb; #ifdef METAL @@ -19,21 +17,22 @@ vec3 diffuse = diffuseColor.rgb; #endif IncidentLight incidentLight; + +GeometricContext geometry = GeometricContext( -vViewPosition, normal, normalize(vViewPosition ) ); + ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -GeometricContext geometricContext = GeometricContext( -vViewPosition, normal, viewDir ); - #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], geometricContext, incidentLight ); + getPointIncidentLight( pointLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); } @@ -43,12 +42,12 @@ GeometricContext geometricContext = GeometricContext( -vViewPosition, normal, vi for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], geometricContext, incidentLight ); + getSpotIncidentLight( spotLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); } @@ -58,12 +57,12 @@ GeometricContext geometricContext = GeometricContext( -vViewPosition, normal, vi for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], geometricContext, incidentLight ); + getDirIncidentLight( directionalLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, geometricContext, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); } @@ -73,10 +72,10 @@ GeometricContext geometricContext = GeometricContext( -vViewPosition, normal, vi for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereIncidentLight( hemisphereLights[ i ], geometricContext, incidentLight ); + getHemisphereIncidentLight( hemisphereLights[ i ], geometry, incidentLight ); - BRDF_Lambert( incidentLight, geometricContext, diffuse, indirectReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometricContext, diffuse, 0.5, indirectReflectedLight ); + BRDF_Lambert( incidentLight, geometry, diffuse, indirectReflectedLight ); + //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, indirectReflectedLight ); } From 36c599679b7cc2d034f3901ba00e2c16cc4de40b Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 20:24:31 -0400 Subject: [PATCH 28/64] initial AreaLight implementation. --- src/renderers/shaders/ShaderChunk/common.glsl | 72 ++++++++++++++----- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 6d5ebfccba7dc3..a58588c1c964b3 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -4,18 +4,15 @@ #define RECIPROCAL_PI2 0.15915494 #define LOG2 1.442695 #define EPSILON 1e-6 -#define PHYSICALLY_BASED_RENDERING #define saturate(a) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) float luminance( const in vec3 color ) { - const vec3 W = vec3(0.2125, 0.7154, 0.0721); - return dot( color, W ); + return dot( color, vec3(0.2125, 0.7154, 0.0721) ); } float average( const in vec3 color ) { - const vec3 W = vec3(0.3333, 0.3333, 0.3333); - return dot( color, W ); + return dot( color, vec3(0.3333, 0.3333, 0.3333) ); } vec3 transformDirection( in vec3 normal, in mat4 matrix ) { @@ -170,10 +167,10 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { +void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { - vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); - float dotNH = saturate( dot( geometryContext.normal, halfDir ) ); + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); @@ -193,7 +190,7 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { + void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { incidentLight.color = directionalLight.color; incidentLight.direction = directionalLight.direction; @@ -213,11 +210,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { + void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { vec3 lightPosition = pointLight.position; - vec3 lVector = lightPosition - geometryContext.position; + vec3 lVector = lightPosition - geometry.position; incidentLight.direction = normalize( lVector ); incidentLight.color = pointLight.color; @@ -241,11 +238,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { + void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { vec3 lightPosition = spotLight.position; - vec3 lVector = lightPosition - geometryContext.position; + vec3 lVector = lightPosition - geometry.position; incidentLight.direction = normalize( lVector ); float spotEffect = dot( spotLight.direction, incidentLight.direction ); @@ -258,6 +255,49 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo #endif +#define MAX_AREA_LIGHTS 0 + +#if MAX_AREA_LIGHTS > 0 + + struct HemisphereLight { + vec3 position; + vec3 width; + vec3 height; + vec3 color; + float distance; + float decay; + }; + + uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; + + void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + + float widthLength = length( areaLight.width ); + float heightLength = length( areaLight.height ); + + vec3 widthDir = areaLight.width / widthLength; + vec3 heightDir = areaLight.height / heightLength; + vec3 direction = normalize( cross( widthDir, heightDir ) ); + + // project onto plane and calculate direction from center to the projection. + vec3 planePosition = projectOnPlane( viewDir, areaLight.position, direction ), // projection in plane + vec3 planeOffset = planePosition - areaLight.position; + + // calculate distance from area: + vec2 planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); + vec2 clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); + vec3 clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); + + vec3 lVector = ( clampedPlanePosition - geometry.position ); + float lLength = length( lVector ); + + incidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lLength, areaLight.distance, areaLight.decay ) * 0.01; + incidentLight.direction = lVector / lLength; + + } + +#endif + #if MAX_HEMI_LIGHTS > 0 @@ -269,15 +309,15 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { + void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - float dotNL = dot( geometryContext.normal, hemiLight.direction ); + float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - incidentLight.direction = geometryContext.normal; + incidentLight.direction = geometry.normal; } From 5d4ad8513534aa89147e69e4b4ce54453b3e3db1 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 21:55:10 -0400 Subject: [PATCH 29/64] rely less on the preprocessing, add GGX shader with SmithGeometry visibility, GGX distribution. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 122 +++++++ src/renderers/shaders/ShaderChunk/common.glsl | 306 +----------------- src/renderers/shaders/ShaderChunk/lights.glsl | 183 +++++++++++ src/renderers/shaders/ShaderChunk/math.glsl | 56 ++++ src/renderers/shaders/ShaderLib.js | 6 + utils/build/includes/common.json | 3 + 6 files changed, 382 insertions(+), 294 deletions(-) create mode 100644 src/renderers/shaders/ShaderChunk/bsdfs.glsl create mode 100644 src/renderers/shaders/ShaderChunk/lights.glsl create mode 100644 src/renderers/shaders/ShaderChunk/math.glsl diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl new file mode 100644 index 00000000000000..ad949603ea8c04 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -0,0 +1,122 @@ +//#define ENERGY_PRESERVING_MONOCHROME + + +struct IncidentLight { + vec3 color; + vec3 direction; +}; + +struct ReflectedLight { + vec3 specular; + vec3 diffuse; +}; + +struct GeometricContext { + vec3 position; + vec3 normal; + vec3 viewDir; +}; + + +void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { + + float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); + + #if defined( ENERGY_PRESERVING_MONOCHROME ) || defined( ENERGY_PRESERVING_RGB ) + + lambertianReflectance *= RECIPROCAL_PI; + + #endif + + reflectedLight.diffuse += incidentLight.color * diffuseColor * lambertianReflectance; + +} + +void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { + + vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); + float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); + float dotNV = saturate( dot( geometryContext.normal, geometryContext.viewDir ) ); + float dotNL = saturate( dot( geometryContext.normal, incidentLight.direction ) ); + + float m2 = roughness * roughness; + float termA = 1.0 - 0.5 * m2 / (m2 + 0.33); + float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; + float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); + + reflectedLight.diffuse = incidentLight.color * diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); + +} + +vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { + + // Original approximation by Christophe Schlick '94 + //;float fresnel = pow( 1.0 - dotLH, 5.0 ); + + // Optimized variant (presented by Epic at SIGGRAPH '13) + float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH ); + + return F0 + ( 1.0 - F0 ) * fresnel; + +} + +float G_SmithSchlick( float roughness2, float dotNL, float dotNV ) { + + float termL = ( dotNL + sqrt( roughness2 + ( 1.0 - roughness2 ) * square( dotNL ) ) ); + float termV = ( dotNV + sqrt( roughness2 + ( 1.0 - roughness2 ) * square( dotNV ) ) ); + + return 1.0 / ( abs( termL * termV ) + 0.0000001 ); + +} + +float D_GGX( float roughness2, float dotNH ) { + + // should 1/PI be in this distribution? + float denom = square( dotNH ) * ( roughness2 - 1.0 ) + 1.0; + return roughness2 / ( PI * square( denom ) + 0.0000001 ); + +} + +float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { + + // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) + return 0.25; + +} + +void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness2, inout ReflectedLight reflectedLight ) { + + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + + vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_SmithSchlick( roughness2, dotNL, dotNV ); + float D = D_GGX( roughness2, dotNH ); + + reflectedLight.specular += incidentLight.color * F * ( G * D ); + +} + +float D_BlinnPhong( const in float shininess, const in float dotNH ) { + + // factor of 1/PI in distribution term omitted ??? + return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); + +} + +void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { + + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + + vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); + float D = D_BlinnPhong( shininess, dotNH ); + + reflectedLight.specular += incidentLight.color * F * ( G * D ); + +} diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index a58588c1c964b3..4acaa09172404f 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -1,64 +1,17 @@ -#define PI 3.14159 -#define PI2 6.28318 -#define RECIPROCAL_PI 0.31830988618 -#define RECIPROCAL_PI2 0.15915494 -#define LOG2 1.442695 -#define EPSILON 1e-6 -#define saturate(a) clamp( a, 0.0, 1.0 ) -#define whiteCompliment(a) ( 1.0 - saturate( a ) ) +const float PI = 3.14159; +const float PI2 = 6.28318; +const float RECIPROCAL_PI = 0.31830988618; +const float RECIPROCAL_PI2 = 0.15915494; +const float LOG2 = 1.442695; +const float EPSILON = 1e-6; -float luminance( const in vec3 color ) { - return dot( color, vec3(0.2125, 0.7154, 0.0721) ); -} - -float average( const in vec3 color ) { - return dot( color, vec3(0.3333, 0.3333, 0.3333) ); -} - -vec3 transformDirection( in vec3 normal, in mat4 matrix ) { - - return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); - -} - -// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations -vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { +float square( const in float a ) { return a*a; } +float saturate( const in float a ) { return clamp( a, 0.0, 1.0 ); } +vec3 saturate( const in vec3 a ) { return clamp( a, 0.0, 1.0 ); } +vec3 whiteCompliment( const in vec3 color ) { return 1.0 - saturate( color ); } +float luminance( const in vec3 color ) { return dot( color, vec3( 0.2125, 0.7154, 0.0721 ) ); } +float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } - return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); - -} - -vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { - - float distance = dot( planeNormal, point - pointOnPlane ); - - return - distance * planeNormal + point; - -} - -float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { - - return sign( dot( point - pointOnPlane, planeNormal ) ); - -} - -vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { - - return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; - -} - -float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { - - if ( decayExponent > 0.0 ) { - - return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); - - } - - return 1.0; - -} vec3 inputToLinear( in vec3 a ) { @@ -87,238 +40,3 @@ vec3 linearToOutput( in vec3 a ) { #endif } - -//#define ENERGY_PRESERVING_MONOCHROME - - -struct IncidentLight { - vec3 color; - vec3 direction; -}; - -struct ReflectedLight { - vec3 specular; - vec3 diffuse; -}; - -struct GeometricContext { - vec3 position; - vec3 normal; - vec3 viewDir; -}; - - -void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - - float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); - - #if defined( ENERGY_PRESERVING_MONOCHROME ) || defined( ENERGY_PRESERVING_RGB ) - - lambertianReflectance *= RECIPROCAL_PI; - - #endif - - reflectedLight.diffuse += incidentLight.color * diffuseColor * lambertianReflectance; - -} - -void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { - - vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); - float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); - float dotNV = saturate( dot( geometryContext.normal, geometryContext.viewDir ) ); - float dotNL = saturate( dot( geometryContext.normal, incidentLight.direction ) ); - - float m2 = roughness * roughness; - float termA = 1.0 - 0.5 * m2 / (m2 + 0.33); - float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; - float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); - - reflectedLight.diffuse = incidentLight.color * diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); - -} - - -vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { - - // Original approximation by Christophe Schlick '94 - //;float fresnel = pow( 1.0 - dotLH, 5.0 ); - - // Optimized variant (presented by Epic at SIGGRAPH '13) - float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH ); - - return F0 + ( 1.0 - F0 ) * fresnel; - -} - -float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { - - // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) - - return 0.25; - -} - -float D_BlinnPhong( const in float shininess, const in float dotNH ) { - - // factor of 1/PI in distribution term omitted - - return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); - -} - -void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { - - vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); - float dotNH = saturate( dot( geometry.normal, halfDir ) ); - float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); - - vec3 F = F_Schlick( specularColor, dotLH ); - float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); - float D = D_BlinnPhong( shininess, dotNH ); - - reflectedLight.specular += incidentLight.color * F * ( G * D ); - -} - -#if MAX_DIR_LIGHTS > 0 - - struct DirectionalLight { - vec3 direction; - vec3 color; - }; - - uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - - void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - - incidentLight.color = directionalLight.color; - incidentLight.direction = directionalLight.direction; - - } - -#endif - -#if MAX_POINT_LIGHTS > 0 - - struct PointLight { - vec3 position; - vec3 color; - float distance; - float decay; - }; - - uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - - void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - - vec3 lightPosition = pointLight.position; - - vec3 lVector = lightPosition - geometry.position; - incidentLight.direction = normalize( lVector ); - - incidentLight.color = pointLight.color; - incidentLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - struct SpotLight { - vec3 position; - vec3 direction; - vec3 color; - float distance; - float decay; - float angleCos; - float exponent; - }; - - uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - - void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - - vec3 lightPosition = spotLight.position; - - vec3 lVector = lightPosition - geometry.position; - incidentLight.direction = normalize( lVector ); - - float spotEffect = dot( spotLight.direction, incidentLight.direction ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - - incidentLight.color = spotLight.color; - incidentLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); - - } - -#endif - -#define MAX_AREA_LIGHTS 0 - -#if MAX_AREA_LIGHTS > 0 - - struct HemisphereLight { - vec3 position; - vec3 width; - vec3 height; - vec3 color; - float distance; - float decay; - }; - - uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; - - void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - - float widthLength = length( areaLight.width ); - float heightLength = length( areaLight.height ); - - vec3 widthDir = areaLight.width / widthLength; - vec3 heightDir = areaLight.height / heightLength; - vec3 direction = normalize( cross( widthDir, heightDir ) ); - - // project onto plane and calculate direction from center to the projection. - vec3 planePosition = projectOnPlane( viewDir, areaLight.position, direction ), // projection in plane - vec3 planeOffset = planePosition - areaLight.position; - - // calculate distance from area: - vec2 planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); - vec2 clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); - vec3 clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); - - vec3 lVector = ( clampedPlanePosition - geometry.position ); - float lLength = length( lVector ); - - incidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lLength, areaLight.distance, areaLight.decay ) * 0.01; - incidentLight.direction = lVector / lLength; - - } - -#endif - - -#if MAX_HEMI_LIGHTS > 0 - - struct HemisphereLight { - vec3 direction; - vec3 skyColor; - vec3 groundColor; - }; - - uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - - void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { - - float dotNL = dot( geometry.normal, hemiLight.direction ); - - float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - - incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - - incidentLight.direction = geometry.normal; - - } - -#endif diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl new file mode 100644 index 00000000000000..5d13a50a113ad9 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -0,0 +1,183 @@ + + +float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { + + if ( decayExponent > 0.0 ) { + + return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); + + } + + return 1.0; + +} + + +#if MAX_DIR_LIGHTS > 0 + + struct DirectionalLight { + vec3 direction; + vec3 color; + }; + + uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; + + void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + + incidentLight.color = directionalLight.color; + incidentLight.direction = directionalLight.direction; + + } + +#endif + +#if MAX_POINT_LIGHTS > 0 + + struct PointLight { + vec3 position; + vec3 color; + float distance; + float decay; + }; + + uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; + + void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + + vec3 lightPosition = pointLight.position; + + vec3 lVector = lightPosition - geometry.position; + incidentLight.direction = normalize( lVector ); + + incidentLight.color = pointLight.color; + incidentLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + struct SpotLight { + vec3 position; + vec3 direction; + vec3 color; + float distance; + float decay; + float angleCos; + float exponent; + }; + + uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; + + void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + + vec3 lightPosition = spotLight.position; + + vec3 lVector = lightPosition - geometry.position; + incidentLight.direction = normalize( lVector ); + + float spotEffect = dot( spotLight.direction, incidentLight.direction ); + spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); + + incidentLight.color = spotLight.color; + incidentLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + + } + +#endif + +#define MAX_AREA_LIGHTS 0 + +#if MAX_AREA_LIGHTS > 0 + + struct HemisphereLight { + vec3 position; + vec3 width; + vec3 height; + vec3 color; + //sampler2D image; + float distance; + float decay; + }; + + uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; + + void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight diffuseIncidentLight, out IncidentLight specularIncidentLight ) { + + float widthLength = length( areaLight.width ); + float heightLength = length( areaLight.height ); + + vec3 widthDir = areaLight.width / widthLength; + vec3 heightDir = areaLight.height / heightLength; + vec3 areaLightDirection = normalize( cross( widthDir, heightDir ) ); + + // project onto plane and calculate direction from center to the projection. + vec3 planePosition = projectOnPlane( viewDir, areaLight.position, areaLightDirection ), // projection in plane + vec3 planeOffset = planePosition - areaLight.position; + + // calculate distance from area: + vec2 planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); + vec2 clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); + vec3 clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); + + vec3 positionToLight = ( clampedPlanePosition - geometry.position ); + float lightDistance = length( positionToLight ); + + diffuseIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; + diffuseIncidentLight.direction = positionToLight / lightDistance; + + + vec3 reflectDir = reflect( geometry.viewDir, geometry.normal ); + planePosition = linePlaneIntersect( geometry.position, reflectDir, areaLight.osition[ i ], areaLightNormal[ i ] ); + float specAngle = dot( reflectDir, direction ); + + if( dot( geometry.position - areaLight.position, areaLightDirection ) >= 0.0 && specAngle > 0.0 ) { + + planeOffset = planePosition - areaLight.position; + planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); + clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); + clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); + + positionToLight = ( clampedPlanePosition - geometry.position ); + lightDistance = length( positionToLight ); + + specularIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; + specularIncidentLight.direction = positionToLight / lightDistance; + + } + else { + + specularIncidentLight.color = vec3( 0.0 ); + specularIncidentLight.direction = vec3( 1.0, 0.0, 0.0 ); + + } + + } + +#endif + + +#if MAX_HEMI_LIGHTS > 0 + + struct HemisphereLight { + vec3 direction; + vec3 skyColor; + vec3 groundColor; + }; + + uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; + + void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + + float dotNL = dot( geometry.normal, hemiLight.direction ); + + float hemiDiffuseWeight = 0.5 * dotNL + 0.5; + + incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + + incidentLight.direction = geometry.normal; + + } + +#endif diff --git a/src/renderers/shaders/ShaderChunk/math.glsl b/src/renderers/shaders/ShaderChunk/math.glsl new file mode 100644 index 00000000000000..08cb18e4b53fb4 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/math.glsl @@ -0,0 +1,56 @@ +vec3 transformDirection( in vec3 normal, in mat4 matrix ) { + + return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); + +} + +// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations +vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { + + return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); + +} + +/* +struct Plane { + vec3 normal; + float constant; +} + +vec3 Plane_distanceToPoint( const in Plane plane, in vec3 point ) { + + return dot( plane.normal, point ); + +} + +vec3 Plane_orthoPoint( const in Plane plane, in vec3 point ) { + + return plane.normal * Plane_distanceToPoint( plane, point ); + +} + +vec3 Plane_projectPoint( const in Plane plane, in vec3 point ) { + + return point - Plane_orthoPoint( plane, point ); + +}*/ + +vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { + + float distance = dot( planeNormal, point - pointOnPlane ); + + return - distance * planeNormal + point; + +} + +float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { + + return sign( dot( point - pointOnPlane, planeNormal ) ); + +} + +vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { + + return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; + +} diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 4f342cfc90f4cc..c98cbe52cb15b4 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -139,10 +139,13 @@ THREE.ShaderLib = { "#endif", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "math" ], THREE.ShaderChunk[ "uv_pars_vertex" ], THREE.ShaderChunk[ "uv2_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], THREE.ShaderChunk[ "lights_lambert_pars_vertex" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "color_pars_vertex" ], THREE.ShaderChunk[ "morphtarget_pars_vertex" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], @@ -336,6 +339,7 @@ THREE.ShaderLib = { "uniform float opacity;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "math" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "uv_pars_fragment" ], THREE.ShaderChunk[ "uv2_pars_fragment" ], @@ -347,6 +351,8 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "envmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], THREE.ShaderChunk[ "normalmap_pars_fragment" ], diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 907be1e5bc5ee5..07cfbd307b7dfc 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -107,6 +107,7 @@ "src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/begin_vertex.glsl", "src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl", + "src/renderers/shaders/ShaderChunk/bsdfs.glsl", "src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/color_fragment.glsl", "src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl", @@ -125,6 +126,7 @@ "src/renderers/shaders/ShaderChunk/fog_fragment.glsl", "src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl", + "src/renderers/shaders/ShaderChunk/lights.glsl", "src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl", @@ -142,6 +144,7 @@ "src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl", "src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl", + "src/renderers/shaders/ShaderChunk/math.glsl", "src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl", "src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl", "src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl", From fa51e8c15d5c6707929d7a1c4e76510b3987fcd4 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 12 Oct 2015 22:00:32 -0400 Subject: [PATCH 30/64] initial light probe skeleton. --- src/renderers/shaders/ShaderChunk/lights.glsl | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index 5d13a50a113ad9..f4a7ae7832974c 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -181,3 +181,27 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } #endif + + +#define MAX_LIGHT_PROBES 0 + +#if MAX_LIGHT_PROBES > 0 + + struct ProbeLight { + vec3 position; + vec3 sh[9]; + }; + + uniform LightProbes lightProbes[ MAX_LIGHT_PROBES ]; + + void getLightProbeIncidentLight( const in GeometricContext geometry, out IncidentLight incidentLight ) { + + // TODO: loop through all light probes and calculate their contributions + // based on an inverse distance weighting. + + incidentLight.color = vec3( 0.0 ); + incidentLight.direction = geometry.normal; + + } + +#endif From f96f6e4eb8518511bd72009961b85b7e640702a6 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 13 Oct 2015 14:11:28 -0400 Subject: [PATCH 31/64] add faster area light clamping. --- src/renderers/shaders/ShaderChunk/lights.glsl | 144 +++++++++--------- src/renderers/shaders/ShaderChunk/math.glsl | 24 --- 2 files changed, 74 insertions(+), 94 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index f4a7ae7832974c..fae6ca19dbcec3 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -31,6 +31,7 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec #endif + #if MAX_POINT_LIGHTS > 0 struct PointLight { @@ -56,6 +57,7 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec #endif + #if MAX_SPOT_LIGHTS > 0 struct SpotLight { @@ -87,76 +89,6 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec #endif -#define MAX_AREA_LIGHTS 0 - -#if MAX_AREA_LIGHTS > 0 - - struct HemisphereLight { - vec3 position; - vec3 width; - vec3 height; - vec3 color; - //sampler2D image; - float distance; - float decay; - }; - - uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; - - void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight diffuseIncidentLight, out IncidentLight specularIncidentLight ) { - - float widthLength = length( areaLight.width ); - float heightLength = length( areaLight.height ); - - vec3 widthDir = areaLight.width / widthLength; - vec3 heightDir = areaLight.height / heightLength; - vec3 areaLightDirection = normalize( cross( widthDir, heightDir ) ); - - // project onto plane and calculate direction from center to the projection. - vec3 planePosition = projectOnPlane( viewDir, areaLight.position, areaLightDirection ), // projection in plane - vec3 planeOffset = planePosition - areaLight.position; - - // calculate distance from area: - vec2 planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); - vec2 clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); - vec3 clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); - - vec3 positionToLight = ( clampedPlanePosition - geometry.position ); - float lightDistance = length( positionToLight ); - - diffuseIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; - diffuseIncidentLight.direction = positionToLight / lightDistance; - - - vec3 reflectDir = reflect( geometry.viewDir, geometry.normal ); - planePosition = linePlaneIntersect( geometry.position, reflectDir, areaLight.osition[ i ], areaLightNormal[ i ] ); - float specAngle = dot( reflectDir, direction ); - - if( dot( geometry.position - areaLight.position, areaLightDirection ) >= 0.0 && specAngle > 0.0 ) { - - planeOffset = planePosition - areaLight.position; - planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) ); - clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) ); - clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y ); - - positionToLight = ( clampedPlanePosition - geometry.position ); - lightDistance = length( positionToLight ); - - specularIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; - specularIncidentLight.direction = positionToLight / lightDistance; - - } - else { - - specularIncidentLight.color = vec3( 0.0 ); - specularIncidentLight.direction = vec3( 1.0, 0.0, 0.0 ); - - } - - } - -#endif - #if MAX_HEMI_LIGHTS > 0 @@ -205,3 +137,75 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } #endif + + +#define MAX_AREA_LIGHTS 0 + +#if MAX_AREA_LIGHTS > 0 + + struct HemisphereLight { + vec3 position; // NOTE: top left of area light, not the center + vec3 width; + vec3 height; + vec3 color; + //sampler2D image; + float distance; + float decay; + }; + + uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; + + vec3 clampToAreaLight( const in mat3 worldToPlaneMat, const in vec3 lightPositionPlaneCoord, const in vec3 point ) { + + // convert into "plane space" from world space + var pointPlaneCoord = worldToPlaneMat * point; + + // clamp point plane coords to positive unit in plane space. + pointPlaneCoord.xy = clamp( positionPlaneCoord.xy - lightPositionPlaneCoord.xy, 0.0, 1.0 ) + lightPositionPlaneCoord.xy; + pointPlaneCoord.z = lightPositionPlaneOffset; // project onto plane in plane coordinate space + + // convert out of "plane space" into world space + return positionPlaneCoord * worldToPlaneMat; + + } + + void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight diffuseIncidentLight, out IncidentLight specularIncidentLight ) { + + vec3 areaLightDirection = normalize( cross( widthDir, heightDir ) ); + // NOTE: width and height are purposely not normalized, this is necessary because plane space is scaled based on width/height size. + mat3 worldToPlaneMat = mat3( areaLight.width, areaLight.height, areaLightDirection ); + vec3 lightPositionPlaneCoord = worldToPlaneMat * areaLight.position; + + vec3 clampedPlanePosition = clampToAreaLight( worldToPlaneMat, lightPositionPlaneCoord, geometry.position ); + + vec3 positionToLight = ( clampedPlanePosition - geometry.position ); + float lightDistance = length( positionToLight ); + + diffuseIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; + diffuseIncidentLight.direction = positionToLight / lightDistance; + + vec3 reflectDir = reflect( geometry.viewDir, geometry.normal ); + float specAngle = dot( reflectDir, direction ); + + if( dot( geometry.position - areaLight.position, areaLightDirection ) >= 0.0 && specAngle > 0.0 ) { + + lightPositionPlaneCoord = linePlaneIntersect( geometry.position, reflectDir, areaLight.position, areaLight.normal ); + clampedPlanePosition = clampToAreaLight( worldToPlaneMat, lightPositionPlaneCoord, lightPositionPlaneCoord ); + + positionToLight = ( clampedPlanePosition - geometry.position ); + lightDistance = length( positionToLight ); + + specularIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ); + specularIncidentLight.direction = positionToLight / lightDistance; + + } + else { + + specularIncidentLight.color = vec3( 0.0 ); + specularIncidentLight.direction = vec3( 1.0, 0.0, 0.0 ); + + } + + } + +#endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/math.glsl b/src/renderers/shaders/ShaderChunk/math.glsl index 08cb18e4b53fb4..47532acc53995c 100644 --- a/src/renderers/shaders/ShaderChunk/math.glsl +++ b/src/renderers/shaders/ShaderChunk/math.glsl @@ -11,30 +11,6 @@ vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { } -/* -struct Plane { - vec3 normal; - float constant; -} - -vec3 Plane_distanceToPoint( const in Plane plane, in vec3 point ) { - - return dot( plane.normal, point ); - -} - -vec3 Plane_orthoPoint( const in Plane plane, in vec3 point ) { - - return plane.normal * Plane_distanceToPoint( plane, point ); - -} - -vec3 Plane_projectPoint( const in Plane plane, in vec3 point ) { - - return point - Plane_orthoPoint( plane, point ); - -}*/ - vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { float distance = dot( planeNormal, point - pointOnPlane ); From 3f4804977bf1e02e54c35f35db30d3cffc9dfb91 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 13 Oct 2015 21:03:42 -0400 Subject: [PATCH 32/64] expose energyConserving as a material parameter on MeshPhongMaterial. --- editor/js/Sidebar.Material.js | 17 ++++ src/materials/MeshPhongMaterial.js | 6 ++ src/renderers/shaders/ShaderChunk/bsdfs.glsl | 8 +- src/renderers/shaders/ShaderChunk/common.glsl | 22 ++--- src/renderers/shaders/ShaderChunk/lights.glsl | 96 ------------------- src/renderers/webgl/WebGLProgram.js | 4 + src/renderers/webgl/WebGLPrograms.js | 2 + 7 files changed, 43 insertions(+), 112 deletions(-) diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index c0ab695033c787..487c1a6a226935 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -163,6 +163,16 @@ Sidebar.Material = function ( editor ) { container.add( materialVertexColorsRow ); + // energy conserving + + var materialEnergyConservingRow = new UI.Panel(); + var materialEnergyConserving = new UI.Checkbox( false ).onChange( update ); + + materialEnergyConservingRow.add( new UI.Text( 'EnergyConserving' ).setWidth( '90px' ) ); + materialEnergyConservingRow.add( materialEnergyConserving ); + + container.add( materialEnergyConservingRow ); + // skinning var materialSkinningRow = new UI.Panel(); @@ -462,6 +472,12 @@ Sidebar.Material = function ( editor ) { } + if ( material.energyConserving !== undefined ) { + + material.energyConserving = materialEnergyConserving.getValue(); + + } + if ( material.map !== undefined ) { var mapEnabled = materialMapEnabled.getValue() === true; @@ -687,6 +703,7 @@ Sidebar.Material = function ( editor ) { 'vertexShader': materialProgramRow, 'vertexColors': materialVertexColorsRow, 'skinning': materialSkinningRow, + 'energyConserving': materialEnergyConservingRow, 'map': materialMapRow, 'alphaMap': materialAlphaMapRow, 'bumpMap': materialBumpMapRow, diff --git a/src/materials/MeshPhongMaterial.js b/src/materials/MeshPhongMaterial.js index 2940d3a16484ed..cf926c8e8a088e 100644 --- a/src/materials/MeshPhongMaterial.js +++ b/src/materials/MeshPhongMaterial.js @@ -11,6 +11,8 @@ * * map: new THREE.Texture( ), * + * energyConverving: false + * * lightMap: new THREE.Texture( ), * lightMapIntensity: * @@ -71,6 +73,8 @@ THREE.MeshPhongMaterial = function ( parameters ) { this.map = null; + this.energyConserving = false; + this.lightMap = null; this.lightMapIntensity = 1.0; @@ -133,6 +137,8 @@ THREE.MeshPhongMaterial.prototype.copy = function ( source ) { this.map = source.map; + this.energyConserving = source.energyConserving; + this.lightMap = source.lightMap; this.lightMapIntensity = source.lightMapIntensity; diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index ad949603ea8c04..73e1eaf4822b5c 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -62,8 +62,8 @@ vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { float G_SmithSchlick( float roughness2, float dotNL, float dotNV ) { - float termL = ( dotNL + sqrt( roughness2 + ( 1.0 - roughness2 ) * square( dotNL ) ) ); - float termV = ( dotNV + sqrt( roughness2 + ( 1.0 - roughness2 ) * square( dotNV ) ) ); + float termL = ( dotNL + sqrt( roughness2 + ( 1.0 - roughness2 ) * dotNL * dotNL ) ); + float termV = ( dotNV + sqrt( roughness2 + ( 1.0 - roughness2 ) * dotNV * dotNV ) ); return 1.0 / ( abs( termL * termV ) + 0.0000001 ); @@ -72,8 +72,8 @@ float G_SmithSchlick( float roughness2, float dotNL, float dotNV ) { float D_GGX( float roughness2, float dotNH ) { // should 1/PI be in this distribution? - float denom = square( dotNH ) * ( roughness2 - 1.0 ) + 1.0; - return roughness2 / ( PI * square( denom ) + 0.0000001 ); + float denom = dotNH * dotNH * ( roughness2 - 1.0 ) + 1.0; + return roughness2 / ( PI * denom * denom + 0.0000001 ); } diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 4acaa09172404f..e9f7131258b1c8 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -1,15 +1,13 @@ -const float PI = 3.14159; -const float PI2 = 6.28318; -const float RECIPROCAL_PI = 0.31830988618; -const float RECIPROCAL_PI2 = 0.15915494; -const float LOG2 = 1.442695; -const float EPSILON = 1e-6; - -float square( const in float a ) { return a*a; } -float saturate( const in float a ) { return clamp( a, 0.0, 1.0 ); } -vec3 saturate( const in vec3 a ) { return clamp( a, 0.0, 1.0 ); } -vec3 whiteCompliment( const in vec3 color ) { return 1.0 - saturate( color ); } -float luminance( const in vec3 color ) { return dot( color, vec3( 0.2125, 0.7154, 0.0721 ) ); } +#define PI 3.14159 +#define PI2 6.28318 +#define RECIPROCAL_PI 0.31830988618 +#define RECIPROCAL_PI2 0.15915494 +#define LOG2 1.442695 +#define EPSILON 1e-6 + +#define saturate(a) clamp( a, 0.0, 1.0 ) +#define whiteCompliment(a) ( 1.0 - saturate( a ) ) + float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index fae6ca19dbcec3..471f7d59eace15 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -113,99 +113,3 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } #endif - - -#define MAX_LIGHT_PROBES 0 - -#if MAX_LIGHT_PROBES > 0 - - struct ProbeLight { - vec3 position; - vec3 sh[9]; - }; - - uniform LightProbes lightProbes[ MAX_LIGHT_PROBES ]; - - void getLightProbeIncidentLight( const in GeometricContext geometry, out IncidentLight incidentLight ) { - - // TODO: loop through all light probes and calculate their contributions - // based on an inverse distance weighting. - - incidentLight.color = vec3( 0.0 ); - incidentLight.direction = geometry.normal; - - } - -#endif - - -#define MAX_AREA_LIGHTS 0 - -#if MAX_AREA_LIGHTS > 0 - - struct HemisphereLight { - vec3 position; // NOTE: top left of area light, not the center - vec3 width; - vec3 height; - vec3 color; - //sampler2D image; - float distance; - float decay; - }; - - uniform AreaLight areaLights[ MAX_AREA_LIGHTS ]; - - vec3 clampToAreaLight( const in mat3 worldToPlaneMat, const in vec3 lightPositionPlaneCoord, const in vec3 point ) { - - // convert into "plane space" from world space - var pointPlaneCoord = worldToPlaneMat * point; - - // clamp point plane coords to positive unit in plane space. - pointPlaneCoord.xy = clamp( positionPlaneCoord.xy - lightPositionPlaneCoord.xy, 0.0, 1.0 ) + lightPositionPlaneCoord.xy; - pointPlaneCoord.z = lightPositionPlaneOffset; // project onto plane in plane coordinate space - - // convert out of "plane space" into world space - return positionPlaneCoord * worldToPlaneMat; - - } - - void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight diffuseIncidentLight, out IncidentLight specularIncidentLight ) { - - vec3 areaLightDirection = normalize( cross( widthDir, heightDir ) ); - // NOTE: width and height are purposely not normalized, this is necessary because plane space is scaled based on width/height size. - mat3 worldToPlaneMat = mat3( areaLight.width, areaLight.height, areaLightDirection ); - vec3 lightPositionPlaneCoord = worldToPlaneMat * areaLight.position; - - vec3 clampedPlanePosition = clampToAreaLight( worldToPlaneMat, lightPositionPlaneCoord, geometry.position ); - - vec3 positionToLight = ( clampedPlanePosition - geometry.position ); - float lightDistance = length( positionToLight ); - - diffuseIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ) * 0.01; - diffuseIncidentLight.direction = positionToLight / lightDistance; - - vec3 reflectDir = reflect( geometry.viewDir, geometry.normal ); - float specAngle = dot( reflectDir, direction ); - - if( dot( geometry.position - areaLight.position, areaLightDirection ) >= 0.0 && specAngle > 0.0 ) { - - lightPositionPlaneCoord = linePlaneIntersect( geometry.position, reflectDir, areaLight.position, areaLight.normal ); - clampedPlanePosition = clampToAreaLight( worldToPlaneMat, lightPositionPlaneCoord, lightPositionPlaneCoord ); - - positionToLight = ( clampedPlanePosition - geometry.position ); - lightDistance = length( positionToLight ); - - specularIncidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lightDistance, areaLight.distance, areaLight.decay ); - specularIncidentLight.direction = positionToLight / lightDistance; - - } - else { - - specularIncidentLight.color = vec3( 0.0 ); - specularIncidentLight.direction = vec3( 1.0, 0.0, 0.0 ); - - } - - } - -#endif \ No newline at end of file diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index f134e58d78e8d1..7c173fe39db4af 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -249,6 +249,10 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.energyConserving ? '#define ENERGY_PRESERVING_MONOCHROME' : '', + + + parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 82e819d47dc1da..67d7a555859f9c 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -149,6 +149,8 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { specularMap: !! material.specularMap, alphaMap: !! material.alphaMap, + energyConserving: !! material.energyConserving, + combine: material.combine, vertexColors: material.vertexColors, From bbc81cdb67d5091800514421d53c3e937c48bf71 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 12:24:55 -0400 Subject: [PATCH 33/64] start refactoring ShaderSkin.js --- editor/js/Sidebar.Material.js | 6 +++ examples/js/ShaderSkin.js | 40 +++++-------------- src/renderers/shaders/ShaderChunk/common.glsl | 34 +++++++++++++++- src/renderers/shaders/ShaderChunk/math.glsl | 32 --------------- src/renderers/shaders/ShaderLib.js | 4 +- 5 files changed, 49 insertions(+), 67 deletions(-) diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index 487c1a6a226935..451dec391a84fd 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -787,6 +787,12 @@ Sidebar.Material = function ( editor ) { } + if ( material.energyConserving !== undefined ) { + + materialEnergyConserving.setValue( material.energyConserving ); + + } + if ( material.map !== undefined ) { materialMapEnabled.setValue( material.map !== null ); diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 122c964154c60c..678e2f3ca58cf5 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -82,33 +82,11 @@ THREE.ShaderSkin = { "uniform vec3 ambientLightColor;", - "#if MAX_DIR_LIGHTS > 0", - - "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", - - "#endif", - "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], @@ -197,9 +175,9 @@ THREE.ShaderSkin = { "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - "vec3 lVector = pointLightPosition[ i ] + vViewPosition.xyz;", + "vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "lVector = normalize( lVector );", @@ -209,8 +187,8 @@ THREE.ShaderSkin = { "float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );", - "totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );", - "totalSpecularLight += pointLightColor[ i ] * specular * ( pointSpecularWeight * specularStrength * attenuation );", + "totalDiffuseLight += pointLight[ i ].color * ( pointDiffuseWeight * attenuation );", + "totalSpecularLight += pointLight[ i ].color * specular * ( pointSpecularWeight * specularStrength * attenuation );", "}", @@ -222,7 +200,7 @@ THREE.ShaderSkin = { "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - "vec3 dirVector = directionalLightDirection[ i ];", + "vec3 dirVector = directionalLight[ i ].direction;", "float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );", "float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );", @@ -230,8 +208,8 @@ THREE.ShaderSkin = { "float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );", - "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", - "totalSpecularLight += directionalLightColor[ i ] * ( dirSpecularWeight * specularStrength );", + "totalDiffuseLight += directionalLight[ i ].color * dirDiffuseWeight;", + "totalSpecularLight += directionalLight[ i ].color * ( dirSpecularWeight * specularStrength );", "}", diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index e9f7131258b1c8..d5dd2c5adf9a21 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -8,8 +8,40 @@ #define saturate(a) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) -float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } +float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } +vec3 transformDirection( in vec3 normal, in mat4 matrix ) { + + return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); + +} + +// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations +vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { + + return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); + +} + +vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { + + float distance = dot( planeNormal, point - pointOnPlane ); + + return - distance * planeNormal + point; + +} + +float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { + + return sign( dot( point - pointOnPlane, planeNormal ) ); + +} + +vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { + + return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; + +} vec3 inputToLinear( in vec3 a ) { diff --git a/src/renderers/shaders/ShaderChunk/math.glsl b/src/renderers/shaders/ShaderChunk/math.glsl index 47532acc53995c..e69de29bb2d1d6 100644 --- a/src/renderers/shaders/ShaderChunk/math.glsl +++ b/src/renderers/shaders/ShaderChunk/math.glsl @@ -1,32 +0,0 @@ -vec3 transformDirection( in vec3 normal, in mat4 matrix ) { - - return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); - -} - -// http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations -vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { - - return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); - -} - -vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { - - float distance = dot( planeNormal, point - pointOnPlane ); - - return - distance * planeNormal + point; - -} - -float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { - - return sign( dot( point - pointOnPlane, planeNormal ) ); - -} - -vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { - - return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; - -} diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index c98cbe52cb15b4..148256e9c18de0 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -139,7 +139,6 @@ THREE.ShaderLib = { "#endif", THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "math" ], THREE.ShaderChunk[ "uv_pars_vertex" ], THREE.ShaderChunk[ "uv2_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], @@ -338,8 +337,7 @@ THREE.ShaderLib = { "uniform float shininess;", "uniform float opacity;", - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "math" ], + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "uv_pars_fragment" ], THREE.ShaderChunk[ "uv2_pars_fragment" ], From 3c9e00fe0d426daf31d1b2ba766e395a45e14ed1 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 12:59:49 -0400 Subject: [PATCH 34/64] get skin, tone mapping and terrain examples working with new BSDF and light structures. --- examples/js/ShaderSkin.js | 61 ++++++------------- examples/js/ShaderTerrain.js | 44 ++++--------- examples/webgl_shaders_tonemapping.html | 9 ++- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 18 ------ src/renderers/shaders/ShaderChunk/common.glsl | 18 ++++++ src/renderers/shaders/ShaderChunk/lights.glsl | 34 +++++------ .../ShaderChunk/lights_lambert_vertex.glsl | 36 ++++++----- .../ShaderChunk/lights_phong_fragment.glsl | 40 ++++++------ 8 files changed, 113 insertions(+), 147 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 678e2f3ca58cf5..91af6710f5b75e 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -200,7 +200,7 @@ THREE.ShaderSkin = { "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - "vec3 dirVector = directionalLight[ i ].direction;", + "vec3 dirVector = directionalLights[ i ].direction;", "float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );", "float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );", @@ -208,8 +208,8 @@ THREE.ShaderSkin = { "float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );", - "totalDiffuseLight += directionalLight[ i ].color * dirDiffuseWeight;", - "totalSpecularLight += directionalLight[ i ].color * ( dirSpecularWeight * specularStrength );", + "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", + "totalSpecularLight += directionalLights[ i ].color * ( dirSpecularWeight * specularStrength );", "}", @@ -369,19 +369,10 @@ THREE.ShaderSkin = { "uniform vec3 ambientLightColor;", - "#if MAX_DIR_LIGHTS > 0", - "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];", - "#endif", - "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "fog_pars_fragment" ], "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {", @@ -464,11 +455,12 @@ THREE.ShaderSkin = { "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - "vec3 pointVector = normalize( vPointLight[ i ].xyz );", - "float attenuation = vPointLight[ i ].w;", - + "vec3 pointVector = normalize( pointLights[ i ].direction );", + "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", + "totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );", "if ( passID == 1 ) {", @@ -489,17 +481,18 @@ THREE.ShaderSkin = { "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - "vec3 dirVector = directionalLightDirection[ i ];", + "vec3 dirVector = directionalLights[ i ].direction;", "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", + + "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", "if ( passID == 1 ) {", "float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );", - "totalSpecularLight += directionalLightColor[ i ] * mSpecular.xyz * dirSpecularWeight;", + "totalSpecularLight += directionalLights[ i ].color * mSpecular.xyz * dirSpecularWeight;", "}", @@ -580,19 +573,10 @@ THREE.ShaderSkin = { "varying vec3 vNormal;", "varying vec2 vUv;", - "#if MAX_POINT_LIGHTS > 0", - - "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", - - "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];", - - "#endif", - "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "lights" ], "void main() {", @@ -612,9 +596,9 @@ THREE.ShaderSkin = { "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", - "vec3 lVector = pointLightPosition[ i ] - vViewPosition;", + "vec3 lVector = pointLights[ i ].position - vViewPosition;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "lVector = normalize( lVector );", @@ -648,19 +632,10 @@ THREE.ShaderSkin = { "varying vec3 vNormal;", "varying vec2 vUv;", - "#if MAX_POINT_LIGHTS > 0", - - "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", - - "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];", - - "#endif", - "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "lights" ], "void main() {", @@ -680,9 +655,9 @@ THREE.ShaderSkin = { "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", - "vec3 lVector = pointLightPosition[ i ] - vViewPosition;", + "vec3 lVector = pointLights[ i ].position - vViewPosition;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "lVector = normalize( lVector );", diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index 97da9304371a3e..de24595efb69ff 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -86,33 +86,11 @@ THREE.ShaderTerrain = { "uniform vec3 ambientLightColor;", - "#if MAX_DIR_LIGHTS > 0", - - "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDecay[ MAX_POINT_LIGHTS ];", - - "#endif", - "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], @@ -168,9 +146,9 @@ THREE.ShaderTerrain = { "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - "vec3 lVector = pointLightPosition[ i ] + vViewPosition.xyz;", + "vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;", - "float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "lVector = normalize( lVector );", @@ -181,8 +159,8 @@ THREE.ShaderTerrain = { "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );", - "totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;", - "totalSpecularLight += attenuation * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;", + "totalDiffuseLight += attenuation * pointLights[ i ].color * pointDiffuseWeight;", + "totalSpecularLight += attenuation * pointLights[ i ].color * specular * pointSpecularWeight * pointDiffuseWeight;", "}", @@ -197,7 +175,7 @@ THREE.ShaderTerrain = { "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - "vec3 dirVector = directionalLightDirection[ i ];", + "vec3 dirVector = directionalLights[ i ].direction;", "vec3 dirHalfVector = normalize( dirVector + viewPosition );", "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", @@ -205,8 +183,8 @@ THREE.ShaderTerrain = { "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );", - "totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;", - "totalSpecularLight += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;", + "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", + "totalSpecularLight += directionalLights[ i ].color * specular * dirSpecularWeight * dirDiffuseWeight;", "}", @@ -228,7 +206,7 @@ THREE.ShaderTerrain = { "float dotProduct = dot( normal, lVector );", "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - "totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", + "totalDiffuseLight += mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight );", // specular (sky light) @@ -246,7 +224,7 @@ THREE.ShaderTerrain = { "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", - "totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", + "totalSpecularLight += specular * mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", "}", diff --git a/examples/webgl_shaders_tonemapping.html b/examples/webgl_shaders_tonemapping.html index 2b861bc74a584d..5fa3335d01f23b 100644 --- a/examples/webgl_shaders_tonemapping.html +++ b/examples/webgl_shaders_tonemapping.html @@ -37,7 +37,7 @@
Adaptive Tone Mapping
- + @@ -158,6 +158,9 @@ fragmentShader: [ + THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], "void main() {", @@ -169,12 +172,12 @@ "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {", - "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", + "vec4 lDirection = viewMatrix * vec4( directionalLights[i].direction, 0.0 );", "vec3 dirVector = normalize( lDirection.xyz );", "float dotProduct = dot( viewPosition, dirVector );", "dotProduct = 1.0 * max( dotProduct, 0.0 ) + (1.0 - max( -dot( normal, dirVector ), 0.0 ));", "dotProduct *= dotProduct;", - "dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLightColor[ i ];", + "dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLights[i].color;", "}", "#endif", diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 73e1eaf4822b5c..f0b5e582f66984 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -1,23 +1,5 @@ //#define ENERGY_PRESERVING_MONOCHROME - -struct IncidentLight { - vec3 color; - vec3 direction; -}; - -struct ReflectedLight { - vec3 specular; - vec3 diffuse; -}; - -struct GeometricContext { - vec3 position; - vec3 normal; - vec3 viewDir; -}; - - void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index d5dd2c5adf9a21..642f55ce526d90 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -10,6 +10,24 @@ float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } + +struct IncidentLight { + vec3 color; + vec3 direction; +}; + +struct ReflectedLight { + vec3 specular; + vec3 diffuse; +}; + +struct GeometricContext { + vec3 position; + vec3 normal; + vec3 viewDir; +}; + + vec3 transformDirection( in vec3 normal, in mat4 matrix ) { return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index 471f7d59eace15..47cb5c9c20bc2b 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -22,10 +22,10 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + void getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { - incidentLight.color = directionalLight.color; - incidentLight.direction = directionalLight.direction; + directLight.color = directionalLight.color; + directLight.direction = directionalLight.direction; } @@ -43,15 +43,15 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + void getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { vec3 lightPosition = pointLight.position; vec3 lVector = lightPosition - geometry.position; - incidentLight.direction = normalize( lVector ); + directLight.direction = normalize( lVector ); - incidentLight.color = pointLight.color; - incidentLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + directLight.color = pointLight.color; + directLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); } @@ -72,18 +72,18 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + void getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { vec3 lightPosition = spotLight.position; vec3 lVector = lightPosition - geometry.position; - incidentLight.direction = normalize( lVector ); + directLight.direction = normalize( lVector ); - float spotEffect = dot( spotLight.direction, incidentLight.direction ); + float spotEffect = dot( spotLight.direction, directLight.direction ); spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) ); - incidentLight.color = spotLight.color; - incidentLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + directLight.color = spotLight.color; + directLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); } @@ -100,15 +100,13 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { + void getHemisphereIndirectLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight indirectLight ) { float dotNL = dot( geometry.normal, hemiLight.direction ); - float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - - incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - - incidentLight.direction = geometry.normal; + + indirectLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + indirectLight.direction = geometry.normal; } diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index eb82b52ef5019d..4e6e1c554b3a5d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -1,7 +1,5 @@ vec3 diffuse = vec3( 1.0 ); -IncidentLight incidentLight; - GeometricContext geometry = GeometricContext( mvPosition.xyz, normalize( transformedNormal ), normalize( -mvPosition.xyz ) ); GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.normal, geometry.viewDir ); @@ -12,13 +10,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], geometry, incidentLight ); + IncidentLight directLight; + + getPointDirectLight( pointLights[ i ], geometry, directLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); + BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -30,13 +30,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], geometry, incidentLight ); + IncidentLight directLight; + + getSpotDirectLight( spotLights[ i ], geometry, directLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); + BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -48,13 +50,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], geometry, incidentLight ); + IncidentLight directLight; - BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); + getDirectionalDirectLight( directionalLights[ i ], geometry, directLight ); + + BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); + BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); #endif @@ -66,15 +70,17 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereLightIndirect( hemisphereLights[ i ], geometry, incidentLight ); + IncidentLight indirectLight; + + getHemisphereIndirectLight( hemisphereLights[ i ], geometry, indirectLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, frontReflectedLight ); + BRDF_Lambert( indirectLight, geometry, diffuse, frontReflectedLight ); #ifdef DOUBLE_SIDED - getHemisphereIncidentLight( hemisphereLights[ i ], backGeometry, incidentLight ); + getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry, indirectLight ); - BRDF_Lambert( incidentLight, backGeometry, diffuse, backReflectedLight ); + BRDF_Lambert( indirectLight, backGeometry, diffuse, backReflectedLight ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 4c042f66cb506d..a250d2ee79241f 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -16,8 +16,6 @@ vec3 diffuse = diffuseColor.rgb; #endif -IncidentLight incidentLight; - GeometricContext geometry = GeometricContext( -vViewPosition, normal, normalize(vViewPosition ) ); ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); @@ -27,12 +25,14 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - getPointIncidentLight( pointLights[ i ], geometry, incidentLight ); + IncidentLight directLight; + + getPointDirectLight( pointLights[ i ], geometry, directLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); } @@ -42,12 +42,14 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - getSpotIncidentLight( spotLights[ i ], geometry, incidentLight ); + IncidentLight directLight; + + getSpotDirectLight( spotLights[ i ], geometry, directLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); - BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); + BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); } @@ -57,12 +59,14 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - getDirIncidentLight( directionalLights[ i ], geometry, incidentLight ); + IncidentLight directLight; - BRDF_Lambert( incidentLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, directReflectedLight ); + getDirectionalDirectLight( directionalLights[ i ], geometry, directLight ); - BRDF_BlinnPhong( incidentLight, geometry, specular, shininess, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); + + BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); } @@ -72,10 +76,12 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - getHemisphereIncidentLight( hemisphereLights[ i ], geometry, incidentLight ); + IncidentLight indirectLight; + + getHemisphereIndirectLight( hemisphereLights[ i ], geometry, indirectLight ); - BRDF_Lambert( incidentLight, geometry, diffuse, indirectReflectedLight ); - //BRDF_OrenNayar( incidentLight, geometry, diffuse, 0.5, indirectReflectedLight ); + BRDF_Lambert( indirectLight, geometry, diffuse, indirectReflectedLight ); + //BRDF_OrenNayar( indirectLight, geometry, diffuse, 0.5, indirectReflectedLight ); } From 0287cab597c854f48b859cbf7eeb5f8b995d6314 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 13:36:09 -0400 Subject: [PATCH 35/64] remove unused code from broken ShaderSkin.js --- examples/js/ShaderSkin.js | 43 ++------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 3693167869c174..b5576707273ddf 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -455,12 +455,11 @@ THREE.ShaderSkin = { "#if MAX_POINT_LIGHTS > 0", "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - + "vec3 pointVector = normalize( pointLights[ i ].direction );", + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", - - "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", "totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );", @@ -577,7 +576,6 @@ THREE.ShaderSkin = { "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "lights" ], "void main() {", @@ -591,24 +589,6 @@ THREE.ShaderSkin = { "vUv = uv;", - // point lights - - "#if MAX_POINT_LIGHTS > 0", - - "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", - - "vec3 lVector = pointLights[ i ].position - vViewPosition;", - - "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", - - "lVector = normalize( lVector );", - - "vPointLight[ i ] = vec4( lVector, attenuation );", - - "}", - - "#endif", - // displacement mapping "#ifdef VERTEX_TEXTURES", @@ -636,7 +616,6 @@ THREE.ShaderSkin = { "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "lights" ], "void main() {", @@ -650,24 +629,6 @@ THREE.ShaderSkin = { "vUv = uv;", - // point lights - - "#if MAX_POINT_LIGHTS > 0", - - "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", - - "vec3 lVector = pointLights[ i ].position - vViewPosition;", - - "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", - - "lVector = normalize( lVector );", - - "vPointLight[ i ] = vec4( lVector, attenuation );", - - "}", - - "#endif", - "gl_Position = vec4( uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0 );", "}" From c45b7cf94d202a4c29ddfbd552ec94a8e52d602d Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:00:33 -0400 Subject: [PATCH 36/64] shadowMask shouldn't be applied to indirect. --- src/renderers/shaders/ShaderLib.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index e4262070102d85..c721a0e821e6ae 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -387,8 +387,6 @@ THREE.ShaderLib = { "directReflectedLight.diffuse *= shadowMask;", "directReflectedLight.specular *= shadowMask;", - "indirectReflectedLight.diffuse *= shadowMask;", - "indirectReflectedLight.specular *= shadowMask;", "#ifdef METAL", From 8c8f538f3086d5f67a9221f05e806d3e2d7d9092 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:12:49 -0400 Subject: [PATCH 37/64] restore erroneously removed modifications by @WestLangley. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 53 ++++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 4ea951b0e031d1..9938d2f8fb678b 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -55,20 +55,36 @@ vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { } -float G_SmithSchlick( float roughness2, float dotNL, float dotNV ) { +// Microfacet Models for Refraction through Rough Surfaces - equation (34) +// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html +// alpha is "roughness squared" in Disney’s reparameterization +float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) { - float termL = ( dotNL + sqrt( roughness2 + ( 1.0 - roughness2 ) * dotNL * dotNL ) ); - float termV = ( dotNV + sqrt( roughness2 + ( 1.0 - roughness2 ) * dotNV * dotNV ) ); - - return 1.0 / ( abs( termL * termV ) + 0.0000001 ); + // geometry term = G(l) . G(v) / 4(n . l)(n. v) + + float a2 = alpha * alpha; + + float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 ); + + float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 ); + + return 1.0 / ( gl * gv ); } -float D_GGX( float roughness2, float dotNH ) { - // should 1/PI be in this distribution? - float denom = dotNH * dotNH * ( roughness2 - 1.0 ) + 1.0; - return roughness2 / ( PI * denom * denom + 0.0000001 ); +// Microfacet Models for Refraction through Rough Surfaces - equation (33) +// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html +// alpha is "roughness squared" in Disney’s reparameterization +float D_GGX( in float alpha, in float dotNH ) { + + // factor of 1/PI in distribution term omitted + + float a2 = alpha * alpha; + + float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 + + return a2 / ( denom * denom ); } @@ -115,3 +131,22 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo reflectedLight.specular += incidentLight.color * F * ( G * D ); } + +// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile +vec3 envBRDFApprox( vec3 specularColor, float roughness, in vec3 normal, in vec3 viewDir ) { + + float dotNV = saturate( dot( normal, viewDir ) ); + + const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + + const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); + + vec4 r = roughness * c0 + c1; + + float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + + vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; + + return specularColor * AB.x + AB.y; + +} \ No newline at end of file From c290352133019105f3be6232db0ecf1f16f591de Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:22:34 -0400 Subject: [PATCH 38/64] simplify light factories. --- src/renderers/shaders/ShaderChunk/lights.glsl | 20 +++++++++++++++---- .../ShaderChunk/lights_lambert_vertex.glsl | 16 ++++----------- .../ShaderChunk/lights_phong_fragment.glsl | 16 ++++----------- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index 3e93fa0089153a..e853247a489b50 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -10,11 +10,14 @@ uniform vec3 ambientLightColor; uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ]; - void getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { + IncidentLight getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry ) { + + IncidentLight directLight; directLight.color = directionalLight.color; directLight.direction = directionalLight.direction; + return directLight; } #endif @@ -31,8 +34,10 @@ uniform vec3 ambientLightColor; uniform PointLight pointLights[ MAX_POINT_LIGHTS ]; - void getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { + IncidentLight getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry ) { + IncidentLight directLight; + vec3 lightPosition = pointLight.position; vec3 lVector = lightPosition - geometry.position; @@ -41,6 +46,7 @@ uniform vec3 ambientLightColor; directLight.color = pointLight.color; directLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); + return directLight; } #endif @@ -60,8 +66,10 @@ uniform vec3 ambientLightColor; uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ]; - void getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { + IncidentLight getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry ) { + IncidentLight directLight; + vec3 lightPosition = spotLight.position; vec3 lVector = lightPosition - geometry.position; @@ -73,6 +81,7 @@ uniform vec3 ambientLightColor; directLight.color = spotLight.color; directLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) ); + return directLight; } #endif @@ -88,14 +97,17 @@ uniform vec3 ambientLightColor; uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - void getHemisphereIndirectLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight indirectLight ) { + IncidentLight getHemisphereIndirectLight( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { + IncidentLight directLight; + float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; indirectLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); indirectLight.direction = geometry.normal; + return indirectLight; } #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 078b37c8722145..ae034759711227 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -10,9 +10,7 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - IncidentLight directLight; - - getPointDirectLight( pointLights[ i ], geometry, directLight ); + IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); @@ -30,9 +28,7 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - IncidentLight directLight; - - getSpotDirectLight( spotLights[ i ], geometry, directLight ); + IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); @@ -50,9 +46,7 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - IncidentLight directLight; - - getDirectionalDirectLight( directionalLights[ i ], geometry, directLight ); + IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); @@ -70,9 +64,7 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - IncidentLight indirectLight; - - getHemisphereIndirectLight( hemisphereLights[ i ], geometry, indirectLight ); + IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); BRDF_Lambert( indirectLight, geometry, diffuse, frontReflectedLight ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index 4d50063cd0046d..d0be811eb26cef 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -25,9 +25,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - IncidentLight directLight; - - getPointDirectLight( pointLights[ i ], geometry, directLight ); + IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); @@ -42,9 +40,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - IncidentLight directLight; - - getSpotDirectLight( spotLights[ i ], geometry, directLight ); + IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); @@ -59,9 +55,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - IncidentLight directLight; - - getDirectionalDirectLight( directionalLights[ i ], geometry, directLight ); + IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); @@ -76,9 +70,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - IncidentLight indirectLight; - - getHemisphereIndirectLight( hemisphereLights[ i ], geometry, indirectLight ); + IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); BRDF_Lambert( indirectLight, geometry, diffuse, indirectReflectedLight ); //BRDF_OrenNayar( indirectLight, geometry, diffuse, 0.5, indirectReflectedLight ); From e40d3f7cfd49555b6c25014ee5c05e8ee669dc5b Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:26:01 -0400 Subject: [PATCH 39/64] remove no longer used hemilight_fragment.glsl --- src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl | 0 src/renderers/shaders/ShaderLib.js | 2 -- utils/build/includes/common.json | 1 - 3 files changed, 3 deletions(-) delete mode 100644 src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl diff --git a/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl b/src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index c721a0e821e6ae..42daff96651975 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -378,7 +378,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "specularmap_fragment" ], THREE.ShaderChunk[ "normal_phong_fragment" ], THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "hemilight_fragment" ], THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "emissivemap_fragment" ], @@ -552,7 +551,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "metalnessmap_fragment" ], THREE.ShaderChunk[ "normal_phong_fragment" ], // use phong chunk for now THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "hemilight_fragment" ], THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "emissivemap_fragment" ], diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 39939c10f759c7..9e2b3bc8f430c7 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -130,7 +130,6 @@ "src/renderers/shaders/ShaderChunk/envmap_vertex.glsl", "src/renderers/shaders/ShaderChunk/fog_fragment.glsl", "src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", - "src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl", "src/renderers/shaders/ShaderChunk/lights.glsl", "src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl", From a101882d5b6c22b926a87126f15880f2915095c3 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:34:12 -0400 Subject: [PATCH 40/64] minor bugs. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 2 +- src/renderers/shaders/ShaderChunk/lights.glsl | 2 +- src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl | 2 +- src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 9938d2f8fb678b..86c6b77bef3bc9 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -58,7 +58,7 @@ vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { // Microfacet Models for Refraction through Rough Surfaces - equation (34) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html // alpha is "roughness squared" in Disney’s reparameterization -float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) { +float G_SmithSchlick( in float alpha, in float dotNL, in float dotNV ) { // geometry term = G(l) . G(v) / 4(n . l)(n. v) diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights.glsl index e853247a489b50..f589e4b40705bc 100644 --- a/src/renderers/shaders/ShaderChunk/lights.glsl +++ b/src/renderers/shaders/ShaderChunk/lights.glsl @@ -99,7 +99,7 @@ uniform vec3 ambientLightColor; IncidentLight getHemisphereIndirectLight( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { - IncidentLight directLight; + IncidentLight indirectLight; float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index ae034759711227..013cfd17299c4d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -70,7 +70,7 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); #ifdef DOUBLE_SIDED - getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry, indirectLight ); + indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ); BRDF_Lambert( indirectLight, backGeometry, diffuse, backReflectedLight ); diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index d0be811eb26cef..c3f89bfac2a602 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -16,7 +16,7 @@ vec3 diffuse = diffuseColor.rgb; #endif -GeometricContext geometry = GeometricContext( -vViewPosition, normal, normalize(vViewPosition ) ); +GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); From 95534e3cfe9f8e77f7fbaa1b980989dc410a29bb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:38:40 -0400 Subject: [PATCH 41/64] refactor physical materials to use new BRDF+Light structs --- .../ShaderChunk/lights_physical_fragment.glsl | 81 +++++-------------- 1 file changed, 21 insertions(+), 60 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl index 5275a780c3e471..20e4092c7284ed 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl @@ -1,8 +1,3 @@ -vec3 viewDir = normalize( vViewPosition ); - -vec3 totalDiffuseLight = vec3( 0.0 ); -vec3 totalSpecularLight = vec3( 0.0 ); - // roughness linear remapping @@ -16,32 +11,22 @@ vec3 specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); diffuseColor.rgb *= ( 1.0 - metalnessFactor ); -#if MAX_POINT_LIGHTS > 0 - - for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - - vec3 lightColor = pointLightColor[ i ]; - - vec3 lightPosition = pointLightPosition[ i ]; - vec3 lVector = lightPosition + vViewPosition.xyz; - vec3 lightDir = normalize( lVector ); - // attenuation +GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); - float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); +ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - // diffuse - float cosineTerm = saturate( dot( normal, lightDir ) ); - - totalDiffuseLight += lightColor * attenuation * cosineTerm; +#if MAX_POINT_LIGHTS > 0 - // specular + for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir ); + IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm; + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); } @@ -51,37 +36,11 @@ diffuseColor.rgb *= ( 1.0 - metalnessFactor ); for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - vec3 lightColor = spotLightColor[ i ]; - - vec3 lightPosition = spotLightPosition[ i ]; - vec3 lVector = lightPosition + vViewPosition.xyz; - vec3 lightDir = normalize( lVector ); - - float spotEffect = dot( spotLightDirection[ i ], lightDir ); - - if ( spotEffect > spotLightAngleCos[ i ] ) { + IncidentLight directLight = getSpotDirectLight( pointLights[ i ], geometry ); - spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) ); + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); - // attenuation - - float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); - - attenuation *= spotEffect; - - // diffuse - - float cosineTerm = saturate( dot( normal, lightDir ) ); - - totalDiffuseLight += lightColor * attenuation * cosineTerm; - - // specular - - vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir ); - - totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm; - - } + BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); } @@ -91,21 +50,23 @@ diffuseColor.rgb *= ( 1.0 - metalnessFactor ); for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - vec3 lightColor = directionalLightColor[ i ]; + IncidentLight directLight = getDirectionalDirectLight( pointLights[ i ], geometry ); - vec3 lightDir = directionalLightDirection[ i ]; + BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); - // diffuse + BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); - float cosineTerm = saturate( dot( normal, lightDir ) ); + } + +#endif - totalDiffuseLight += lightColor * cosineTerm; +#if MAX_HEMI_LIGHTS > 0 - // specular + for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir ); + IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm; + BRDF_Lambert( indirectLight, geometry, diffuse, indirectReflectedLight ); } From 08fe98963762ed4feaf0309c1b06792cc90d8cfb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 14:41:57 -0400 Subject: [PATCH 42/64] fix bug in physical material conversion to structs, add energy preservation option. --- .../ShaderChunk/lights_physical_fragment.glsl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl index 20e4092c7284ed..d8c9541addbdde 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl @@ -11,6 +11,15 @@ vec3 specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); diffuseColor.rgb *= ( 1.0 - metalnessFactor ); +#if defined( ENERGY_PRESERVING_RGB ) + + diffuseColor *= whiteCompliment( specularColor ); + +#elif defined( ENERGY_PRESERVING_MONOCHROME ) + + diffuseColor *= whiteCompliment( luminance( specularColor ) ); + +#endif GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); @@ -24,7 +33,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); @@ -38,7 +47,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) IncidentLight directLight = getSpotDirectLight( pointLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); @@ -52,7 +61,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) IncidentLight directLight = getDirectionalDirectLight( pointLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); + BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); @@ -66,7 +75,7 @@ ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - BRDF_Lambert( indirectLight, geometry, diffuse, indirectReflectedLight ); + BRDF_Lambert( indirectLight, geometry, diffuseColor, indirectReflectedLight ); } From 05118ea6bb955ba7c97364c91414a8e04e4f4512 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 21:46:19 -0400 Subject: [PATCH 43/64] further consolidation of different material BRDFs via the same lighting template. --- examples/js/ShaderSkin.js | 4 +- examples/js/ShaderTerrain.js | 2 +- examples/webgl_shaders_tonemapping.html | 2 +- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 94 ++++++++++++------- src/renderers/shaders/ShaderChunk/common.glsl | 7 ++ .../{lights.glsl => lights_pars.glsl} | 0 .../ShaderChunk/lights_phong_fragment.glsl | 74 ++------------- .../lights_phong_pars_fragment.glsl | 27 ++++++ .../ShaderChunk/lights_physical_fragment.glsl | 82 ++-------------- .../lights_physical_pars_fragment.glsl | 36 +++++++ .../shaders/ShaderChunk/lights_template.glsl | 57 +++++++++++ src/renderers/shaders/ShaderLib.js | 10 +- utils/build/includes/common.json | 4 +- 13 files changed, 212 insertions(+), 187 deletions(-) rename src/renderers/shaders/ShaderChunk/{lights.glsl => lights_pars.glsl} (100%) create mode 100644 src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl create mode 100644 src/renderers/shaders/ShaderChunk/lights_template.glsl diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index b5576707273ddf..01e02f7431b47f 100644 --- a/examples/js/ShaderSkin.js +++ b/examples/js/ShaderSkin.js @@ -84,7 +84,7 @@ THREE.ShaderSkin = { THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], @@ -373,7 +373,7 @@ THREE.ShaderSkin = { "varying vec3 vViewPosition;", THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "lights" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "fog_pars_fragment" ], "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {", diff --git a/examples/js/ShaderTerrain.js b/examples/js/ShaderTerrain.js index de24595efb69ff..87d2c37779778b 100644 --- a/examples/js/ShaderTerrain.js +++ b/examples/js/ShaderTerrain.js @@ -90,7 +90,7 @@ THREE.ShaderTerrain = { THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], diff --git a/examples/webgl_shaders_tonemapping.html b/examples/webgl_shaders_tonemapping.html index 5fa3335d01f23b..954822eec3d30a 100644 --- a/examples/webgl_shaders_tonemapping.html +++ b/examples/webgl_shaders_tonemapping.html @@ -160,7 +160,7 @@ THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], "void main() {", diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 86c6b77bef3bc9..c804dbabf334b9 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -1,5 +1,7 @@ //#define ENERGY_PRESERVING_MONOCHROME +#define DIELECTRIC_SPECULAR_F0 0.20 + float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { if ( decayExponent > 0.0 ) { @@ -27,6 +29,7 @@ void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricConte } +// this roughness is a different property than specular roughness used in GGX. void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); @@ -57,44 +60,39 @@ vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { // Microfacet Models for Refraction through Rough Surfaces - equation (34) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// alpha is "roughness squared" in Disney’s reparameterization -float G_SmithSchlick( in float alpha, in float dotNL, in float dotNV ) { +// roughtness2 is "roughness squared" in Disney’s reparameterization +float G_SmithSchlick( in float roughtness2, in float dotNL, in float dotNV ) { // geometry term = G(l) . G(v) / 4(n . l)(n. v) - float a2 = alpha * alpha; - + float a2 = roughtness2 * roughtness2; float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 ); - float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 ); return 1.0 / ( gl * gv ); } +// useful for clear coat surfaces, use with Distribution_GGX. +float G_Kelemen( float vDotH ) { + + return 1.0 / ( 4.0 * vDotH * vDotH + 0.0000001 ); + +} // Microfacet Models for Refraction through Rough Surfaces - equation (33) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// alpha is "roughness squared" in Disney’s reparameterization -float D_GGX( in float alpha, in float dotNH ) { +// roughtness2 is "roughness squared" in Disney’s reparameterization +float D_GGX( in float roughtness2, in float dotNH ) { // factor of 1/PI in distribution term omitted - - float a2 = alpha * alpha; - - float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 + float a2 = roughtness2 * roughtness2; + float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid roughtness2 = 0 with dotNH = 1 return a2 / ( denom * denom ); } -float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { - - // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) - return 0.25; - -} - void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness2, inout ReflectedLight reflectedLight ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); @@ -111,42 +109,66 @@ void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext g } -float D_BlinnPhong( const in float shininess, const in float dotNH ) { - - // factor of 1/PI in distribution term omitted ??? - return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); - -} - -void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { +// this blends the existing reflected light with a clear coat. +void BRDF_GGX_ClearCoat_Over( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness, inout ReflectedLight reflectedLight ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); - vec3 F = F_Schlick( specularColor, dotLH ); - float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); - float D = D_BlinnPhong( shininess, dotNH ); + vec3 F = F_Schlick( vec3( DIELECTRIC_SPECULAR_F0 ), dotLH ); + float G = G_Kelemen( dotNV ); + float D = D_GGX( clearCoatRoughness, dotNH ); - reflectedLight.specular += incidentLight.color * F * ( G * D ); + vec3 clearCoatColor = F * ( G * D ); + + reflectedLight.diffuse = mix( reflectedLight.diffuse, vec3( 0.0 ), clearCoatWeight ); + reflectedLight.specular = mix( reflectedLight.specular, clearCoatColor, clearCoatWeight ); } // ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile -vec3 envBRDFApprox( vec3 specularColor, float roughness, in vec3 normal, in vec3 viewDir ) { +vec3 BRDF_GGX_Environment( const in GeometricContext geometry, vec3 specularColor, float roughness ) { - float dotNV = saturate( dot( normal, viewDir ) ); + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); - const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); - vec4 r = roughness * c0 + c1; - float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; - vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; return specularColor * AB.x + AB.y; +} + + +float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { + + // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) + return 0.25; + +} + +float D_BlinnPhong( const in float shininess, const in float dotNH ) { + + // factor of 1/PI in distribution term omitted ??? + return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); + +} + +void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { + + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + + vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); + float D = D_BlinnPhong( shininess, dotNH ); + + reflectedLight.specular += incidentLight.color * F * ( G * D ); + } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index 642f55ce526d90..ddd252a86679a1 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -21,6 +21,13 @@ struct ReflectedLight { vec3 diffuse; }; +void accumulateReflectedLight( inout ReflectedLight accumulator, const in ReflectedLight item ) { + + accumulator.diffuse += item.diffuse; + accumulator.specular += item.specular; + +} + struct GeometricContext { vec3 position; vec3 normal; diff --git a/src/renderers/shaders/ShaderChunk/lights.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl similarity index 100% rename from src/renderers/shaders/ShaderChunk/lights.glsl rename to src/renderers/shaders/ShaderChunk/lights_pars.glsl diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index c3f89bfac2a602..b8293f053c3244 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -1,80 +1,20 @@ -vec3 diffuse = diffuseColor.rgb; +BlinnPhongMaterial material; +material.specularColor = specular; +material.specularShininess = shininess; +material.diffuseColor = diffuseColor.rgb; #ifdef METAL - diffuse = vec3( 0.0 ); + material.diffuseColor = vec3( 0.0 ); #endif #if defined( ENERGY_PRESERVING_RGB ) - diffuse *= whiteCompliment( specular ); + material.diffuseColor *= whiteCompliment( specular ); #elif defined( ENERGY_PRESERVING_MONOCHROME ) - diffuse *= whiteCompliment( luminance( specular ) ); + material.diffuseColor *= whiteCompliment( luminance( specular ) ); #endif - -GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); - -ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - -#if MAX_POINT_LIGHTS > 0 - - for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - - IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); - - BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - - IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); - - BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); - - } - -#endif - -#if MAX_DIR_LIGHTS > 0 - - for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - - IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight ); - //BRDF_OrenNayar( directLight, geometry, diffuse, 0.5, directReflectedLight ); - - BRDF_BlinnPhong( directLight, geometry, specular, shininess, directReflectedLight ); - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - - IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - - BRDF_Lambert( indirectLight, geometry, diffuse, indirectReflectedLight ); - //BRDF_OrenNayar( indirectLight, geometry, diffuse, 0.5, indirectReflectedLight ); - - } - -#endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index d5c2b5f09abed0..d8789a63d21c49 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -12,3 +12,30 @@ varying vec3 vViewPosition; #endif + +struct BlinnPhongMaterial { + vec3 diffuseColor; + float specularShininess; + vec3 specularColor; +}; + +void BRDF_BlinnPhongMaterial_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight directReflectedLight ) { + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + + BRDF_Lambert( directLight, geometry, material.diffuseColor, directReflectedLight ); + //BRDF_OrenNayar( directLight, geometry, material.diffuseColor, 0.5, directReflectedLight ); + + BRDF_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess, directReflectedLight ); + +} + + +void BRDF_BlinnPhongMaterial_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { + + BRDF_Lambert( indirectLight, geometry, material.diffuseColor, indirectReflectedLight ); + +} + +#define BRDF_Material_DirectLight BRDF_BlinnPhongMaterial_DirectLight +#define BRDF_Material_IndirectLight BRDF_BlinnPhongMaterial_IndirectLight diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl index d8c9541addbdde..beb8a57fa255c7 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl @@ -1,82 +1,14 @@ - -// roughness linear remapping - -roughnessFactor = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ] - - -// metalness effect on color - -vec3 specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); - -diffuseColor.rgb *= ( 1.0 - metalnessFactor ); - +PhysicalMaterial material; +material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); +material.specularRoughness = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ] +material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); #if defined( ENERGY_PRESERVING_RGB ) - diffuseColor *= whiteCompliment( specularColor ); + material.diffuseColor *= whiteCompliment( specularColor ); #elif defined( ENERGY_PRESERVING_MONOCHROME ) - diffuseColor *= whiteCompliment( luminance( specularColor ) ); - -#endif - -GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); - -ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - - -#if MAX_POINT_LIGHTS > 0 - - for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { - - IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); - - BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); - - } - -#endif - -#if MAX_SPOT_LIGHTS > 0 - - for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { - - IncidentLight directLight = getSpotDirectLight( pointLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); - - BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); - - } - -#endif - -#if MAX_DIR_LIGHTS > 0 - - for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { - - IncidentLight directLight = getDirectionalDirectLight( pointLights[ i ], geometry ); - - BRDF_Lambert( directLight, geometry, diffuseColor, directReflectedLight ); - - BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight ); - - } - -#endif - -#if MAX_HEMI_LIGHTS > 0 - - for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - - IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - - BRDF_Lambert( indirectLight, geometry, diffuseColor, indirectReflectedLight ); - - } + material.diffuseColor *= whiteCompliment( luminance( specularColor ) ); -#endif +#endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl new file mode 100644 index 00000000000000..50b4b9639938a4 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -0,0 +1,36 @@ +struct PhysicalMaterial { + vec3 diffuseColor; + float specularRoughness; + vec3 specularColor; + float clearCoatWeight; + float clearCoatRoughness; +}; + +void BRDF_PhysicalMaterial_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight directReflectedLight ) { + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + + BRDF_Lambert( directLight, geometry, material.diffuseColor, reflectedLight ); + + BRDF_GGX( directLight, geometry, material.specularColor, material.roughness, reflectedLight ); + +#ifdef CLEARCOAT + + BRDF_GGX_ClearCoat_Over( directLight, geometry, material.clearCoatWeight, material.clearCoatRoughness, reflectedLight ); + +#endif + + directReflectedLight.diffuse += reflectedLight.diffuse; + directReflectedLight.specular += reflectedLight.specular; + +} + + +void BRDF_PhysicalMaterial_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { + + BRDF_Lambert( indirectLight, geometry, material.diffuseColor, indirectReflectedLight ); + +} + +#define BRDF_Material_DirectLight BRDF_PhysicalMaterial_DirectLight +#define BRDF_Material_IndirectLight BRDF_PhysicalMaterial_IndirectLight diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl new file mode 100644 index 00000000000000..cf4160893d501b --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -0,0 +1,57 @@ +// Instructions for use: +// - Ensure that both BRDF_Material_DirectLight and BRDF_Material_Indirect light are defined +// - Create a material parameter that is to be passed as the third parameter to your lighting functions. + +GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); + +ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); +ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + + +#if MAX_POINT_LIGHTS > 0 + + for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { + + IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); + + BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + + } + +#endif + +#if MAX_SPOT_LIGHTS > 0 + + for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { + + IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); + + BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + + } + +#endif + +#if MAX_DIR_LIGHTS > 0 + + for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { + + IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); + + BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + + } + +#endif + +#if MAX_HEMI_LIGHTS > 0 + + for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { + + IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); + + BRDF_Material_IndirectLight( indirectLight, geometry, material, indirectReflectedLight ); + + } + +#endif diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 42daff96651975..1070f6f48a31b3 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -144,7 +144,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "uv2_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights" ], + THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "color_pars_vertex" ], THREE.ShaderChunk[ "morphtarget_pars_vertex" ], THREE.ShaderChunk[ "skinning_pars_vertex" ], @@ -352,10 +352,9 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "emissivemap_pars_fragment" ], THREE.ShaderChunk[ "envmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], + THREE.ShaderChunk[ "bsdfs" ], THREE.ShaderChunk[ "lights_pars" ], THREE.ShaderChunk[ "lights_phong_pars_fragment" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights" ], THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], THREE.ShaderChunk[ "normalmap_pars_fragment" ], @@ -382,6 +381,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "emissivemap_fragment" ], THREE.ShaderChunk[ "lights_phong_fragment" ], + THREE.ShaderChunk[ "lights_template" ], THREE.ShaderChunk[ "shadowmap_fragment" ], "directReflectedLight.diffuse *= shadowMask;", @@ -522,8 +522,9 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "emissivemap_pars_fragment" ], THREE.ShaderChunk[ "envmap_pars_fragment" ], THREE.ShaderChunk[ "fog_pars_fragment" ], + THREE.ShaderChunk[ "bsdfs" ], THREE.ShaderChunk[ "lights_pars" ], - THREE.ShaderChunk[ "lights_phong_pars_fragment" ], // use phong chunk for now + THREE.ShaderChunk[ "lights_physical_pars_fragment" ], // use phong chunk for now THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "bumpmap_pars_fragment" ], THREE.ShaderChunk[ "normalmap_pars_fragment" ], @@ -555,6 +556,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "emissivemap_fragment" ], THREE.ShaderChunk[ "lights_physical_fragment" ], + THREE.ShaderChunk[ "lights_template" ], THREE.ShaderChunk[ "shadowmap_fragment" ], "totalDiffuseLight *= shadowMask;", diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 9e2b3bc8f430c7..30ad2c4fba3eaa 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -130,7 +130,7 @@ "src/renderers/shaders/ShaderChunk/envmap_vertex.glsl", "src/renderers/shaders/ShaderChunk/fog_fragment.glsl", "src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", - "src/renderers/shaders/ShaderChunk/lights.glsl", + "src/renderers/shaders/ShaderChunk/lights_pars.glsl", "src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl", @@ -139,6 +139,8 @@ "src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl", "src/renderers/shaders/ShaderChunk/lights_phong_vertex.glsl", "src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl", + "src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl", + "src/renderers/shaders/ShaderChunk/lights_template.glsl", "src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl", "src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl", "src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl", From ba207f089de724f8c9240304c640de26aeb6607b Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 20 Oct 2015 23:47:58 -0400 Subject: [PATCH 44/64] incorporate indirectReflectedLight into lightmap, envmap and oamap per @WestLangley. --- .../shaders/ShaderChunk/aomap_fragment.glsl | 2 +- .../shaders/ShaderChunk/envmap_fragment.glsl | 6 +- .../ShaderChunk/envmap_physical_fragment.glsl | 2 +- .../ShaderChunk/lightmap_fragment.glsl | 2 +- .../shaders/ShaderChunk/lights_template.glsl | 4 -- src/renderers/shaders/ShaderLib.js | 61 ++++++++++--------- 6 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl b/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl index 2f444dbf69515c..fa3d189c6bab28 100644 --- a/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_AOMAP - totalAmbientLight *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; + indirectReflectedLight.diffuse *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; #endif diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 1d125de494f377..11be9fddda412f 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -47,15 +47,15 @@ #ifdef ENVMAP_BLENDING_MULTIPLY - outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); + indirectReflectedLight.specular = mix( indirectReflectedLight.specular, indirectReflectedLight.specular * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) - outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); + indirectReflectedLight.specular = mix( indirectReflectedLight.specular, envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_ADD ) - outgoingLight += envColor.xyz * specularStrength * reflectivity; + indirectReflectedLight.specular += envColor.xyz * specularStrength * reflectivity; #endif diff --git a/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl index c50a7f9a9af1c3..3d9bccdbcd1d34 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl @@ -57,7 +57,7 @@ envMapColor.rgb = inputToLinear( envMapColor.rgb ); - outgoingLight += envBRDFApprox( specularColor, roughnessFactor, normal, viewDir ) * envMapColor.rgb * envMapIntensity * reflectivityFactor; + indirectReflectedLight.specular += envBRDFApprox( specularColor, roughnessFactor, normal, viewDir ) * envMapColor.rgb * envMapIntensity * reflectivityFactor; #endif diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl index 803ab91a6e5f0c..b1e79d52c3c69e 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl @@ -1,5 +1,5 @@ #ifdef USE_LIGHTMAP - totalAmbientLight += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; + indirectReflectedLight.diffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index cf4160893d501b..3ebd387ee237e6 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -4,10 +4,6 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); -ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - - #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 1070f6f48a31b3..9aa30af09f9bbf 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -82,9 +82,7 @@ THREE.ShaderLib = { "void main() {", - " vec3 outgoingLight = vec3( 0.0 );", " vec4 diffuseColor = vec4( diffuse, opacity );", - " vec3 totalAmbientLight = vec3( 1.0 );", // hardwired " vec3 shadowMask = vec3( 1.0 );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], @@ -93,12 +91,15 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "alphamap_fragment" ], THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "aomap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], - " outgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), diffuse );", + THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "envmap_fragment" ], + THREE.ShaderChunk[ "shadowmap_fragment" ], + "indirectReflectedLight.diffuse *= shadowMask;", + + "vec3 outgoingLight = indirectReflectedLight.diffuse;", THREE.ShaderChunk[ "linear_to_gamma_fragment" ], @@ -234,8 +235,6 @@ THREE.ShaderLib = { " #endif", - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], @@ -363,12 +362,11 @@ THREE.ShaderLib = { "void main() {", - " vec3 outgoingLight = vec3( 0.0 );", " vec4 diffuseColor = vec4( diffuse, opacity );", - " vec3 totalAmbientLight = ambientLightColor;", + " ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), ambientLightColor );", " vec3 totalEmissiveLight = emissive;", - " vec3 shadowMask = vec3( 1.0 );", - + THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], THREE.ShaderChunk[ "color_fragment" ], @@ -376,29 +374,32 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], THREE.ShaderChunk[ "normal_phong_fragment" ], - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "emissivemap_fragment" ], + // accumulation THREE.ShaderChunk[ "lights_phong_fragment" ], THREE.ShaderChunk[ "lights_template" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], + THREE.ShaderChunk[ "lightmap_fragment" ], + // modulation + THREE.ShaderChunk[ "envmap_fragment" ], + THREE.ShaderChunk[ "aomap_fragment" ], + + "vec3 shadowMask = vec3( 1.0 );", + THREE.ShaderChunk[ "shadowmap_fragment" ], "directReflectedLight.diffuse *= shadowMask;", "directReflectedLight.specular *= shadowMask;", "#ifdef METAL", - " outgoingLight += diffuseColor.rgb * ( directReflectedLight.diffuse + indirectReflectedLight.diffuse + totalAmbientLight ) * specular + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;", + " vec3 outgoingLight = ( directReflectedLight.diffuse + indirectReflectedLight.diffuse ) * specular + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;", "#else", - " outgoingLight += diffuseColor.rgb * ( directReflectedLight.diffuse + indirectReflectedLight.diffuse + totalAmbientLight ) + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;", + " vec3 outgoingLight = ( directReflectedLight.diffuse + indirectReflectedLight.diffuse ) + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;", "#endif", - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], @@ -535,11 +536,10 @@ THREE.ShaderLib = { "void main() {", - " vec3 outgoingLight = vec3( 0.0 );", " vec4 diffuseColor = vec4( diffuse, opacity );", - " vec3 totalAmbientLight = ambientLightColor;", + " ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), ambientLightColor );", " vec3 totalEmissiveLight = emissive;", - " vec3 shadowMask = vec3( 1.0 );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], THREE.ShaderChunk[ "map_fragment" ], @@ -551,20 +551,23 @@ THREE.ShaderLib = { //THREE.ShaderChunk[ "reflectivitymap_fragment" ], THREE.ShaderChunk[ "metalnessmap_fragment" ], THREE.ShaderChunk[ "normal_phong_fragment" ], // use phong chunk for now - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "emissivemap_fragment" ], + // accumulation THREE.ShaderChunk[ "lights_physical_fragment" ], - THREE.ShaderChunk[ "lights_template" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], + THREE.ShaderChunk[ "lights_template" ], + THREE.ShaderChunk[ "lightmap_fragment" ], + THREE.ShaderChunk[ "envmap_physical_fragment" ], - "totalDiffuseLight *= shadowMask;", - "totalSpecularLight *= shadowMask;", + // modulation + THREE.ShaderChunk[ "aomap_fragment" ], - "outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight;", + "vec3 shadowMask = vec3( 1.0 );", + THREE.ShaderChunk[ "shadowmap_fragment" ], + "directReflectedLight.diffuse *= shadowMask;", + "directReflectedLight.specular *= shadowMask;", - THREE.ShaderChunk[ "envmap_physical_fragment" ], + "vec3 outgoingLight = directReflectedLight.diffuse + indirectReflectedLight.diffuse + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;", THREE.ShaderChunk[ "linear_to_gamma_fragment" ], From b1df0234204f9a43eaa3c80da91803e87ded52d8 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 00:55:36 -0400 Subject: [PATCH 45/64] fix reflectivity (it should modulate specularColor globally), fix GGX Render Equation, clean up BRDF_GGX_Environment to have incident and reflected light, pull out SpecularLightProbe. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 32 ++++++-- .../ShaderChunk/envmap_physical_fragment.glsl | 63 ---------------- .../shaders/ShaderChunk/lights_pars.glsl | 73 +++++++++++++++++++ .../lights_phong_pars_fragment.glsl | 4 +- .../ShaderChunk/lights_physical_fragment.glsl | 2 +- .../lights_physical_pars_fragment.glsl | 17 ++++- .../shaders/ShaderChunk/lights_template.glsl | 22 ++++-- 7 files changed, 133 insertions(+), 80 deletions(-) delete mode 100644 src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index c804dbabf334b9..aae3d9343deca5 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -15,6 +15,20 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } +ReflectedLight BRDF_Mix( const in ReflectedLight base, const in ReflectedLight over, const in float weight ) { + return ReflectedLight( + mix( base.diffuse, over.diffuse, weight ), + mix( base.specular, over.specular, weight ) + ); +} + +ReflectedLight BRDF_Add( const in ReflectedLight base, const in ReflectedLight over, const in float weight ) { + return ReflectedLight( + base.diffuse + over.diffuse, + base.specular + over.specular + ); +} + void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); @@ -105,12 +119,14 @@ void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext g float G = G_SmithSchlick( roughness2, dotNL, dotNV ); float D = D_GGX( roughness2, dotNH ); - reflectedLight.specular += incidentLight.color * F * ( G * D ); + reflectedLight.specular += incidentLight.color * F * ( dotNL * G * D ); } +#define DIELECTRIC_SPECULAR_F0 0.20 + // this blends the existing reflected light with a clear coat. -void BRDF_GGX_ClearCoat_Over( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness, inout ReflectedLight reflectedLight ) { +void BRDF_GGX_ClearCoat( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness, inout ReflectedLight reflectedLight ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); @@ -122,15 +138,17 @@ void BRDF_GGX_ClearCoat_Over( const in IncidentLight incidentLight, const in Geo float G = G_Kelemen( dotNV ); float D = D_GGX( clearCoatRoughness, dotNH ); - vec3 clearCoatColor = F * ( G * D ); + + ReflectedLight clearCoatReflectedLight; + clearCoatReflectedLight.specular = incidentLight.color * F * ( G * D ); + clearCoatReflectedLight.diffuse = vec3( 0.0 ); - reflectedLight.diffuse = mix( reflectedLight.diffuse, vec3( 0.0 ), clearCoatWeight ); - reflectedLight.specular = mix( reflectedLight.specular, clearCoatColor, clearCoatWeight ); + reflectedLight = BRDF_Mix( reflectedLight, clearCoatReflectedLight, clearCoatWeight ); } // ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile -vec3 BRDF_GGX_Environment( const in GeometricContext geometry, vec3 specularColor, float roughness ) { +void BRDF_GGX_Environment( const in IncidentLight incidentLight, const in GeometricContext geometry, vec3 specularColor, float roughness, inout ReflectedLight reflectedLight ) { float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); @@ -140,7 +158,7 @@ vec3 BRDF_GGX_Environment( const in GeometricContext geometry, vec3 specularColo float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; - return specularColor * AB.x + AB.y; + reflectedLight.specular += incidentLight.color * specularColor * AB.x + AB.y; } diff --git a/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl deleted file mode 100644 index 3d9bccdbcd1d34..00000000000000 --- a/src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl +++ /dev/null @@ -1,63 +0,0 @@ -#ifdef USE_ENVMAP - - float reflectivityFactor = reflectivity; // fix add map - replace specular strength? - - vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition ); - - // Transforming Normal Vectors with the Inverse Transformation - vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); - - #ifdef ENVMAP_MODE_REFLECTION - - vec3 reflectVec = reflect( cameraToVertex, worldNormal ); - - #else - - vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio ); - - #endif - - #ifdef DOUBLE_SIDED - - float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 ); - - #else - - float flipNormal = 1.0; - - #endif - - #ifdef ENVMAP_TYPE_CUBE - - #if defined( TEXTURE_CUBE_LOD_EXT ) - - float bias = pow( roughness, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor) - - vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias ); - - #else - - vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); - - #endif - - #elif defined( ENVMAP_TYPE_EQUIREC ) - - vec2 sampleUV; - sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); - sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; - vec4 envMapColor = texture2D( envMap, sampleUV ); - - #elif defined( ENVMAP_TYPE_SPHERE ) - - vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); - vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); - - #endif - - envMapColor.rgb = inputToLinear( envMapColor.rgb ); - - indirectReflectedLight.specular += envBRDFApprox( specularColor, roughnessFactor, normal, viewDir ) * envMapColor.rgb * envMapIntensity * reflectivityFactor; - -#endif - diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index f589e4b40705bc..04524424d9dd5b 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -111,3 +111,76 @@ uniform vec3 ambientLightColor; } #endif + + +#ifdef USE_ENVMAP + + struct SpecularLightProbe { + samplerCube map; + float intensity; + }; + + IncidentLight getSpecularLightProbeIndirectLight( const in SpecularLightProbe specularLightProbe, const in GeometricContext geometry, const in float lodLevel ) { + + #ifdef ENVMAP_MODE_REFLECTION + + vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); + + #else + + vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio ); + + #endif + + #ifdef DOUBLE_SIDED + + float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 ); + + #else + + float flipNormal = 1.0; + + #endif + + reflectVec = normalize( transformDirection( reflectVec, viewMatrix ) ); + + #ifdef ENVMAP_TYPE_CUBE + + #if defined( TEXTURE_CUBE_LOD_EXT ) + + float bias = pow( lodLevel, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor) + + vec4 envMapColor = textureCubeLodEXT( specularLightProbe.map, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias ); + + #else + + vec4 envMapColor = textureCube( specularLightProbe.map, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); + + #endif + + #elif defined( ENVMAP_TYPE_EQUIREC ) + + vec2 sampleUV; + sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); + sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; + vec4 envMapColor = texture2D( specularLightProbe.map, sampleUV ); + + #elif defined( ENVMAP_TYPE_SPHERE ) + + vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); + vec4 envMapColor = texture2D( specularLightProbe.map, reflectView.xy * 0.5 + 0.5 ); + + #endif + + envMapColor.rgb = inputToLinear( envMapColor.rgb ); + + IncidentLight indirectLight; + indirectLight.color = envMapColor.rgb * specularLightProbe.intensity; + indirectLight.direction = geometry.normal; + + return indirectLight; + + } + +#endif + diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index d8789a63d21c49..11a4d9b0de59fd 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -30,6 +30,7 @@ void BRDF_BlinnPhongMaterial_DirectLight( const in IncidentLight directLight, co } +#define BRDF_Material_DirectLight BRDF_BlinnPhongMaterial_DirectLight void BRDF_BlinnPhongMaterial_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { @@ -37,5 +38,6 @@ void BRDF_BlinnPhongMaterial_IndirectLight( const in IncidentLight indirectLight } -#define BRDF_Material_DirectLight BRDF_BlinnPhongMaterial_DirectLight #define BRDF_Material_IndirectLight BRDF_BlinnPhongMaterial_IndirectLight + +#define Material_LightProbeLOD( material ) (0) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl index beb8a57fa255c7..5d6abc35148cbb 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl @@ -1,7 +1,7 @@ PhysicalMaterial material; material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); material.specularRoughness = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ] -material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); +material.specularColor = mix( vec3( 0.04 ) * reflectivity, diffuseColor.rgb, metalnessFactor ); #if defined( ENERGY_PRESERVING_RGB ) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index 50b4b9639938a4..0b67aecac1c396 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -24,13 +24,24 @@ void BRDF_PhysicalMaterial_DirectLight( const in IncidentLight directLight, cons directReflectedLight.specular += reflectedLight.specular; } +#define BRDF_Material_DirectLight BRDF_PhysicalMaterial_DirectLight -void BRDF_PhysicalMaterial_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { +void BRDF_PhysicalMaterial_DiffuseIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { BRDF_Lambert( indirectLight, geometry, material.diffuseColor, indirectReflectedLight ); } -#define BRDF_Material_DirectLight BRDF_PhysicalMaterial_DirectLight -#define BRDF_Material_IndirectLight BRDF_PhysicalMaterial_IndirectLight +#define BRDF_Material_DiffuseIndirectLight BRDF_PhysicalMaterial_DiffuseIndirectLight + + +void BRDF_PhysicalMaterial_SpecularIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { + + BRDF_GGX_Environment( lightProbeIncidentLight, geometry, material.specularColor, material.roughness, indirectReflectedLight ); + +} + +#define Material_LightProbeLOD( material ) (material.roughness) + +#define BRDF_Material_SpecularIndirectLight BRDF_PhysicalMaterial_SpecularIndirectLight diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 3ebd387ee237e6..f613a1b2a381ee 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -4,7 +4,7 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); -#if MAX_POINT_LIGHTS > 0 +#if ( MAX_POINT_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { @@ -16,7 +16,7 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif -#if MAX_SPOT_LIGHTS > 0 +#if ( MAX_SPOT_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { @@ -28,7 +28,7 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif -#if MAX_DIR_LIGHTS > 0 +#if ( MAX_DIR_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { @@ -40,14 +40,26 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif -#if MAX_HEMI_LIGHTS > 0 +#if ( MAX_HEMI_LIGHTS > 0 ) && defined( BRDF_Material_DiffuseIndirectLight ) for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - BRDF_Material_IndirectLight( indirectLight, geometry, material, indirectReflectedLight ); + BRDF_Material_DiffuseIndirectLight( indirectLight, geometry, material, indirectReflectedLight ); } #endif + +#if defined( ENV_MAP ) && defined( BRDF_Material_SpecularIndirectLight ) + + { + + IncidentLight indirectLight = getSpecularLightProbeIndirectLight( specularLightProbe, geometry, Material_LightProbeLOD( material ) ); + + BRDF_Material_SpecularIndirectLight( lightProbeIncidentLight, geometry, material, indirectReflectedLight ); + + } + +#endif \ No newline at end of file From c5e001a74b3df9111fb55f050e19f287127d5440 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 01:36:18 -0400 Subject: [PATCH 46/64] incorporate ambientLightColor into standardized BRDF calculations. --- src/renderers/shaders/ShaderChunk/lights_pars.glsl | 9 +++++++++ .../shaders/ShaderChunk/lights_phong_pars_fragment.glsl | 2 +- src/renderers/shaders/ShaderChunk/lights_template.glsl | 8 ++++++++ src/renderers/shaders/ShaderLib.js | 4 ++-- utils/build/includes/common.json | 1 - 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 04524424d9dd5b..428b5d89504a5a 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -86,6 +86,15 @@ uniform vec3 ambientLightColor; #endif + IncidentLight getAmbientIndirectLight( const in vec3 ambientLightColor, const in GeometricContext geometry ) { + + IncidentLight indirectLight; + + indirectLight.color = ambientLightColor; + indirectLight.direction = geometry.normal; + + return indirectLight; + } #if MAX_HEMI_LIGHTS > 0 diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 11a4d9b0de59fd..7f0f47b3269293 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -38,6 +38,6 @@ void BRDF_BlinnPhongMaterial_IndirectLight( const in IncidentLight indirectLight } -#define BRDF_Material_IndirectLight BRDF_BlinnPhongMaterial_IndirectLight +#define BRDF_Material_DiffuseIndirectLight BRDF_BlinnPhongMaterial_IndirectLight #define Material_LightProbeLOD( material ) (0) diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index f613a1b2a381ee..81ff6604a94e0a 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -40,6 +40,14 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif + { + + IncidentLight indirectLight = getAmbientIndirectLight( ambientLightColor, geometry ); + + BRDF_Material_DiffuseIndirectLight( indirectLight, geometry, material, indirectReflectedLight ); + + } + #if ( MAX_HEMI_LIGHTS > 0 ) && defined( BRDF_Material_DiffuseIndirectLight ) for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 9aa30af09f9bbf..74fa38a56705ac 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -364,7 +364,7 @@ THREE.ShaderLib = { " vec4 diffuseColor = vec4( diffuse, opacity );", " ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", - " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), ambientLightColor );", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", " vec3 totalEmissiveLight = emissive;", THREE.ShaderChunk[ "logdepthbuf_fragment" ], @@ -538,7 +538,7 @@ THREE.ShaderLib = { " vec4 diffuseColor = vec4( diffuse, opacity );", " ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", - " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), ambientLightColor );", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );", " vec3 totalEmissiveLight = emissive;", THREE.ShaderChunk[ "logdepthbuf_fragment" ], diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 30ad2c4fba3eaa..ac8078d00bde5f 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -126,7 +126,6 @@ "src/renderers/shaders/ShaderChunk/envmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl", - "src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl", "src/renderers/shaders/ShaderChunk/envmap_vertex.glsl", "src/renderers/shaders/ShaderChunk/fog_fragment.glsl", "src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", From 28997aa732b173142865fa197bfc0413543eaf85 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 01:56:02 -0400 Subject: [PATCH 47/64] accumulate all indirect diffuse sources and then apply a single diffuse indirect BRDF. --- .../ShaderChunk/lightmap_fragment.glsl | 5 ----- .../shaders/ShaderChunk/lights_template.glsl | 22 ++++++++++++++----- utils/build/includes/common.json | 1 - 3 files changed, 16 insertions(+), 12 deletions(-) delete mode 100644 src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl deleted file mode 100644 index b1e79d52c3c69e..00000000000000 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef USE_LIGHTMAP - - indirectReflectedLight.diffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; - -#endif diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 81ff6604a94e0a..0c9406e9e0bf9b 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -40,19 +40,29 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif +#if defined( BRDF_Material_DiffuseIndirectLight ) + { - IncidentLight indirectLight = getAmbientIndirectLight( ambientLightColor, geometry ); + IncidentLight indirectLight; + indirectLight.direction = geometry.normal; + indirectLight.color = ambientLightColor; - BRDF_Material_DiffuseIndirectLight( indirectLight, geometry, material, indirectReflectedLight ); +#ifdef USE_LIGHTMAP - } + indirectLight.color += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; + +#endif + +#if ( MAX_HEMI_LIGHTS > 0 ) -#if ( MAX_HEMI_LIGHTS > 0 ) && defined( BRDF_Material_DiffuseIndirectLight ) + for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { + indirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ).color; - IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); + } + +#endif BRDF_Material_DiffuseIndirectLight( indirectLight, geometry, material, indirectReflectedLight ); diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index ac8078d00bde5f..b602a0b5521f4e 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -130,7 +130,6 @@ "src/renderers/shaders/ShaderChunk/fog_fragment.glsl", "src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/lights_pars.glsl", - "src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl", "src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl", From 8610ef32210a5426aedd4ecd29c3ba4c0f2ff3c0 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 01:59:51 -0400 Subject: [PATCH 48/64] remove unneeded function. --- src/renderers/shaders/ShaderChunk/common.glsl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl b/src/renderers/shaders/ShaderChunk/common.glsl index ddd252a86679a1..642f55ce526d90 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl +++ b/src/renderers/shaders/ShaderChunk/common.glsl @@ -21,13 +21,6 @@ struct ReflectedLight { vec3 diffuse; }; -void accumulateReflectedLight( inout ReflectedLight accumulator, const in ReflectedLight item ) { - - accumulator.diffuse += item.diffuse; - accumulator.specular += item.specular; - -} - struct GeometricContext { vec3 position; vec3 normal; From 23ebff6bc0a3eecee4f1bb463a9913ed8c4b82b4 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 12:25:58 -0400 Subject: [PATCH 49/64] split BRDFs from Rendering Equations per @WestLangley's recommendations. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 36 ++++++++---------- .../ShaderChunk/lights_lambert_vertex.glsl | 25 +++++++----- .../shaders/ShaderChunk/lights_pars.glsl | 17 +++------ .../lights_phong_pars_fragment.glsl | 20 +++++----- .../lights_physical_pars_fragment.glsl | 38 ++++++++----------- .../shaders/ShaderChunk/lights_template.glsl | 22 +++++------ src/renderers/shaders/ShaderLib.js | 14 +++++++ 7 files changed, 90 insertions(+), 82 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index aae3d9343deca5..4b926c2bd79a16 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -29,22 +29,22 @@ ReflectedLight BRDF_Add( const in ReflectedLight base, const in ReflectedLight o ); } -void BRDF_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) { - - float lambertianReflectance = saturate( dot( geometryContext.normal, incidentLight.direction ) ); +vec3 BRDF_Diffuse_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor ) { #if defined( ENERGY_PRESERVING_MONOCHROME ) || defined( ENERGY_PRESERVING_RGB ) - lambertianReflectance *= RECIPROCAL_PI; + return diffuseColor * RECIPROCAL_PI; - #endif + #else - reflectedLight.diffuse += incidentLight.color * diffuseColor * lambertianReflectance; + return diffuseColor; + + #endif } // this roughness is a different property than specular roughness used in GGX. -void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness, inout ReflectedLight reflectedLight ) { +vec3 BRDF_Diffuse_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness ) { vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); @@ -56,7 +56,7 @@ void BRDF_OrenNayar( const in IncidentLight incidentLight, const in GeometricCon float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); - reflectedLight.diffuse = incidentLight.color * diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); + return diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); } @@ -107,7 +107,7 @@ float D_GGX( in float roughtness2, in float dotNH ) { } -void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness2, inout ReflectedLight reflectedLight ) { +vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness2 ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); @@ -119,14 +119,14 @@ void BRDF_GGX( const in IncidentLight incidentLight, const in GeometricContext g float G = G_SmithSchlick( roughness2, dotNL, dotNV ); float D = D_GGX( roughness2, dotNH ); - reflectedLight.specular += incidentLight.color * F * ( dotNL * G * D ); + return F * ( G * D ); } #define DIELECTRIC_SPECULAR_F0 0.20 // this blends the existing reflected light with a clear coat. -void BRDF_GGX_ClearCoat( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness, inout ReflectedLight reflectedLight ) { +vec3 BRDF_Specular_ClearCoat( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); @@ -139,16 +139,12 @@ void BRDF_GGX_ClearCoat( const in IncidentLight incidentLight, const in Geometri float D = D_GGX( clearCoatRoughness, dotNH ); - ReflectedLight clearCoatReflectedLight; - clearCoatReflectedLight.specular = incidentLight.color * F * ( G * D ); - clearCoatReflectedLight.diffuse = vec3( 0.0 ); - - reflectedLight = BRDF_Mix( reflectedLight, clearCoatReflectedLight, clearCoatWeight ); + return F * ( G * D ); } // ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile -void BRDF_GGX_Environment( const in IncidentLight incidentLight, const in GeometricContext geometry, vec3 specularColor, float roughness, inout ReflectedLight reflectedLight ) { +vec3 BRDF_Specular_GGX_Environment( const in IncidentLight incidentLight, const in GeometricContext geometry, vec3 specularColor, float roughness ) { float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); @@ -158,7 +154,7 @@ void BRDF_GGX_Environment( const in IncidentLight incidentLight, const in Geomet float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; - reflectedLight.specular += incidentLight.color * specularColor * AB.x + AB.y; + return specularColor * AB.x + AB.y; } @@ -177,7 +173,7 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) { } -void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) { +vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); @@ -187,6 +183,6 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); float D = D_BlinnPhong( shininess, dotNH ); - reflectedLight.specular += incidentLight.color * F * ( G * D ); + return F * ( G * D ); } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 013cfd17299c4d..07c686b41f2ec0 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -12,11 +12,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); + float dotNL = dot( geometry.normal, directLight.direction ); + frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); + float dotNLBack = dot( -geometry.normal, directLight.direction ); + backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif @@ -30,14 +32,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); + float dotNL = dot( geometry.normal, directLight.direction ); + frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); + float dotNLBack = dot( -geometry.normal, directLight.direction ); + backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif - } #endif @@ -48,11 +51,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); - BRDF_Lambert( directLight, geometry, diffuse, frontReflectedLight ); + float dotNL = dot( geometry.normal, directLight.direction ); + frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - BRDF_Lambert( directLight, backGeometry, diffuse, backReflectedLight ); + float dotNLBack = dot( -geometry.normal, directLight.direction ); + backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif @@ -66,13 +71,15 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - BRDF_Lambert( indirectLight, geometry, diffuse, frontReflectedLight ); + float dotNL = dot( geometry.normal, directLight.direction ); + frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ); - BRDF_Lambert( indirectLight, backGeometry, diffuse, backReflectedLight ); + float dotNLBack = dot( -geometry.normal, directLight.direction ); + backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 428b5d89504a5a..628122126e3acc 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -124,12 +124,7 @@ uniform vec3 ambientLightColor; #ifdef USE_ENVMAP - struct SpecularLightProbe { - samplerCube map; - float intensity; - }; - - IncidentLight getSpecularLightProbeIndirectLight( const in SpecularLightProbe specularLightProbe, const in GeometricContext geometry, const in float lodLevel ) { + IncidentLight getSpecularLightProbeIndirectLight( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) { #ifdef ENVMAP_MODE_REFLECTION @@ -159,11 +154,11 @@ uniform vec3 ambientLightColor; float bias = pow( lodLevel, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor) - vec4 envMapColor = textureCubeLodEXT( specularLightProbe.map, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias ); + vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias ); #else - vec4 envMapColor = textureCube( specularLightProbe.map, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); + vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); #endif @@ -172,19 +167,19 @@ uniform vec3 ambientLightColor; vec2 sampleUV; sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; - vec4 envMapColor = texture2D( specularLightProbe.map, sampleUV ); + vec4 envMapColor = texture2D( envMap, sampleUV ); #elif defined( ENVMAP_TYPE_SPHERE ) vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); - vec4 envMapColor = texture2D( specularLightProbe.map, reflectView.xy * 0.5 + 0.5 ); + vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); #endif envMapColor.rgb = inputToLinear( envMapColor.rgb ); IncidentLight indirectLight; - indirectLight.color = envMapColor.rgb * specularLightProbe.intensity; + indirectLight.color = envMapColor.rgb * reflectivity; indirectLight.direction = geometry.normal; return indirectLight; diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 7f0f47b3269293..1dc4d06df0d2bb 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -19,25 +19,27 @@ struct BlinnPhongMaterial { vec3 specularColor; }; -void BRDF_BlinnPhongMaterial_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight directReflectedLight ) { +void BlinnPhongMaterial_RE_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight directReflectedLight ) { - ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - BRDF_Lambert( directLight, geometry, material.diffuseColor, directReflectedLight ); - //BRDF_OrenNayar( directLight, geometry, material.diffuseColor, 0.5, directReflectedLight ); + directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, material.diffuseColor ); + //directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_OrenNayar( directLight, geometry, material.diffuseColor, 0.5 ); - BRDF_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess, directReflectedLight ); + directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ); } -#define BRDF_Material_DirectLight BRDF_BlinnPhongMaterial_DirectLight +#define Material_RE_DirectLight BlinnPhongMaterial_RE_DirectLight -void BRDF_BlinnPhongMaterial_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { +void BlinnPhongMaterial_RE_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { - BRDF_Lambert( indirectLight, geometry, material.diffuseColor, indirectReflectedLight ); + float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); + + indirectReflectedLight.diffuse += dotNL * indirectLight.color * BRDF_Diffuse_Lambert( indirectLight, geometry, material.diffuseColor ); } -#define BRDF_Material_DiffuseIndirectLight BRDF_BlinnPhongMaterial_IndirectLight +#define Material_RE_DiffuseIndirectLight BlinnPhongMaterial_RE_IndirectLight #define Material_LightProbeLOD( material ) (0) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index 0b67aecac1c396..102275574e24c0 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -6,42 +6,36 @@ struct PhysicalMaterial { float clearCoatRoughness; }; -void BRDF_PhysicalMaterial_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight directReflectedLight ) { +void PhysicalMaterial_RE_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight directReflectedLight ) { - ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - BRDF_Lambert( directLight, geometry, material.diffuseColor, reflectedLight ); - - BRDF_GGX( directLight, geometry, material.specularColor, material.roughness, reflectedLight ); - -#ifdef CLEARCOAT - - BRDF_GGX_ClearCoat_Over( directLight, geometry, material.clearCoatWeight, material.clearCoatRoughness, reflectedLight ); - -#endif - - directReflectedLight.diffuse += reflectedLight.diffuse; - directReflectedLight.specular += reflectedLight.specular; + directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, material.diffuseColor ); + directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); } -#define BRDF_Material_DirectLight BRDF_PhysicalMaterial_DirectLight +#define Material_RE_DirectLight PhysicalMaterial_RE_DirectLight + +void PhysicalMaterial_RE_DiffuseIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { -void BRDF_PhysicalMaterial_DiffuseIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { + float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); - BRDF_Lambert( indirectLight, geometry, material.diffuseColor, indirectReflectedLight ); + indirectReflectedLight.diffuse += dotNL * indirectLight.color * BRDF_Diffuse_Lambert( indirectLight, geometry, material.diffuseColor ); } -#define BRDF_Material_DiffuseIndirectLight BRDF_PhysicalMaterial_DiffuseIndirectLight +#define Material_RE_IndirectDiffuseLight PhysicalMaterial_RE_DiffuseIndirectLight + +void PhysicalMaterial_RE_SpecularIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { -void BRDF_PhysicalMaterial_SpecularIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { + float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); - BRDF_GGX_Environment( lightProbeIncidentLight, geometry, material.specularColor, material.roughness, indirectReflectedLight ); + indirectReflectedLight.specular += dotNL * indirectLight.color * BRDF_Specular_GGX_Environment( indirectLight, geometry, material.specularColor, material.specularRoughness ); } -#define Material_LightProbeLOD( material ) (material.roughness) +#define Material_LightProbeLOD( material ) (material.specularRoughness) -#define BRDF_Material_SpecularIndirectLight BRDF_PhysicalMaterial_SpecularIndirectLight +#define Material_RE_IndirectSpecularLight PhysicalMaterial_RE_SpecularIndirectLight diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 0c9406e9e0bf9b..5bdb8629167593 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -4,43 +4,43 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); -#if ( MAX_POINT_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) +#if ( MAX_POINT_LIGHTS > 0 ) && defined( Material_RE_DirectLight ) for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + Material_RE_DirectLight( directLight, geometry, material, directReflectedLight ); } #endif -#if ( MAX_SPOT_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) +#if ( MAX_SPOT_LIGHTS > 0 ) && defined( Material_RE_DirectLight ) for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); - BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + Material_RE_DirectLight( directLight, geometry, material, directReflectedLight ); } #endif -#if ( MAX_DIR_LIGHTS > 0 ) && defined( BRDF_Material_DirectLight ) +#if ( MAX_DIR_LIGHTS > 0 ) && defined( Material_RE_DirectLight ) for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); - BRDF_Material_DirectLight( directLight, geometry, material, directReflectedLight ); + Material_RE_DirectLight( directLight, geometry, material, directReflectedLight ); } #endif -#if defined( BRDF_Material_DiffuseIndirectLight ) +#if defined( Material_RE_IndirectDiffuseLight ) { @@ -64,19 +64,19 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #endif - BRDF_Material_DiffuseIndirectLight( indirectLight, geometry, material, indirectReflectedLight ); + Material_RE_IndirectDiffuseLight( indirectLight, geometry, material, indirectReflectedLight ); } #endif -#if defined( ENV_MAP ) && defined( BRDF_Material_SpecularIndirectLight ) +#if defined( USE_ENVMAP ) && defined( Material_RE_IndirectSpecularLight ) { - IncidentLight indirectLight = getSpecularLightProbeIndirectLight( specularLightProbe, geometry, Material_LightProbeLOD( material ) ); + IncidentLight indirectLight = getSpecularLightProbeIndirectLight( /*specularLightProbe,*/ geometry, Material_LightProbeLOD( material ) ); - BRDF_Material_SpecularIndirectLight( lightProbeIncidentLight, geometry, material, indirectReflectedLight ); + Material_RE_IndirectSpecularLight( indirectLight, geometry, material, indirectReflectedLight ); } diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 74fa38a56705ac..05314b55ed8793 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -67,6 +67,12 @@ THREE.ShaderLib = { "uniform vec3 diffuse;", "uniform float opacity;", + "#ifndef FLAT_SHADED", + + " varying vec3 vNormal;", + + "#endif", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "uv_pars_fragment" ], @@ -512,6 +518,14 @@ THREE.ShaderLib = { "uniform float envMapIntensity;", // temporary + "varying vec3 vViewPosition;", + + "#ifndef FLAT_SHADED", + + " varying vec3 vNormal;", + + "#endif", + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "uv_pars_fragment" ], From 26b54cdbaa8fd799b7eb80a9ce693bdd6d08dd2a Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 13:49:55 -0400 Subject: [PATCH 50/64] validated all bsdfs against preexisting code. materials match except for cubemaps. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 95 +++++++++++-------- .../lights_phong_pars_fragment.glsl | 2 +- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 4b926c2bd79a16..57db0ed93c835d 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -31,20 +31,14 @@ ReflectedLight BRDF_Add( const in ReflectedLight base, const in ReflectedLight o vec3 BRDF_Diffuse_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor ) { - #if defined( ENERGY_PRESERVING_MONOCHROME ) || defined( ENERGY_PRESERVING_RGB ) + // factor of 1/PI in BRDF omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source - return diffuseColor * RECIPROCAL_PI; + return diffuseColor; - #else - - return diffuseColor; - - #endif - -} +} // validated // this roughness is a different property than specular roughness used in GGX. -vec3 BRDF_Diffuse_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuse, const in float roughness ) { +vec3 BRDF_Diffuse_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, const in float roughness ) { vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); @@ -56,11 +50,11 @@ vec3 BRDF_Diffuse_OrenNayar( const in IncidentLight incidentLight, const in Geom float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); - return diffuse * ( RECIPROCAL_PI * ( dotNL * termA + termB ) ); + return diffuseColor * ( dotNL * termA + termB ); } -vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { +vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { // Original approximation by Christophe Schlick '94 //;float fresnel = pow( 1.0 - dotLH, 5.0 ); @@ -68,59 +62,72 @@ vec3 F_Schlick( const in vec3 F0, const in float dotLH ) { // Optimized variant (presented by Epic at SIGGRAPH '13) float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH ); - return F0 + ( 1.0 - F0 ) * fresnel; + return ( 1.0 - specularColor ) * fresnel + specularColor; -} +} // validated // Microfacet Models for Refraction through Rough Surfaces - equation (34) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// roughtness2 is "roughness squared" in Disney’s reparameterization -float G_SmithSchlick( in float roughtness2, in float dotNL, in float dotNV ) { +// alpha is "roughness squared" in Disney’s reparameterization +float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) { + + // geometry term = G(l)⋅G(v) / 4(n⋅l)(n⋅v) - // geometry term = G(l) . G(v) / 4(n . l)(n. v) + float a2 = alpha * alpha; - float a2 = roughtness2 * roughtness2; float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 ); + float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 ); return 1.0 / ( gl * gv ); -} +} // validated -// useful for clear coat surfaces, use with Distribution_GGX. -float G_Kelemen( float vDotH ) { - - return 1.0 / ( 4.0 * vDotH * vDotH + 0.0000001 ); - -} // Microfacet Models for Refraction through Rough Surfaces - equation (33) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// roughtness2 is "roughness squared" in Disney’s reparameterization -float D_GGX( in float roughtness2, in float dotNH ) { +// alpha is "roughness squared" in Disney’s reparameterization +float D_GGX( in float alpha, in float dotNH ) { + + // factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source + + float a2 = alpha * alpha; - // factor of 1/PI in distribution term omitted - float a2 = roughtness2 * roughtness2; - float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid roughtness2 = 0 with dotNH = 1 + float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 return a2 / ( denom * denom ); } -vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness2 ) { +// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility +vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { + // factor of 1/PI in BRDF omitted (normally it is in D_GGX) as incoming light intensity is scaled up by PI because it is considered a punctual light source + + float alpha = roughness * roughness; // UE4's roughness + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); - float dotNH = saturate( dot( geometry.normal, halfDir ) ); - float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); - float G = G_SmithSchlick( roughness2, dotNL, dotNV ); - float D = D_GGX( roughness2, dotNH ); + + float G = G_GGX_Smith( alpha, dotNL, dotNV ); + + float D = D_GGX( alpha, dotNH ); return F * ( G * D ); +} // validated + +// useful for clear coat surfaces, use with Distribution_GGX. +float G_Kelemen( float vDotH ) { + + return 1.0 / ( 4.0 * vDotH * vDotH + 0.0000001 ); + } #define DIELECTRIC_SPECULAR_F0 0.20 @@ -149,14 +156,18 @@ vec3 BRDF_Specular_GGX_Environment( const in IncidentLight incidentLight, const float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); + vec4 r = roughness * c0 + c1; + float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; return specularColor * AB.x + AB.y; -} +} // validated float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { @@ -168,21 +179,29 @@ float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) { float D_BlinnPhong( const in float shininess, const in float dotNH ) { - // factor of 1/PI in distribution term omitted ??? + // factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source + return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); } vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { + // factor of 1/PI in BRDF omitted (normally it is in D_BlinnPhong) as incoming light intensity is scaled up by PI because it is considered a punctual light source + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + + //float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); + //float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); float dotNH = saturate( dot( geometry.normal, halfDir ) ); float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); + float D = D_BlinnPhong( shininess, dotNH ); return F * ( G * D ); -} \ No newline at end of file +} // validated \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 1dc4d06df0d2bb..fd9229ec621516 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -40,6 +40,6 @@ void BlinnPhongMaterial_RE_IndirectLight( const in IncidentLight indirectLight, } -#define Material_RE_DiffuseIndirectLight BlinnPhongMaterial_RE_IndirectLight +#define Material_RE_IndirectDiffuseLight BlinnPhongMaterial_RE_IndirectLight #define Material_LightProbeLOD( material ) (0) From f89f27d0971fb46c0c4fab2556d72b916b2589cf Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 14:21:20 -0400 Subject: [PATCH 51/64] remove unused code (clear coat), oren-nayar, and make envmap work in world space properly while using local space coords. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 59 +------------------ .../shaders/ShaderChunk/lights_pars.glsl | 8 +-- .../lights_physical_pars_fragment.glsl | 3 +- 3 files changed, 7 insertions(+), 63 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 57db0ed93c835d..c055e08d59e19b 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -1,6 +1,5 @@ //#define ENERGY_PRESERVING_MONOCHROME -#define DIELECTRIC_SPECULAR_F0 0.20 float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { @@ -15,20 +14,6 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } -ReflectedLight BRDF_Mix( const in ReflectedLight base, const in ReflectedLight over, const in float weight ) { - return ReflectedLight( - mix( base.diffuse, over.diffuse, weight ), - mix( base.specular, over.specular, weight ) - ); -} - -ReflectedLight BRDF_Add( const in ReflectedLight base, const in ReflectedLight over, const in float weight ) { - return ReflectedLight( - base.diffuse + over.diffuse, - base.specular + over.specular - ); -} - vec3 BRDF_Diffuse_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor ) { // factor of 1/PI in BRDF omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source @@ -37,22 +22,6 @@ vec3 BRDF_Diffuse_Lambert( const in IncidentLight incidentLight, const in Geomet } // validated -// this roughness is a different property than specular roughness used in GGX. -vec3 BRDF_Diffuse_OrenNayar( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor, const in float roughness ) { - - vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir ); - float dotVH = saturate( dot( geometryContext.viewDir, halfDir ) ); - float dotNV = saturate( dot( geometryContext.normal, geometryContext.viewDir ) ); - float dotNL = saturate( dot( geometryContext.normal, incidentLight.direction ) ); - - float m2 = roughness * roughness; - float termA = 1.0 - 0.5 * m2 / (m2 + 0.33); - float Cosri = 2.0 * dotVH - 1.0 - dotNV * dotNL; - float termB = 0.45 * m2 / (m2 + 0.09) * Cosri * ( Cosri >= 0.0 ? min( 1.0, dotNL / dotNV ) : dotNL ); - - return diffuseColor * ( dotNL * termA + termB ); - -} vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { @@ -66,6 +35,7 @@ vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { } // validated + // Microfacet Models for Refraction through Rough Surfaces - equation (34) // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html // alpha is "roughness squared" in Disney’s reparameterization @@ -99,6 +69,7 @@ float D_GGX( in float alpha, in float dotNH ) { } + // GGX Distribution, Schlick Fresnel, GGX-Smith Visibility vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { @@ -123,32 +94,6 @@ vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in Geometric } // validated -// useful for clear coat surfaces, use with Distribution_GGX. -float G_Kelemen( float vDotH ) { - - return 1.0 / ( 4.0 * vDotH * vDotH + 0.0000001 ); - -} - -#define DIELECTRIC_SPECULAR_F0 0.20 - -// this blends the existing reflected light with a clear coat. -vec3 BRDF_Specular_ClearCoat( const in IncidentLight incidentLight, const in GeometricContext geometry, const in float clearCoatWeight, const in float clearCoatRoughness ) { - - vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); - float dotNH = saturate( dot( geometry.normal, halfDir ) ); - float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); - float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); - float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); - - vec3 F = F_Schlick( vec3( DIELECTRIC_SPECULAR_F0 ), dotLH ); - float G = G_Kelemen( dotNV ); - float D = D_GGX( clearCoatRoughness, dotNH ); - - - return F * ( G * D ); - -} // ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile vec3 BRDF_Specular_GGX_Environment( const in IncidentLight incidentLight, const in GeometricContext geometry, vec3 specularColor, float roughness ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 628122126e3acc..205c4713638abe 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -146,15 +146,13 @@ uniform vec3 ambientLightColor; #endif - reflectVec = normalize( transformDirection( reflectVec, viewMatrix ) ); + reflectVec = normalize( inverseTransformDirection( reflectVec, viewMatrix ) ); #ifdef ENVMAP_TYPE_CUBE - #if defined( TEXTURE_CUBE_LOD_EXT ) + #if defined( TEXTURE_CUBE_LOD_EXT ) - float bias = pow( lodLevel, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor) - - vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias ); + vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), lodLevel ); #else diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index 102275574e24c0..cca27f9c09151d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -36,6 +36,7 @@ void PhysicalMaterial_RE_SpecularIndirectLight( const in IncidentLight indirectL } -#define Material_LightProbeLOD( material ) (material.specularRoughness) +// from bhouston - there are other models for this calculation (roughness; not roughnesFactor) +#define Material_LightProbeLOD( material ) (pow( ( material.specularRoughness - 0.5 ) * 2.0, 0.5 ) * 7.0) #define Material_RE_IndirectSpecularLight PhysicalMaterial_RE_SpecularIndirectLight From 89b3dac2dce16c25076e1cc23a0107d7eb56ca13 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 14:23:46 -0400 Subject: [PATCH 52/64] remove energy conserving mode. --- editor/js/Sidebar.Material.js | 23 ------------------- src/materials/MeshPhongMaterial.js | 6 ----- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 3 --- .../ShaderChunk/lights_phong_fragment.glsl | 12 +--------- .../ShaderChunk/lights_physical_fragment.glsl | 10 -------- src/renderers/webgl/WebGLProgram.js | 4 ---- src/renderers/webgl/WebGLPrograms.js | 2 -- 7 files changed, 1 insertion(+), 59 deletions(-) diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index dce8128803ca1e..ba0c983d7d9950 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -163,16 +163,6 @@ Sidebar.Material = function ( editor ) { container.add( materialVertexColorsRow ); - // energy conserving - - var materialEnergyConservingRow = new UI.Panel(); - var materialEnergyConserving = new UI.Checkbox( false ).onChange( update ); - - materialEnergyConservingRow.add( new UI.Text( 'EnergyConserving' ).setWidth( '90px' ) ); - materialEnergyConservingRow.add( materialEnergyConserving ); - - container.add( materialEnergyConservingRow ); - // skinning var materialSkinningRow = new UI.Panel(); @@ -472,12 +462,6 @@ Sidebar.Material = function ( editor ) { } - if ( material.energyConserving !== undefined ) { - - material.energyConserving = materialEnergyConserving.getValue(); - - } - if ( material.map !== undefined ) { var mapEnabled = materialMapEnabled.getValue() === true; @@ -703,7 +687,6 @@ Sidebar.Material = function ( editor ) { 'vertexShader': materialProgramRow, 'vertexColors': materialVertexColorsRow, 'skinning': materialSkinningRow, - 'energyConserving': materialEnergyConservingRow, 'map': materialMapRow, 'alphaMap': materialAlphaMapRow, 'bumpMap': materialBumpMapRow, @@ -787,12 +770,6 @@ Sidebar.Material = function ( editor ) { } - if ( material.energyConserving !== undefined ) { - - materialEnergyConserving.setValue( material.energyConserving ); - - } - if ( material.map !== undefined ) { materialMapEnabled.setValue( material.map !== null ); diff --git a/src/materials/MeshPhongMaterial.js b/src/materials/MeshPhongMaterial.js index cf926c8e8a088e..2940d3a16484ed 100644 --- a/src/materials/MeshPhongMaterial.js +++ b/src/materials/MeshPhongMaterial.js @@ -11,8 +11,6 @@ * * map: new THREE.Texture( ), * - * energyConverving: false - * * lightMap: new THREE.Texture( ), * lightMapIntensity: * @@ -73,8 +71,6 @@ THREE.MeshPhongMaterial = function ( parameters ) { this.map = null; - this.energyConserving = false; - this.lightMap = null; this.lightMapIntensity = 1.0; @@ -137,8 +133,6 @@ THREE.MeshPhongMaterial.prototype.copy = function ( source ) { this.map = source.map; - this.energyConserving = source.energyConserving; - this.lightMap = source.lightMap; this.lightMapIntensity = source.lightMapIntensity; diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index c055e08d59e19b..a9ef2c988a3758 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -1,6 +1,3 @@ -//#define ENERGY_PRESERVING_MONOCHROME - - float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { if ( decayExponent > 0.0 ) { diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl index b8293f053c3244..51b5c12886bef0 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -7,14 +7,4 @@ material.diffuseColor = diffuseColor.rgb; material.diffuseColor = vec3( 0.0 ); -#endif - -#if defined( ENERGY_PRESERVING_RGB ) - - material.diffuseColor *= whiteCompliment( specular ); - -#elif defined( ENERGY_PRESERVING_MONOCHROME ) - - material.diffuseColor *= whiteCompliment( luminance( specular ) ); - -#endif +#endif \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl index 5d6abc35148cbb..49883408aef27e 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl @@ -2,13 +2,3 @@ PhysicalMaterial material; material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); material.specularRoughness = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ] material.specularColor = mix( vec3( 0.04 ) * reflectivity, diffuseColor.rgb, metalnessFactor ); - -#if defined( ENERGY_PRESERVING_RGB ) - - material.diffuseColor *= whiteCompliment( specularColor ); - -#elif defined( ENERGY_PRESERVING_MONOCHROME ) - - material.diffuseColor *= whiteCompliment( luminance( specularColor ) ); - -#endif \ No newline at end of file diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 678ecfc4271a75..f39699c22d00ee 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -252,10 +252,6 @@ THREE.WebGLProgram = ( function () { parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.vertexColors ? '#define USE_COLOR' : '', - parameters.energyConserving ? '#define ENERGY_PRESERVING_MONOCHROME' : '', - - - parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index d5c612f6a726da..211798c66a93d1 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -160,8 +160,6 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { specularMap: !! material.specularMap, alphaMap: !! material.alphaMap, - energyConserving: !! material.energyConserving, - combine: material.combine, vertexColors: material.vertexColors, From ce22ecc930fce8b6a0d6b0a5a0a4f262872a6099 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 15:17:41 -0400 Subject: [PATCH 53/64] perfect backwards compatibility for envmap_fragment for phong. --- .../shaders/ShaderChunk/envmap_fragment.glsl | 6 +- .../ShaderChunk/lights_lambert_vertex.glsl | 74 +++++++++++-------- .../shaders/ShaderChunk/lights_pars.glsl | 2 +- src/renderers/shaders/ShaderLib.js | 7 +- 4 files changed, 50 insertions(+), 39 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 11be9fddda412f..1d125de494f377 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -47,15 +47,15 @@ #ifdef ENVMAP_BLENDING_MULTIPLY - indirectReflectedLight.specular = mix( indirectReflectedLight.specular, indirectReflectedLight.specular * envColor.xyz, specularStrength * reflectivity ); + outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_MIX ) - indirectReflectedLight.specular = mix( indirectReflectedLight.specular, envColor.xyz, specularStrength * reflectivity ); + outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); #elif defined( ENVMAP_BLENDING_ADD ) - indirectReflectedLight.specular += envColor.xyz * specularStrength * reflectivity; + outgoingLight += envColor.xyz * specularStrength * reflectivity; #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 07c686b41f2ec0..7b51ead078ea20 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -3,22 +3,19 @@ vec3 diffuse = vec3( 1.0 ); GeometricContext geometry = GeometricContext( mvPosition.xyz, normalize( transformedNormal ), normalize( -mvPosition.xyz ) ); GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.normal, geometry.viewDir ); -ReflectedLight frontReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); -ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); - #if MAX_POINT_LIGHTS > 0 for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - float dotNL = dot( geometry.normal, directLight.direction ); - frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - float dotNLBack = dot( -geometry.normal, directLight.direction ); - backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif @@ -32,13 +29,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); - float dotNL = dot( geometry.normal, directLight.direction ); - frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - float dotNLBack = dot( -geometry.normal, directLight.direction ); - backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif } @@ -51,13 +48,13 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); - float dotNL = dot( geometry.normal, directLight.direction ); - frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); #ifdef DOUBLE_SIDED - float dotNLBack = dot( -geometry.normal, directLight.direction ); - backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); #endif @@ -65,32 +62,45 @@ ReflectedLight backReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) ); #endif -#if MAX_HEMI_LIGHTS > 0 + { + + IncidentLight frontIndirectLight; + frontIndirectLight.direction = geometry.normal; + frontIndirectLight.color = ambientLightColor; - for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { + #ifdef DOUBLE_SIDED + + IncidentLight backIndirectLight; + backIndirectLight.direction = -geometry.normal; + backIndirectLight.color = ambientLightColor; - IncidentLight indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); + #endif - float dotNL = dot( geometry.normal, directLight.direction ); - frontReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + #if MAX_HEMI_LIGHTS > 0 - #ifdef DOUBLE_SIDED - - indirectLight = getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ); + for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - float dotNLBack = dot( -geometry.normal, directLight.direction ); - backReflectedLight.diffuse += dotNLBack * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + frontIndirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ).color; - #endif - } + #ifdef DOUBLE_SIDED + + backIndirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ).color; -#endif + #endif + + } -vLightFront = frontReflectedLight.diffuse; + #endif -#ifdef DOUBLE_SIDED + float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); + vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( frontIndirectLight, geometry, diffuse ); - vLightBack = backReflectedLight.diffuse; + #ifdef DOUBLE_SIDED + + float backDotNL = saturate( dot( -geometry.normal, backIndirectLight.direction ) ); + vLightBack += backDotNL * backIndirectLight.color * BRDF_Diffuse_Lambert( backIndirectLight, backGeometry, diffuse ); + + #endif -#endif \ No newline at end of file + } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 205c4713638abe..f3873a882fdc2d 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -122,7 +122,7 @@ uniform vec3 ambientLightColor; #endif -#ifdef USE_ENVMAP +#if defined( USE_ENVMAP ) && defined( PHYSICAL ) IncidentLight getSpecularLightProbeIndirectLight( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) { diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 05314b55ed8793..0a2862ad0f5dfe 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -101,14 +101,13 @@ THREE.ShaderLib = { " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), diffuse );", THREE.ShaderChunk[ "aomap_fragment" ], - THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], "indirectReflectedLight.diffuse *= shadowMask;", "vec3 outgoingLight = indirectReflectedLight.diffuse;", + THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", @@ -241,6 +240,8 @@ THREE.ShaderLib = { " #endif", + THREE.ShaderChunk[ "envmap_fragment" ], + THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], @@ -388,7 +389,6 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "lightmap_fragment" ], // modulation - THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "aomap_fragment" ], "vec3 shadowMask = vec3( 1.0 );", @@ -406,6 +406,7 @@ THREE.ShaderLib = { "#endif", + THREE.ShaderChunk[ "envmap_fragment" ], THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ], From f75c05512064f5a9161a1eced9339d0badb7e9e2 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 15:17:49 -0400 Subject: [PATCH 54/64] add lambert variations example. --- .../webgl_materials_lambert_variations.html | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 examples/webgl_materials_lambert_variations.html diff --git a/examples/webgl_materials_lambert_variations.html b/examples/webgl_materials_lambert_variations.html new file mode 100644 index 00000000000000..e8fa39aa944108 --- /dev/null +++ b/examples/webgl_materials_lambert_variations.html @@ -0,0 +1,242 @@ + + + + three.js webgl - materials + + + + + + +
+
three.js - Lambert Material Variantions by Ben Houston.
+ + + + + + + + + + + + + + From d59e16a96edd01ed00faf1b819243eda2dc800f4 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 15:37:53 -0400 Subject: [PATCH 55/64] update basic material to use new indirectReflectedLight structure, add basic_variations. --- .../webgl_materials_basic_variations.html | 247 ++++++++++++++++++ .../webgl_materials_lambert_variations.html | 8 +- src/renderers/shaders/ShaderLib.js | 2 +- 3 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 examples/webgl_materials_basic_variations.html diff --git a/examples/webgl_materials_basic_variations.html b/examples/webgl_materials_basic_variations.html new file mode 100644 index 00000000000000..5b5086acaea860 --- /dev/null +++ b/examples/webgl_materials_basic_variations.html @@ -0,0 +1,247 @@ + + + + three.js webgl - materials + + + + + + +
+
three.js - Basic Material Variantions by Ben Houston.
+ + + + + + + + + + + + + + diff --git a/examples/webgl_materials_lambert_variations.html b/examples/webgl_materials_lambert_variations.html index e8fa39aa944108..a1e7fb99829e8b 100644 --- a/examples/webgl_materials_lambert_variations.html +++ b/examples/webgl_materials_lambert_variations.html @@ -93,13 +93,16 @@ var baseColor = new THREE.Color().setHSL( alpha, 0.5, 0.5 ); + if( alpha >= 0.5 ) { + reflectionCube = null; + } + for( var beta = 0; beta <= 1.0; beta += stepSize ) { var reflectivity = beta; for( var gamma = 0; gamma <= 1.0; gamma += stepSize ) { - // basic monochromatic energy preservation var diffuseColor = baseColor.clone().multiplyScalar( gamma ); var material = new THREE.MeshLambertMaterial( { map: imgTexture, color: diffuseColor, reflectivity: reflectivity, shading: THREE.SmoothShading, envMap: reflectionCube } ) @@ -147,6 +150,9 @@ addLabel( "-diffuse", new THREE.Vector3( 0, 0, -300 ) ); addLabel( "+diffuse", new THREE.Vector3( 0, 0, 300 ) ); + + addLabel( "envMap", new THREE.Vector3( -350, 300, 0 ) ); + addLabel( "no envMap", new THREE.Vector3( 350, 300, 0 ) ); particleLight = new THREE.Mesh( new THREE.SphereBufferGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) ); scene.add( particleLight ); diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 0a2862ad0f5dfe..dd8136edbbbffd 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -98,7 +98,7 @@ THREE.ShaderLib = { THREE.ShaderChunk[ "alphatest_fragment" ], THREE.ShaderChunk[ "specularmap_fragment" ], - " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), diffuse );", + " ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), diffuseColor.rgb );", THREE.ShaderChunk[ "aomap_fragment" ], THREE.ShaderChunk[ "shadowmap_fragment" ], From 2d3f69905f8f426fdc43c1c082cac6b56bd54713 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 16:16:33 -0400 Subject: [PATCH 56/64] fix double application of ambient light. --- src/renderers/shaders/ShaderLib.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index dd8136edbbbffd..6fc01a2d8500d7 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -230,13 +230,13 @@ THREE.ShaderLib = { " #ifdef DOUBLE_SIDED", " if ( gl_FrontFacing )", - " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;", + " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", " else", - " outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask + totalAmbientLight ) + emissive;", + " outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask ) + emissive;", " #else", - " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;", + " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", " #endif", From 181973a280ffd5f3cbf2c607c3bc1ddc8bc82f79 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 16:21:43 -0400 Subject: [PATCH 57/64] Explicitly optimized, rather than theoretically pure. --- .../shaders/ShaderChunk/lights_lambert_vertex.glsl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 7b51ead078ea20..42c5ca0a1a8117 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -93,13 +93,17 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n #endif - float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); - vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( frontIndirectLight, geometry, diffuse ); + //float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); + //vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( frontIndirectLight, geometry, diffuse ); + // the following is equivalent to the above + vLightFront += frontIndirectLight.color; #ifdef DOUBLE_SIDED - float backDotNL = saturate( dot( -geometry.normal, backIndirectLight.direction ) ); - vLightBack += backDotNL * backIndirectLight.color * BRDF_Diffuse_Lambert( backIndirectLight, backGeometry, diffuse ); + //float backDotNL = saturate( dot( -geometry.normal, backIndirectLight.direction ) ); + //vLightBack += backDotNL * backIndirectLight.color * BRDF_Diffuse_Lambert( backIndirectLight, backGeometry, diffuse ); + // the following is equivalent to the above + vLightBack += backIndirectLight.color; #endif From 0cf45b80fb867b1a150ae38b3d10024392f10a9f Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 20:00:13 -0400 Subject: [PATCH 58/64] better description of lights_template. remove double normalize. --- src/renderers/shaders/ShaderChunk/lights_pars.glsl | 2 +- .../shaders/ShaderChunk/lights_template.glsl | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index f3873a882fdc2d..50fe62c515fb64 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -146,7 +146,7 @@ uniform vec3 ambientLightColor; #endif - reflectVec = normalize( inverseTransformDirection( reflectVec, viewMatrix ) ); + reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); #ifdef ENVMAP_TYPE_CUBE diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 5bdb8629167593..168fb6192e289a 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -1,6 +1,17 @@ +// +// This is a template that can be used to light a material, it uses pluggable RenderEquations (RE) +// for specific lighting scenarios. +// // Instructions for use: -// - Ensure that both BRDF_Material_DirectLight and BRDF_Material_Indirect light are defined +// - Ensure that both Material_RE_DirectLight, Material_RE_IndirectDiffuseLight and Material_RE_IndirectSpecularLight are defined +// - If you have defined a Material_RE_IndirectSpecularLight, you need to also provide a Material_LightProbeLOD. // - Create a material parameter that is to be passed as the third parameter to your lighting functions. +// +// TODO: +// - Add area light support. +// - Add sphere light support. +// - Add diffuse light probe (irradiance cubemap) support. +// GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) ); From 5c6fc4916263755436a0c1c7a0fc4436e00c4b9e Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 20:52:44 -0400 Subject: [PATCH 59/64] simplification of BSDFs. --- src/renderers/shaders/ShaderChunk/bsdfs.glsl | 4 +- .../ShaderChunk/lights_lambert_vertex.glsl | 43 ++++++------------- .../shaders/ShaderChunk/lights_pars.glsl | 25 ++--------- .../lights_phong_pars_fragment.glsl | 11 +++-- .../lights_physical_pars_fragment.glsl | 14 +++--- .../shaders/ShaderChunk/lights_template.glsl | 14 +++--- 6 files changed, 38 insertions(+), 73 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index a9ef2c988a3758..ef4f7aeebde4ea 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -11,7 +11,7 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec } -vec3 BRDF_Diffuse_Lambert( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 diffuseColor ) { +vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { // factor of 1/PI in BRDF omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source @@ -93,7 +93,7 @@ vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in Geometric // ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile -vec3 BRDF_Specular_GGX_Environment( const in IncidentLight incidentLight, const in GeometricContext geometry, vec3 specularColor, float roughness ) { +vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, vec3 specularColor, float roughness ) { float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 42c5ca0a1a8117..84b1ece1614bb4 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -10,12 +10,12 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #ifdef DOUBLE_SIDED float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #endif @@ -30,12 +30,12 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #ifdef DOUBLE_SIDED float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #endif } @@ -49,12 +49,12 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, diffuse ); + vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #ifdef DOUBLE_SIDED float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, backGeometry, diffuse ); + vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); #endif @@ -63,16 +63,15 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n #endif { - - IncidentLight frontIndirectLight; - frontIndirectLight.direction = geometry.normal; - frontIndirectLight.color = ambientLightColor; + // dotNL is always one, and diffuseColor is vec3(1.0), thus the result is equivalent to summing indirectDiffuse lights + //float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); + //vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( diffuse ); + + vLightFront += ambientLightColor; #ifdef DOUBLE_SIDED - IncidentLight backIndirectLight; - backIndirectLight.direction = -geometry.normal; - backIndirectLight.color = ambientLightColor; + vec3 vLightBack = ambientLightColor; #endif @@ -80,12 +79,12 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - frontIndirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ).color; + vLightFront += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); #ifdef DOUBLE_SIDED - backIndirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ).color; + vLightBack += getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ); #endif @@ -93,18 +92,4 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n #endif - //float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); - //vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( frontIndirectLight, geometry, diffuse ); - // the following is equivalent to the above - vLightFront += frontIndirectLight.color; - - #ifdef DOUBLE_SIDED - - //float backDotNL = saturate( dot( -geometry.normal, backIndirectLight.direction ) ); - //vLightBack += backDotNL * backIndirectLight.color * BRDF_Diffuse_Lambert( backIndirectLight, backGeometry, diffuse ); - // the following is equivalent to the above - vLightBack += backIndirectLight.color; - - #endif - } \ No newline at end of file diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 50fe62c515fb64..29949ac66dc123 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -86,15 +86,6 @@ uniform vec3 ambientLightColor; #endif - IncidentLight getAmbientIndirectLight( const in vec3 ambientLightColor, const in GeometricContext geometry ) { - - IncidentLight indirectLight; - - indirectLight.color = ambientLightColor; - indirectLight.direction = geometry.normal; - - return indirectLight; - } #if MAX_HEMI_LIGHTS > 0 @@ -106,17 +97,13 @@ uniform vec3 ambientLightColor; uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - IncidentLight getHemisphereIndirectLight( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { + vec3 getHemisphereIndirectLightColor( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { - IncidentLight indirectLight; - float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - indirectLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - indirectLight.direction = geometry.normal; + return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); - return indirectLight; } #endif @@ -124,7 +111,7 @@ uniform vec3 ambientLightColor; #if defined( USE_ENVMAP ) && defined( PHYSICAL ) - IncidentLight getSpecularLightProbeIndirectLight( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) { + vec3 getSpecularLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) { #ifdef ENVMAP_MODE_REFLECTION @@ -176,11 +163,7 @@ uniform vec3 ambientLightColor; envMapColor.rgb = inputToLinear( envMapColor.rgb ); - IncidentLight indirectLight; - indirectLight.color = envMapColor.rgb * reflectivity; - indirectLight.direction = geometry.normal; - - return indirectLight; + return envMapColor.rgb * reflectivity; } diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index fd9229ec621516..f3e18c4ab86a03 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -23,8 +23,7 @@ void BlinnPhongMaterial_RE_DirectLight( const in IncidentLight directLight, cons float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, material.diffuseColor ); - //directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_OrenNayar( directLight, geometry, material.diffuseColor, 0.5 ); + directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor ); directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ); @@ -32,14 +31,14 @@ void BlinnPhongMaterial_RE_DirectLight( const in IncidentLight directLight, cons #define Material_RE_DirectLight BlinnPhongMaterial_RE_DirectLight -void BlinnPhongMaterial_RE_IndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { +void BlinnPhongMaterial_RE_IndirectDiffuseLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) { - float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); + //float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); not required because result is always 1.0 - indirectReflectedLight.diffuse += dotNL * indirectLight.color * BRDF_Diffuse_Lambert( indirectLight, geometry, material.diffuseColor ); + indirectReflectedLight.diffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor ); } -#define Material_RE_IndirectDiffuseLight BlinnPhongMaterial_RE_IndirectLight +#define Material_RE_IndirectDiffuseLight BlinnPhongMaterial_RE_IndirectDiffuseLight #define Material_LightProbeLOD( material ) (0) diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index cca27f9c09151d..aec3d056f4ffb7 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -10,29 +10,29 @@ void PhysicalMaterial_RE_DirectLight( const in IncidentLight directLight, const float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( directLight, geometry, material.diffuseColor ); + directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor ); directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); } #define Material_RE_DirectLight PhysicalMaterial_RE_DirectLight -void PhysicalMaterial_RE_DiffuseIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { +void PhysicalMaterial_RE_DiffuseIndirectLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { - float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); + //float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); not required because result is always 1.0 - indirectReflectedLight.diffuse += dotNL * indirectLight.color * BRDF_Diffuse_Lambert( indirectLight, geometry, material.diffuseColor ); + indirectReflectedLight.diffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor ); } #define Material_RE_IndirectDiffuseLight PhysicalMaterial_RE_DiffuseIndirectLight -void PhysicalMaterial_RE_SpecularIndirectLight( const in IncidentLight indirectLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { +void PhysicalMaterial_RE_SpecularIndirectLight( const in vec3 indirectSpecularColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) { - float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); + //float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) ); not required because result is always 1.0 - indirectReflectedLight.specular += dotNL * indirectLight.color * BRDF_Specular_GGX_Environment( indirectLight, geometry, material.specularColor, material.specularRoughness ); + indirectReflectedLight.specular += indirectSpecularColor * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); } diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 168fb6192e289a..5b522a6f9256f1 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -55,13 +55,11 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal { - IncidentLight indirectLight; - indirectLight.direction = geometry.normal; - indirectLight.color = ambientLightColor; + vec3 indirectDiffuseColor = ambientLightColor; #ifdef USE_LIGHTMAP - indirectLight.color += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; + indirectDiffuseColor += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; #endif @@ -69,13 +67,13 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - indirectLight.color += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ).color; + indirectDiffuseColor += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry ); } #endif - Material_RE_IndirectDiffuseLight( indirectLight, geometry, material, indirectReflectedLight ); + Material_RE_IndirectDiffuseLight( indirectDiffuseColor, geometry, material, indirectReflectedLight ); } @@ -85,9 +83,9 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal { - IncidentLight indirectLight = getSpecularLightProbeIndirectLight( /*specularLightProbe,*/ geometry, Material_LightProbeLOD( material ) ); + vec3 indirectSpecularColor = getSpecularLightProbeIndirectLightColor( /*specularLightProbe,*/ geometry, Material_LightProbeLOD( material ) ); - Material_RE_IndirectSpecularLight( indirectLight, geometry, material, indirectReflectedLight ); + Material_RE_IndirectSpecularLight( indirectSpecularColor, geometry, material, indirectReflectedLight ); } From 5ad4d109f09bbe7f1abb8d3b5046dcf91d750776 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 20:59:34 -0400 Subject: [PATCH 60/64] forgotten function name update. --- src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 84b1ece1614bb4..fc7c8598fbdd80 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -79,12 +79,11 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vLightFront += getHemisphereIndirectLight( hemisphereLights[ i ], geometry ); - + vLightFront += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry ); #ifdef DOUBLE_SIDED - vLightBack += getHemisphereIndirectLight( hemisphereLights[ i ], backGeometry ); + vLightBack += getHemisphereIndirectLightColor( hemisphereLights[ i ], backGeometry ); #endif From d1499b2d533421a758d14d3d40ac11aa2ed6ad58 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 21:07:24 -0400 Subject: [PATCH 61/64] more straightforward optimizations. --- .../ShaderChunk/lights_lambert_vertex.glsl | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index fc7c8598fbdd80..fe7e9b092f05fd 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -9,13 +9,14 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); - float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + float dotNL = dot( geometry.normal, directLight.direction ); + vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; #ifdef DOUBLE_SIDED - float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vLightBack += saturate( -dotNL ) * directLightColor_Diffuse; #endif @@ -29,13 +30,14 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); - float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + float dotNL = dot( geometry.normal, directLight.direction ); + vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; #ifdef DOUBLE_SIDED - float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vLightBack += saturate( -dotNL ) * directLightColor_Diffuse; #endif } @@ -48,13 +50,14 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); - float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - vLightFront += dotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + float dotNL = dot( geometry.normal, directLight.direction ); + vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; #ifdef DOUBLE_SIDED - float backDotNL = saturate( dot( -geometry.normal, directLight.direction ) ); - vLightBack += backDotNL * directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vLightBack += saturate( -dotNL ) * directLightColor_Diffuse; #endif From 752fc8bb189b3f1afcdc4668707cb3368a96c782 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 21:08:50 -0400 Subject: [PATCH 62/64] bug fix. --- src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index fe7e9b092f05fd..1b4b80a163b691 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -74,7 +74,7 @@ GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.n #ifdef DOUBLE_SIDED - vec3 vLightBack = ambientLightColor; + vLightBack += ambientLightColor; #endif From 082a19d5b8e2720714b4c3a1f02841a4fa3caf69 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 21:16:54 -0400 Subject: [PATCH 63/64] add lambert variations now varies double sided. --- examples/webgl_materials_lambert_variations.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/webgl_materials_lambert_variations.html b/examples/webgl_materials_lambert_variations.html index a1e7fb99829e8b..89d8d9e6e152e2 100644 --- a/examples/webgl_materials_lambert_variations.html +++ b/examples/webgl_materials_lambert_variations.html @@ -88,8 +88,7 @@ var geometry = new THREE.SphereBufferGeometry( sphereRadius, 32, 16 ); - - for( var alpha = 0; alpha <= 1.0; alpha += stepSize ) { + for( var alpha = 0, alphaIndex = 0; alpha <= 1.0; alpha += stepSize, alphaIndex ++ ) { var baseColor = new THREE.Color().setHSL( alpha, 0.5, 0.5 ); @@ -97,15 +96,21 @@ reflectionCube = null; } - for( var beta = 0; beta <= 1.0; beta += stepSize ) { + for( var beta = 0, betaIndex = 0; beta <= 1.0; beta += stepSize, betaIndex ++ ) { var reflectivity = beta; + var side = THREE.FrontSide; + if( ( betaIndex % 2 ) === 0 ) { + side = THREE.DoubleSide; + } + for( var gamma = 0; gamma <= 1.0; gamma += stepSize ) { var diffuseColor = baseColor.clone().multiplyScalar( gamma ); - var material = new THREE.MeshLambertMaterial( { map: imgTexture, color: diffuseColor, reflectivity: reflectivity, shading: THREE.SmoothShading, envMap: reflectionCube } ) + var material = new THREE.MeshLambertMaterial( { map: imgTexture, color: diffuseColor, + reflectivity: reflectivity, envMap: reflectionCube, side: side } ) var mesh = new THREE.Mesh( geometry, material ); From 6737d106ff4849ae26fb5dac3e99cc0396b4dab5 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 21 Oct 2015 21:25:24 -0400 Subject: [PATCH 64/64] cleanup. --- src/renderers/shaders/ShaderChunk/lights_pars.glsl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index 29949ac66dc123..67abcf6127d239 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -37,10 +37,8 @@ uniform vec3 ambientLightColor; IncidentLight getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry ) { IncidentLight directLight; - - vec3 lightPosition = pointLight.position; - vec3 lVector = lightPosition - geometry.position; + vec3 lVector = pointLight.position - geometry.position; directLight.direction = normalize( lVector ); directLight.color = pointLight.color; @@ -70,9 +68,7 @@ uniform vec3 ambientLightColor; IncidentLight directLight; - vec3 lightPosition = spotLight.position; - - vec3 lVector = lightPosition - geometry.position; + vec3 lVector = spotLight.position - geometry.position; directLight.direction = normalize( lVector ); float spotEffect = dot( spotLight.direction, directLight.direction );