Skip to content

Commit

Permalink
Merge pull request #7414 from bhouston/cosine_envMap_lod
Browse files Browse the repository at this point in the history
Cosine-based specular env map LOD selection
  • Loading branch information
mrdoob committed Oct 30, 2015
2 parents 0e632df + 6e3c2e8 commit 7939105
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 12 deletions.
17 changes: 11 additions & 6 deletions src/renderers/shaders/ShaderChunk/bsdfs.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {
float calcLightAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {

if ( decayExponent > 0.0 ) {

Expand Down Expand Up @@ -36,7 +36,7 @@ vec3 F_Schlick( const in vec3 specularColor, 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_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {

// geometry term = G(l)⋅G(v) / 4(n⋅l)(n⋅v)

Expand All @@ -54,7 +54,7 @@ float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) {
// 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 ) {
float D_GGX( const in float alpha, const 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

Expand Down Expand Up @@ -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 GeometricContext geometry, vec3 specularColor, float roughness ) {
vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );

Expand All @@ -112,7 +112,7 @@ vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, vec3 spe
} // validated


float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) {
float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) {

// geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)
return 0.25;
Expand Down Expand Up @@ -146,4 +146,9 @@ vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in Ge

return F * ( G * D );

} // validated
} // validated

// source: http://simonstechblog.blogspot.ca/2011/12/microfacet-brdf.html
float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {
return ( 2.0 / square( ggxRoughness + 0.0001 ) - 2.0 );
}
1 change: 1 addition & 0 deletions src/renderers/shaders/ShaderChunk/common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define saturate(a) clamp( a, 0.0, 1.0 )
#define whiteCompliment(a) ( 1.0 - saturate( a ) )

float square( const in float x ) { return x*x; }
float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }


Expand Down
24 changes: 21 additions & 3 deletions src/renderers/shaders/ShaderChunk/lights_pars.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,21 @@ uniform vec3 ambientLightColor;

#if defined( USE_ENVMAP ) && defined( PHYSICAL )

vec3 getSpecularLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) {
// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {

//float envMapWidth = pow( 2.0, maxMIPLevelScalar );
//float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( square( blinnShininessExponent ) + 1.0 );

float maxMIPLevelScalar = float( maxMIPLevel );
float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( square( blinnShininessExponent ) + 1.0 );

// clamp to allowable LOD ranges.
return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );

}

vec3 getSpecularLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {

#ifdef ENVMAP_MODE_REFLECTION

Expand All @@ -133,15 +147,19 @@ uniform vec3 ambientLightColor;

#ifdef ENVMAP_TYPE_CUBE

vec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );

#if defined( TEXTURE_CUBE_LOD_EXT )

vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), lodLevel );
float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );

#else

vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
vec4 envMapColor = textureCube( envMap, queryReflectVec );

#endif


#elif defined( ENVMAP_TYPE_EQUIREC )

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ void PhysicalMaterial_RE_SpecularIndirectLight( const in vec3 indirectSpecularCo

}

// 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_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )

#define Material_RE_IndirectSpecularLight PhysicalMaterial_RE_SpecularIndirectLight
3 changes: 2 additions & 1 deletion src/renderers/shaders/ShaderChunk/lights_template.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal

{

vec3 indirectSpecularColor = getSpecularLightProbeIndirectLightColor( /*specularLightProbe,*/ geometry, Material_LightProbeLOD( material ) );
// TODO, replace 8 with the real maxMIPLevel
vec3 indirectSpecularColor = getSpecularLightProbeIndirectLightColor( /*specularLightProbe,*/ geometry, Material_BlinnShininessExponent( material ), 8 );

Material_RE_IndirectSpecularLight( indirectSpecularColor, geometry, material, reflectedLight );

Expand Down

0 comments on commit 7939105

Please sign in to comment.