Explorar o código

Add detail map support to pbr material

Popov72 %!s(int64=5) %!d(string=hai) anos
pai
achega
eb519103b4
Modificáronse 1 ficheiros con 81 adicións e 3 borrados
  1. 81 3
      src/Materials/PBR/pbrBaseMaterial.ts

+ 81 - 3
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1,4 +1,4 @@
-import { serialize, serializeAsImageProcessingConfiguration, expandToProperty } from "../../Misc/decorators";
+import { serialize, serializeAsImageProcessingConfiguration, expandToProperty, serializeAsTexture } from "../../Misc/decorators";
 import { Observer } from "../../Misc/observable";
 import { Logger } from "../../Misc/logger";
 import { SmartArray } from "../../Misc/smartArray";
@@ -69,6 +69,10 @@ export class PBRMaterialDefines extends MaterialDefines
     public ALBEDODIRECTUV = 0;
     public VERTEXCOLOR = false;
 
+    public DETAIL = false;
+    public DETAILDIRECTUV = 0;
+    public DETAIL_NORMALBLENDMETHOD = 0;
+
     public AMBIENT = false;
     public AMBIENTDIRECTUV = 0;
     public AMBIENTINGRAYSCALE = false;
@@ -793,6 +797,43 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
     protected _rebuildInParallel = false;
 
+    @serializeAsTexture("detailTexture")
+    private _detailTexture: Nullable<BaseTexture> = null;
+    /**
+     * The detail texture of the material.
+     */
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public detailTexture: Nullable<BaseTexture>;
+
+    /**
+     * Defines how strongly the detail albedo channel is blended with the regular albedo texture
+     * Bigger values mean stronger blending
+     */
+    @serialize()
+    public detailAlbedoBlendLevel = 0.5;
+
+    /**
+     * Defines how strongly the detail roughness channel is blended with the regular roughness value
+     * Bigger values mean stronger blending
+     */
+    @serialize()
+    public detailRoughnessBlendLevel = 0.5;
+
+    /**
+     * Defines how strong the bump effect from the detail map is
+     * Bigger values mean stronger effect
+     */
+    @serialize()
+    public detailBumpLevel = 1;
+
+    @serialize()
+    private _detailNormalBlendMethod = Material.MATERIAL_NORMALBLENDMETHOD_WHITEOUT;
+    /**
+     * The method used to blend the bump and detail normals together
+     */
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public detailNormalBlendMethod: number;
+
     /**
      * Instantiates a new PBRMaterial instance.
      *
@@ -936,6 +977,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                     }
                 }
 
+                if (this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                    if (!this._detailTexture.isReadyOrNotBlocking()) {
+                        return false;
+                    }
+                }
+
                 if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
                     if (!this._ambientTexture.isReadyOrNotBlocking()) {
                         return false;
@@ -1210,7 +1257,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
         var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vAlbedoColor", "vReflectivityColor", "vMetallicReflectanceFactors", "vEmissiveColor", "visibility", "vReflectionColor",
             "vFogInfos", "vFogColor", "pointSize",
-            "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", "vReflectionFilteringInfo", "vMetallicReflectanceInfos",
+            "vAlbedoInfos", "vDetailInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", "vReflectionFilteringInfo", "vMetallicReflectanceInfos",
             "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos",
             "mBones",
             "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "vClipPlane5", "vClipPlane6", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "normalMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix", "metallicReflectanceMatrix",
@@ -1227,7 +1274,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             "vDebugMode"
         ];
 
-        var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
+        var samplers = ["albedoSampler", "detailSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
             "bumpSampler", "lightmapSampler", "opacitySampler",
             "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh", "irradianceSampler",
             "microSurfaceSampler", "environmentBrdfSampler", "boneSampler", "metallicReflectanceSampler"];
@@ -1494,6 +1541,13 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                     defines.BUMP = false;
                 }
 
+                if (scene.getEngine().getCaps().standardDerivatives && this._detailTexture && MaterialFlags.DetailTextureEnabled && !this._disableBumpMap) {
+                    MaterialHelper.PrepareDefinesForMergedUV(this._detailTexture, defines, "DETAIL");
+                    defines.DETAIL_NORMALBLENDMETHOD = this._detailNormalBlendMethod;
+                } else {
+                    defines.DETAIL = false;
+                }
+
                 if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {
                     defines.ENVIRONMENTBRDF = true;
                     // Not actual true RGBD, only the B chanel is encoded as RGBD for sheen.
@@ -1624,7 +1678,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         ubo.addUniform("vReflectionPosition", 3);
         ubo.addUniform("vReflectionSize", 3);
         ubo.addUniform("vBumpInfos", 3);
+        ubo.addUniform("vDetailInfos", 4);
         ubo.addUniform("albedoMatrix", 16);
+        ubo.addUniform("detailMatrix", 16);
         ubo.addUniform("ambientMatrix", 16);
         ubo.addUniform("opacityMatrix", 16);
         ubo.addUniform("emissiveMatrix", 16);
@@ -1735,6 +1791,11 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                         MaterialHelper.BindTextureMatrix(this._albedoTexture, ubo, "albedo");
                     }
 
+                    if (this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                        ubo.updateFloat4("vDetailInfos", this._detailTexture.coordinatesIndex, 1 - this.detailAlbedoBlendLevel, this.detailBumpLevel, this.detailRoughnessBlendLevel);
+                        MaterialHelper.BindTextureMatrix(this._detailTexture, ubo, "detail");
+                    }
+
                     if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
                         ubo.updateFloat4("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength, this._ambientTextureImpactOnAnalyticalLights);
                         MaterialHelper.BindTextureMatrix(this._ambientTexture, ubo, "ambient");
@@ -1899,6 +1960,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                     ubo.setTexture("albedoSampler", this._albedoTexture);
                 }
 
+                if (this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                    ubo.setTexture("detailSampler", this._detailTexture);
+                }
+
                 if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
                     ubo.setTexture("ambientSampler", this._ambientTexture);
                 }
@@ -2021,6 +2086,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             results.push(this._albedoTexture);
         }
 
+        if (this._detailTexture && this._detailTexture.animations && this._detailTexture.animations.length > 0) {
+            results.push(this._detailTexture);
+        }
+
         if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
             results.push(this._ambientTexture);
         }
@@ -2083,6 +2152,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             activeTextures.push(this._albedoTexture);
         }
 
+        if (this._detailTexture) {
+            activeTextures.push(this._detailTexture);
+        }
+
         if (this._ambientTexture) {
             activeTextures.push(this._ambientTexture);
         }
@@ -2145,6 +2218,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             return true;
         }
 
+        if (this._detailTexture === texture) {
+            return true;
+        }
+
         if (this._ambientTexture === texture) {
             return true;
         }
@@ -2199,6 +2276,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             }
 
             this._albedoTexture?.dispose();
+            this._detailTexture?.dispose();
             this._ambientTexture?.dispose();
             this._opacityTexture?.dispose();
             this._reflectionTexture?.dispose();