Browse Source

added irradiance power and fixed specular reflection

ncannasse 7 years ago
parent
commit
a356b62a47

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

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

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

@@ -85,7 +85,9 @@ class Renderer extends h3d.scene.Renderer {
 		pbrProps.pbrTex = pbr;
 		pbrProps.pbrTex = pbr;
 		pbrProps.cameraInverseViewProj = ctx.camera.getInverseViewProj();
 		pbrProps.cameraInverseViewProj = ctx.camera.getInverseViewProj();
 
 
+		pbrDirect.cameraPosition.load(ctx.camera.pos);
 		pbrOut.shader.cameraPosition.load(ctx.camera.pos);
 		pbrOut.shader.cameraPosition.load(ctx.camera.pos);
+		pbrOut.shader.irrPower = irrad.power;
 		pbrOut.shader.irrLut = irrad.lut;
 		pbrOut.shader.irrLut = irrad.lut;
 		pbrOut.shader.irrDiffuse = irrad.diffuse;
 		pbrOut.shader.irrDiffuse = irrad.diffuse;
 		pbrOut.shader.irrSpecular = irrad.specular;
 		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 irrDiffuse : SamplerCube;
 		@param var irrSpecular : SamplerCube;
 		@param var irrSpecular : SamplerCube;
 		@param var irrSpecularLevels : Float;
 		@param var irrSpecularLevels : Float;
+		@param var irrPower : Float;
 
 
 		function fragment() {
 		function fragment() {
 			var diffuse = irrDiffuse.get(normal).rgb.pow(vec3(2.2)) * albedo;
 			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
 				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.
 				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;
 			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)
 				// 		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"
 				// formulas below from 2013 Siggraph "Real Shading in UE4"
-				var alpha = roughness.pow(2);
+				var alpha = roughness * roughness;
 
 
 				// D = normal distribution fonction
 				// D = normal distribution fonction
 				// GGX (Trowbridge-Reitz) "Disney"
 				// 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
 				// F = fresnel term
 				// Schlick approx
 				// Schlick approx

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

@@ -27,7 +27,8 @@ class PropsDefinition extends hxsl.Shader {
 		}
 		}
 
 
 		function calcG(v:Vec3) : Float {
 		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);
 			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;
 			roughness = pbr.g;
 			occlusion = pbr.b;
 			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
 			// this is the original object transformed position, not our current drawing object one
 			var uv2 = (uv - 0.5) * vec2(2, -2);
 			var uv2 = (uv - 0.5) * vec2(2, -2);