Procházet zdrojové kódy

added irradiance power and fixed specular reflection

ncannasse před 7 roky
rodič
revize
a356b62a47

+ 2 - 0
h3d/scene/pbr/Irradiance.hx

@@ -183,6 +183,8 @@ class Irradiance  {
 	public var diffuse : h3d.mat.Texture;
 	public var specular : h3d.mat.Texture;
 
+	public var power : Float = 1.;
+
 	public function new(envMap) {
 		this.envMap = envMap;
 		#if (js || flash)

+ 2 - 0
h3d/scene/pbr/Renderer.hx

@@ -85,7 +85,9 @@ class Renderer extends h3d.scene.Renderer {
 		pbrProps.pbrTex = pbr;
 		pbrProps.cameraInverseViewProj = ctx.camera.getInverseViewProj();
 
+		pbrDirect.cameraPosition.load(ctx.camera.pos);
 		pbrOut.shader.cameraPosition.load(ctx.camera.pos);
+		pbrOut.shader.irrPower = irrad.power;
 		pbrOut.shader.irrLut = irrad.lut;
 		pbrOut.shader.irrDiffuse = irrad.diffuse;
 		pbrOut.shader.irrSpecular = irrad.specular;

+ 6 - 3
h3d/shader/pbr/Lighting.hx

@@ -8,6 +8,7 @@ class Indirect extends PropsDefinition {
 		@param var irrDiffuse : SamplerCube;
 		@param var irrSpecular : SamplerCube;
 		@param var irrSpecularLevels : Float;
+		@param var irrPower : Float;
 
 		function fragment() {
 			var diffuse = irrDiffuse.get(normal).rgb.pow(vec3(2.2)) * albedo;
@@ -19,7 +20,7 @@ class Indirect extends PropsDefinition {
 				Usually indirect diffuse is multiplied by occlusion, but since our occlusion mosly
 				comes from shadow map, we want to keep the diffuse term for colored shadows here.
 			*/
-			var indirect = diffuse + specular;
+			var indirect = (diffuse + specular) * irrPower;
 			pixelColor.rgb += indirect;
 		}
 
@@ -57,11 +58,13 @@ class Direct extends PropsDefinition {
 				// 		f(l,v) = D(h).F(v,h).G(l,v,h) / 4(n.l)(n.v)
 
 				// formulas below from 2013 Siggraph "Real Shading in UE4"
-				var alpha = roughness.pow(2);
+				var alpha = roughness * roughness;
 
 				// D = normal distribution fonction
 				// GGX (Trowbridge-Reitz) "Disney"
-				var D = alpha.pow(2) / (PI * ( NdH.pow(2) * (alpha.pow(2) - 1.) + 1).pow(2));
+				var alpha2 = alpha * alpha;
+				var denom = NdH * NdH * (alpha2 - 1.) + 1;
+				var D = alpha2 / (PI * denom * denom);
 
 				// F = fresnel term
 				// Schlick approx

+ 2 - 1
h3d/shader/pbr/PropsDefinition.hx

@@ -27,7 +27,8 @@ class PropsDefinition extends hxsl.Shader {
 		}
 
 		function calcG(v:Vec3) : Float {
-			var k = (roughness + 1).pow(2) / 8;// (roughness * roughness) / 2;
+			var k = (roughness + 1);
+			k *= k;
 			return NdV / (NdV * (1 - k) + k);
 		}
 

+ 4 - 1
h3d/shader/pbr/PropsImport.hx

@@ -32,7 +32,10 @@ class PropsImport extends hxsl.Shader {
 			roughness = pbr.g;
 			occlusion = pbr.b;
 
-			specularColor = metalness < 0.3 ? vec3(metalness) : albedo;
+			// specular is calculated in two ways:
+			//    - for metalic surfaces, we use the albedo for reflection
+			//    - for other surfaces, we use the glossiness as a gray input value
+			specularColor = metalness < 0.3 ? vec3(1 - roughness) : albedo;
 
 			// this is the original object transformed position, not our current drawing object one
 			var uv2 = (uv - 0.5) * vec2(2, -2);