浏览代码

Merge pull request #18118 from Mugen87/dev29

Examples: Fix webgl_materials_envmaps_parallax.
Mr.doob 5 年之前
父节点
当前提交
c3af2f2082
共有 1 个文件被更改,包括 43 次插入30 次删除
  1. 43 30
      examples/webgl_materials_envmaps_parallax.html

+ 43 - 30
examples/webgl_materials_envmaps_parallax.html

@@ -72,29 +72,33 @@
 					uniform float refractionRatio;
 				#endif
 
-				vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {
+				vec3 getLightProbeIndirectIrradiance( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in int maxMIPLevel ) {
+
 					vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );
+
 					#ifdef ENVMAP_TYPE_CUBE
 
-						vec3 worldNormalFinal = worldNormal;
+						#ifdef BOX_PROJECTED_ENV_MAP
 
-					#ifdef BOX_PROJECTED_ENV_MAP
+							worldNormal = parallaxCorrectNormal( worldNormal, cubeMapSize, cubeMapPos );
 
-						worldNormalFinal = parallaxCorrectNormal( worldNormal, cubeMapSize, cubeMapPos );
+						#endif
 
-					#endif
+						vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
 
-					vec3 queryVec = vec3( flipEnvMap * worldNormalFinal.x, worldNormalFinal.yz );
+						// TODO: replace with properly filtered cubemaps and access the irradiance LOD level, be it the last LOD level
+						// of a specular cubemap, or just the default level of a specially created irradiance cubemap.
 
-					#ifdef TEXTURE_LOD_EXT
+						#ifdef TEXTURE_LOD_EXT
 
-						vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );
+							vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );
 
-					#else
+						#else
 
-						vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
+							// force the bias high to get the last LOD level as it is the most blurred.
+							vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
 
-					#endif
+						#endif
 
 						envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
 
@@ -110,20 +114,31 @@
 					#endif
 
 					return PI * envMapColor.rgb * envMapIntensity;
+
 				}
 
-				float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {
+				// Trowbridge-Reitz distribution to Mip level, following the logic of http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
+				float getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {
+
 					float maxMIPLevelScalar = float( maxMIPLevel );
-					float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
+
+					float sigma = PI * roughness * roughness / ( 1.0 + roughness );
+					float desiredMIPLevel = maxMIPLevelScalar + log2( sigma );
+
+					// clamp to allowable LOD ranges.
 					return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
+
 				}
 
-				vec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float blinnShininessExponent, const in int maxMIPLevel ) {
+				vec3 getLightProbeIndirectRadiance( /*const in SpecularLightProbe specularLightProbe,*/ const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {
 
 					#ifdef ENVMAP_MODE_REFLECTION
 
 						vec3 reflectVec = reflect( -viewDir, normal );
 
+						// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
+						reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );
+
 					#else
 
 						vec3 reflectVec = refract( -viewDir, normal, refractionRatio );
@@ -131,36 +146,33 @@
 					#endif
 
 					reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
-					float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
-
-					#ifdef ENVMAP_TYPE_CUBE
-
-						vec3 reflectVecFinal = reflectVec;
 
-					#ifdef BOX_PROJECTED_ENV_MAP
+					float specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );
 
-					 reflectVecFinal = parallaxCorrectNormal( reflectVec, cubeMapSize, cubeMapPos );
+					#ifdef ENVMAP_TYPE_CUBE
 
-					#endif
+						#ifdef BOX_PROJECTED_ENV_MAP
+							reflectVec = parallaxCorrectNormal( reflectVec, cubeMapSize, cubeMapPos );
+						#endif
 
-					vec3 queryReflectVec = vec3( flipEnvMap * reflectVecFinal.x, reflectVecFinal.yz );
+						vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
 
-					#ifdef TEXTURE_LOD_EXT
+						#ifdef TEXTURE_LOD_EXT
 
-						vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );
+							vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );
 
-					#else
+						#else
 
-						vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
+							vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
 
-					#endif
+						#endif
 
-					envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
+						envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
 
 					#elif defined( ENVMAP_TYPE_CUBE_UV )
 
 						vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
-						vec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));
+						vec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );
 
 					#elif defined( ENVMAP_TYPE_EQUIREC )
 
@@ -179,6 +191,7 @@
 						#endif
 
 						envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
+
 					#elif defined( ENVMAP_TYPE_SPHERE )
 
 						vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );