Pārlūkot izejas kodu

Merge pull request #1595 from bghgary/metallic-roughness-scalar-support

Add metallic/roughness scalar value support to pbr materials
David Catuhe 8 gadi atpakaļ
vecāks
revīzija
7e38fef86b
2 mainītis faili ar 52 papildinājumiem un 20 dzēšanām
  1. 33 6
      src/Materials/babylon.pbrMaterial.ts
  2. 19 14
      src/Shaders/pbr.fragment.fx

+ 33 - 6
src/Materials/babylon.pbrMaterial.ts

@@ -64,8 +64,9 @@
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPY = false;
         public SHADOWFULLFLOAT = false;
-        
+
         public METALLICWORKFLOW = false;
+        public METALLICROUGHNESSMAP = false;
         public METALLICROUGHNESSGSTOREINALPHA = false;
         public METALLICROUGHNESSGSTOREINGREEN = false;
 
@@ -292,6 +293,20 @@
         @serializeAsTexture()
         public metallicTexture: BaseTexture;
 
+        /**
+         * Specifies the metallic scalar of the metallic/roughness workflow.
+         * Can also be used to scale the metalness values of the metallic texture.
+         */
+        @serialize()
+        public metallic: number;
+
+        /**
+         * Specifies the roughness scalar of the metallic/roughness workflow.
+         * Can also be used to scale the roughness values of the metallic texture.
+         */
+        @serialize()
+        public roughness: number;
+
         @serializeAsTexture()
         public bumpTexture: BaseTexture;
 
@@ -749,13 +764,14 @@
                     }
                 }
 
-                if (StandardMaterial.SpecularTextureEnabled) {                        
+                if (StandardMaterial.SpecularTextureEnabled) {
                     if (this.metallicTexture) {
                         if (!this.metallicTexture.isReady()) {
                             return false;
                         } else {
                             needUVs = true;
                             this._defines.METALLICWORKFLOW = true;
+                            this._defines.METALLICROUGHNESSMAP = true;
                             this._defines.METALLICROUGHNESSGSTOREINALPHA = this.useRoughnessFromMetallicTextureAlpha;
                             this._defines.METALLICROUGHNESSGSTOREINGREEN = !this.useRoughnessFromMetallicTextureAlpha && this.useRoughnessFromMetallicTextureGreen;
                         }
@@ -917,6 +933,10 @@
                 this._defines.RADIANCEOVERALPHA = true;
             }
 
+            if (this.metallic !== undefined || this.roughness !== undefined) {
+                this._defines.METALLICWORKFLOW = true;
+            }
+
             // Attribs
             if (mesh) {
                 if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
@@ -1268,13 +1288,20 @@
 
                 // Colors
                 this._myScene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
-                
-                // GAMMA CORRECTION.
-                this.convertColorToLinearSpaceToRef(this.reflectivityColor, PBRMaterial._scaledReflectivity);
+
+                if (this._defines.METALLICWORKFLOW) {
+                    PBRMaterial._scaledReflectivity.r = this.metallic === undefined ? 1 : this.metallic;
+                    PBRMaterial._scaledReflectivity.g = this.roughness === undefined ? 1 : this.roughness;
+                    this._effect.setColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, 0);
+                }
+                else {
+                    // GAMMA CORRECTION.
+                    this.convertColorToLinearSpaceToRef(this.reflectivityColor, PBRMaterial._scaledReflectivity);
+                    this._effect.setColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, this.microSurface);
+                }
 
                 this._effect.setVector3("vEyePosition", this._myScene._mirroredCameraPosition ? this._myScene._mirroredCameraPosition : this._myScene.activeCamera.position);
                 this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
-                this._effect.setColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, this.microSurface);
 
                 // GAMMA CORRECTION.
                 this.convertColorToLinearSpaceToRef(this.emissiveColor, PBRMaterial._scaledEmissive);

+ 19 - 14
src/Shaders/pbr.fragment.fx

@@ -269,35 +269,40 @@ void main(void) {
 #endif
 
 #ifdef METALLICWORKFLOW
-	vec4 surfaceMetallicColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
-
-	// No gamma space fro the metallic map in metallic workflow.
-	float metallic = surfaceMetallicColorMap.r; // Unity like base channel for metallness.
+	vec2 metallicRoughness = surfaceReflectivityColor.rg;
+
+	#ifdef METALLICROUGHNESSMAP
+		vec4 surfaceMetallicColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
+
+		// No gamma space from the metallic map in metallic workflow.
+		metallicRoughness.r *= surfaceMetallicColorMap.r;
+		#ifdef METALLICROUGHNESSGSTOREINALPHA
+			metallicRoughness.g *= surfaceMetallicColorMap.a;
+		#else
+			#ifdef METALLICROUGHNESSGSTOREINGREEN
+				metallicRoughness.g *= surfaceMetallicColorMap.g;
+			#endif
+		#endif
+	#endif
 
 	// Diffuse is used as the base of the reflectivity.
 	vec3 baseColor = surfaceAlbedo.rgb;
 
 	// Drop the surface diffuse by the 1.0 - metalness.
-	surfaceAlbedo.rgb *= (1.0 - metallic);
+	surfaceAlbedo.rgb *= (1.0 - metallicRoughness.r);
 	
 	// Default specular reflectance at normal incidence.
-	// 4% corresponds to index of refraction (IOR) of 1.50, approximately equal to glass.    
+	// 4% corresponds to index of refraction (IOR) of 1.50, approximately equal to glass.
 	const vec3 DefaultSpecularReflectanceDielectric = vec3(0.04, 0.04, 0.04);
 
 	// Compute the converted reflectivity.
-	surfaceReflectivityColor = mix(DefaultSpecularReflectanceDielectric, baseColor, metallic);
+	surfaceReflectivityColor = mix(DefaultSpecularReflectanceDielectric, baseColor, metallicRoughness.r);
 
 	#ifdef OVERLOADEDVALUES
 		surfaceReflectivityColor = mix(surfaceReflectivityColor, vOverloadedReflectivity, vOverloadedIntensity.z);
 	#endif
 
-	#ifdef METALLICROUGHNESSGSTOREINALPHA
-		microSurface = 1.0 - surfaceMetallicColorMap.a;
-	#else
-		#ifdef METALLICROUGHNESSGSTOREINGREEN
-			microSurface = 1.0 - surfaceMetallicColorMap.g;
-		#endif
-	#endif
+	microSurface = 1.0 - metallicRoughness.g;
 #endif
 
 #ifdef OVERLOADEDVALUES