Sfoglia il codice sorgente

Image based specular now functional

BearishSun 8 anni fa
parent
commit
1d3c1dce6c

+ 2 - 21
Data/Raw/Engine/Includes/ReflectionCubemapSampling.bslinc

@@ -192,24 +192,6 @@ Technique : base("ReflectionCubemapSampling") =
 				#endif
 			}
 			
-			half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV )
-			{
-				// [ Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II" ]
-				// Adaptation to fit our G term.
-				const half4 c0 = { -1, -0.0275, -0.572, 0.022 };
-				const half4 c1 = { 1, 0.0425, 1.04, -0.04 };
-				half4 r = Roughness * c0 + c1;
-				half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
-				half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw;
-
-				// Anything less than 2% is physically impossible and is instead considered to be shadowing
-				// In ES2 this is skipped for performance as the impact can be small
-				// Note: this is needed for the 'specular' show flag to work, since it uses a SpecularColor of 0
-				AB.y *= saturate( 50.0 * SpecularColor.g );
-
-				return SpecularColor * AB.x + AB.y;
-			}			
-			
 			float3 getImageBasedSpecular(float3 worldPos, float3 V, SurfaceData surfaceData)
 			{
 				// See C++ code for generation of gPreintegratedEnvBRDF to see why this code works as is
@@ -223,10 +205,9 @@ Technique : base("ReflectionCubemapSampling") =
 				float3 R = 2 * dot(V, N) * N - V;
 				float3 radiance = gatherReflectionRadiance(worldPos, R, surfaceData.roughness, 0, 0);
 				
-				//float2 envBRDF = gPreintegratedEnvBRDF.SampleLevel(gPreintegratedEnvBRDFSamp, float2(NoV, surfaceData.roughness), 0).rg;
+				float2 envBRDF = gPreintegratedEnvBRDF.SampleLevel(gPreintegratedEnvBRDFSamp, float2(NoV, surfaceData.roughness), 0).rg;
 				
-				//return radiance * (specularColor * envBRDF.x + envBRDF.y);
-				return radiance * EnvBRDFApprox(specularColor, surfaceData.roughness, NoV);
+				return radiance * (specularColor * envBRDF.x + envBRDF.y);
 			}		
 		};
 	};

+ 1 - 1
Source/BansheeEngine/Source/BsReflectionProbes.cpp

@@ -63,7 +63,7 @@ namespace bs { namespace ct
 		float width = (float)source->getProperties().getWidth();
 		float height = (float)source->getProperties().getHeight();
 
-		// First part of the equation for determining mip level for sample from.
+		// First part of the equation for determining mip level to sample from.
 		// See http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
 		float mipFactor = 0.5f * std::log2(width * height / NUM_SAMPLES);
 		gReflectionCubeImportanceSampleParamDef.gPrecomputedMipFactor.set(mParamBuffer, mipFactor);

+ 13 - 7
Source/RenderBeast/Source/BsLightRendering.cpp

@@ -267,7 +267,7 @@ namespace bs { namespace ct
 	{
 		// See GGXImportanceSample.nb for derivation (essentially, take base GGX, normalize it, generate PDF, split PDF into
 		// marginal probability for theta and conditional probability for phi. Plug those into the CDF, invert it.)				
-		cosTheta = sqrt((1.0f - e0) / (1.0f + (roughness4 - 1.0f) * e1));
+		cosTheta = sqrt((1.0f - e0) / (1.0f + (roughness4 - 1.0f) * e0));
 		phi = 2.0f * Math::PI * e1;
 	}
 
@@ -330,10 +330,10 @@ namespace bs { namespace ct
 					float NoL = std::max(L.z, 0.0f); // N assumed (0, 0, 1)
 					float NoH = std::max(H.z, 0.0f); // N assumed (0, 0, 1)
 
-														// Set second part of the split sum integral is split into two parts:
-														//   F0*I[G * (1 - (1 - v.h)^5) * cos(theta)] + I[G * (1 - v.h)^5 * cos(theta)] (F0 * scale + bias)
+					// Set second part of the split sum integral is split into two parts:
+					//   F0*I[G * (1 - (1 - v.h)^5) * cos(theta)] + I[G * (1 - v.h)^5 * cos(theta)] (F0 * scale + bias)
 
-														// We calculate the fresnel scale (1 - (1 - v.h)^5) and bias ((1 - v.h)^5) parts
+					// We calculate the fresnel scale (1 - (1 - v.h)^5) and bias ((1 - v.h)^5) parts
 					float fc = pow(1.0f - VoH, 5.0f);
 					float fresnelScale = 1.0f - fc;
 					float fresnelOffset = fc;
@@ -341,11 +341,17 @@ namespace bs { namespace ct
 					// We calculate the G part
 					float G = calcMicrofacetShadowingSmithGGX(m2, NoV, NoL);
 
-					// Note: PDF?
+					// When we factor out G and F, then divide D by PDF, this is what's left
+					//float pdfFactor = 1.0f / NoH;
+
+					// Note: This is based on PDF: D * NoH / (4 * VoH), but I'm not sure where does the (4 * VoH) factor
+					// come from. I'm keeping it since it seems to look better.
+					float pdfFactor = 4.0f * VoH / NoH;
+
 					if (NoL > 0.0f)
 					{
-						scale += NoL * G * fresnelScale;
-						offset += NoL * G * fresnelOffset;
+						scale += NoL * pdfFactor * G * fresnelScale;
+						offset += NoL * pdfFactor * G * fresnelOffset;
 					}
 				}