Pārlūkot izejas kodu

Make a separate class for detailMap

Popov72 5 gadi atpakaļ
vecāks
revīzija
16f3c66027

+ 21 - 78
src/Materials/PBR/pbrBaseMaterial.ts

@@ -40,6 +40,7 @@ import "../../Shaders/pbr.fragment";
 import "../../Shaders/pbr.vertex";
 
 import { EffectFallbacks } from '../effectFallbacks';
+import { IMaterialDetailMapDefines, DetailMap } from '../material.detailMap';
 
 const onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };
 
@@ -53,7 +54,8 @@ export class PBRMaterialDefines extends MaterialDefines
     IMaterialAnisotropicDefines,
     IMaterialBRDFDefines,
     IMaterialSheenDefines,
-    IMaterialSubSurfaceDefines {
+    IMaterialSubSurfaceDefines,
+    IMaterialDetailMapDefines {
     public PBR = true;
 
     public NUM_SAMPLES = "0u";
@@ -796,44 +798,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
      */
     public readonly subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
 
-    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
+     * Defines the detail map parameters for the material.
      */
-    @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;
+    public readonly detailMap = new DetailMap();
 
-    /**
-     * 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;
+    protected _rebuildInParallel = false;
 
     /**
      * Instantiates a new PBRMaterial instance.
@@ -1044,13 +1014,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                     }
                 }
 
-                if (engine.getCaps().standardDerivatives && this._detailTexture && MaterialFlags.DetailTextureEnabled) {
-                    // Detail texture cannot be not blocking.
-                    if (!this._detailTexture.isReady()) {
-                        return false;
-                    }
-                }
-
                 if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {
                     // This is blocking.
                     if (!this._environmentBRDFTexture.isReady()) {
@@ -1063,7 +1026,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         if (!this.subSurface.isReadyForSubMesh(defines, scene) ||
             !this.clearCoat.isReadyForSubMesh(defines, scene, engine, this._disableBumpMap) ||
             !this.sheen.isReadyForSubMesh(defines, scene) ||
-            !this.anisotropy.isReadyForSubMesh(defines, scene)) {
+            !this.anisotropy.isReadyForSubMesh(defines, scene) ||
+            !this.detailMap.isReadyForSubMesh(defines, scene)) {
             return false;
         }
 
@@ -1259,7 +1223,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", "vDetailInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", "vReflectionFilteringInfo", "vMetallicReflectanceInfos",
+            "vAlbedoInfos", "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",
@@ -1276,13 +1240,16 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             "vDebugMode"
         ];
 
-        var samplers = ["albedoSampler", "detailSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
+        var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
             "bumpSampler", "lightmapSampler", "opacitySampler",
             "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh", "irradianceSampler",
             "microSurfaceSampler", "environmentBrdfSampler", "boneSampler", "metallicReflectanceSampler"];
 
         var uniformBuffers = ["Material", "Scene"];
 
+        DetailMap.AddUniforms(uniforms);
+        DetailMap.AddSamplers(samplers);
+
         PBRSubSurfaceConfiguration.AddUniforms(uniforms);
         PBRSubSurfaceConfiguration.AddSamplers(samplers);
 
@@ -1543,13 +1510,6 @@ 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.
@@ -1618,6 +1578,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         }
 
         // External config
+        this.detailMap.prepareDefines(defines, scene);
         this.subSurface.prepareDefines(defines, scene);
         this.clearCoat.prepareDefines(defines, scene);
         this.anisotropy.prepareDefines(defines, mesh, scene);
@@ -1680,9 +1641,7 @@ 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);
@@ -1710,6 +1669,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRAnisotropicConfiguration.PrepareUniformBuffer(ubo);
         PBRSheenConfiguration.PrepareUniformBuffer(ubo);
         PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
+        DetailMap.PrepareUniformBuffer(ubo);
 
         ubo.create();
     }
@@ -1793,11 +1753,6 @@ 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");
@@ -1962,10 +1917,6 @@ 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);
                 }
@@ -2023,6 +1974,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                 }
             }
 
+            this.detailMap.bindForSubMesh(ubo, scene, this.isFrozen);
             this.subSurface.bindForSubMesh(ubo, scene, engine, this.isFrozen, defines.LODBASEDMICROSFURACE, this.realTimeFiltering);
             this.clearCoat.bindForSubMesh(ubo, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
             this.anisotropy.bindForSubMesh(ubo, scene, this.isFrozen);
@@ -2088,10 +2040,6 @@ 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);
         }
@@ -2123,6 +2071,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             results.push(this._lightmapTexture);
         }
 
+        this.detailMap.getAnimatables(results);
         this.subSurface.getAnimatables(results);
         this.clearCoat.getAnimatables(results);
         this.sheen.getAnimatables(results);
@@ -2154,10 +2103,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             activeTextures.push(this._albedoTexture);
         }
 
-        if (this._detailTexture) {
-            activeTextures.push(this._detailTexture);
-        }
-
         if (this._ambientTexture) {
             activeTextures.push(this._ambientTexture);
         }
@@ -2198,6 +2143,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             activeTextures.push(this._lightmapTexture);
         }
 
+        this.detailMap.getActiveTextures(activeTextures);
         this.subSurface.getActiveTextures(activeTextures);
         this.clearCoat.getActiveTextures(activeTextures);
         this.sheen.getActiveTextures(activeTextures);
@@ -2220,10 +2166,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             return true;
         }
 
-        if (this._detailTexture === texture) {
-            return true;
-        }
-
         if (this._ambientTexture === texture) {
             return true;
         }
@@ -2260,7 +2202,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             return true;
         }
 
-        return this.subSurface.hasTexture(texture) ||
+        return this.detailMap.hasTexture(texture) ||
+            this.subSurface.hasTexture(texture) ||
             this.clearCoat.hasTexture(texture) ||
             this.sheen.hasTexture(texture) ||
             this.anisotropy.hasTexture(texture);
@@ -2278,7 +2221,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             }
 
             this._albedoTexture?.dispose();
-            this._detailTexture?.dispose();
             this._ambientTexture?.dispose();
             this._opacityTexture?.dispose();
             this._reflectionTexture?.dispose();
@@ -2291,6 +2233,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             this._microSurfaceTexture?.dispose();
         }
 
+        this.detailMap.dispose(forceDisposeTextures);
         this.subSurface.dispose(forceDisposeTextures);
         this.clearCoat.dispose(forceDisposeTextures);
         this.sheen.dispose(forceDisposeTextures);

+ 243 - 0
src/Materials/material.detailMap.ts

@@ -0,0 +1,243 @@
+import { Nullable } from "../types";
+import { Scene } from "../scene";
+import { Material } from "./material";
+import { _TypeStore } from "../Misc/typeStore";
+import { serialize, expandToProperty, serializeAsTexture, SerializationHelper } from '../Misc/decorators';
+import { MaterialFlags } from './materialFlags';
+import { MaterialHelper } from './materialHelper';
+import { BaseTexture } from './Textures/baseTexture';
+import { UniformBuffer } from './uniformBuffer';
+import { IAnimatable } from '../Animations/animatable.interface';
+
+/**
+ * @hidden
+ */
+export interface IMaterialDetailMapDefines {
+    DETAIL: boolean;
+    DETAILDIRECTUV : number;
+    DETAIL_NORMALBLENDMETHOD: number;
+
+    /** @hidden */
+    _areTexturesDirty: boolean;
+}
+
+export class DetailMap {
+
+    @serializeAsTexture("detailTexture")
+    private _detailTexture: Nullable<BaseTexture> = null;
+    /**
+     * The detail texture of the material.
+     */
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public detailTexture: Nullable<BaseTexture>;
+
+    /**
+     * Defines how strongly the detail diffuse/albedo channel is blended with the regular diffuse/albedo texture
+     * Bigger values mean stronger blending
+     */
+    @serialize()
+    public detailDiffuseBlendLevel = 0.5;
+
+    /**
+     * Defines how strongly the detail roughness channel is blended with the regular roughness value
+     * Bigger values mean stronger blending. Only used with PBR materials
+     */
+    @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("_markAllSubMeshesAsMiscDirty")
+    public detailNormalBlendMethod: number;
+
+    /**
+     * Enable or disable the detail map on this material
+     */
+    @serialize()
+    public disableDetailMap: boolean = false;
+
+    /**
+     * Gets whether the submesh is ready to be used or not.
+     * @param defines the list of "defines" to update.
+     * @param scene defines the scene the material belongs to.
+     * @returns - boolean indicating that the submesh is ready or not.
+     */
+    public isReadyForSubMesh(defines: IMaterialDetailMapDefines, scene: Scene): boolean {
+        const engine = scene.getEngine();
+
+        if (defines._areTexturesDirty && scene.texturesEnabled) {
+            if (engine.getCaps().standardDerivatives && this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                // Detail texture cannot be not blocking.
+                if (!this._detailTexture.isReady()) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Update the defines for detail map usage
+     * @param defines the list of "defines" to update.
+     * @param scene defines the scene the material belongs to.
+     */
+    public prepareDefines(defines: IMaterialDetailMapDefines, scene: Scene): boolean {
+        if (!this.disableDetailMap) {
+            defines.DETAIL_NORMALBLENDMETHOD = this._detailNormalBlendMethod;
+
+            const engine = scene.getEngine();
+
+            if (defines._areTexturesDirty) {
+                if (engine.getCaps().standardDerivatives && this._detailTexture && MaterialFlags.DetailTextureEnabled && !this.disableDetailMap) {
+                    MaterialHelper.PrepareDefinesForMergedUV(this._detailTexture, defines, "DETAIL");
+                    defines.DETAIL_NORMALBLENDMETHOD = this._detailNormalBlendMethod;
+                } else {
+                    defines.DETAIL = false;
+                }
+            }
+        } else {
+            defines.DETAIL = false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Binds the material data.
+     * @param uniformBuffer defines the Uniform buffer to fill in.
+     * @param scene defines the scene the material belongs to.
+     * @param isFrozen defines whether the material is frozen or not.
+     */
+    public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, isFrozen: boolean): void {
+        if (this.disableDetailMap) {
+            return;
+        }
+
+        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
+            if (this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                uniformBuffer.updateFloat4("vDetailInfos", this._detailTexture.coordinatesIndex, this.detailDiffuseBlendLevel, this.detailBumpLevel, this.detailRoughnessBlendLevel);
+                MaterialHelper.BindTextureMatrix(this._detailTexture, uniformBuffer, "detail");
+            }
+        }
+
+        // Textures
+        if (scene.texturesEnabled) {
+            if (this._detailTexture && MaterialFlags.DetailTextureEnabled) {
+                uniformBuffer.setTexture("detailSampler", this._detailTexture);
+            }
+        }
+    }
+
+    /**
+     * Checks to see if a texture is used in the material.
+     * @param texture - Base texture to use.
+     * @returns - Boolean specifying if a texture is used in the material.
+     */
+    public hasTexture(texture: BaseTexture): boolean {
+        if (this._detailTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns an array of the actively used textures.
+     * @param activeTextures Array of BaseTextures
+     */
+    public getActiveTextures(activeTextures: BaseTexture[]): void {
+        if (this._detailTexture) {
+            activeTextures.push(this._detailTexture);
+        }
+    }
+
+    /**
+     * Returns the animatable textures.
+     * @param animatables Array of animatable textures.
+     */
+    public getAnimatables(animatables: IAnimatable[]): void {
+        if (this._detailTexture && this._detailTexture.animations && this._detailTexture.animations.length > 0) {
+            animatables.push(this._detailTexture);
+        }
+    }
+
+    /**
+     * Disposes the resources of the material.
+     * @param forceDisposeTextures - Forces the disposal of all textures.
+     */
+    public dispose(forceDisposeTextures?: boolean): void {
+        if (forceDisposeTextures) {
+            this._detailTexture?.dispose();
+        }
+    }
+
+    /**
+    * Get the current class name useful for serialization or dynamic coding.
+    * @returns "DetailMap"
+    */
+    public getClassName(): string {
+        return "DetailMap";
+    }
+
+    /**
+     * Add the required uniforms to the current list.
+     * @param uniforms defines the current uniform list.
+     */
+    public static AddUniforms(uniforms: string[]): void {
+        uniforms.push("vDetailInfos");
+    }
+
+    /**
+     * Add the required samplers to the current list.
+     * @param samplers defines the current sampler list.
+     */
+    public static AddSamplers(samplers: string[]): void {
+        samplers.push("detailSampler");
+    }
+
+    /**
+     * Add the required uniforms to the current buffer.
+     * @param uniformBuffer defines the current uniform buffer.
+     */
+    public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
+        uniformBuffer.addUniform("vDetailInfos", 4);
+        uniformBuffer.addUniform("detailMatrix", 16);
+    }
+
+    /**
+     * Makes a duplicate of the current instance into another one.
+     * @param detailMap define the instance where to copy the info
+     */
+    public copyTo(detailMap: DetailMap): void {
+        SerializationHelper.Clone(() => detailMap, this);
+    }
+
+    /**
+     * Serializes this detail map instance
+     * @returns - An object with the serialized instance.
+     */
+    public serialize(): any {
+        return SerializationHelper.Serialize(this);
+    }
+
+    /**
+     * Parses a detail map setting from a serialized object.
+     * @param source - Serialized object.
+     * @param scene Defines the scene we are parsing for
+     * @param rootUrl Defines the rootUrl to load from
+     */
+    public parse(source: any, scene: Scene, rootUrl: string): void {
+        SerializationHelper.Parse(() => this, source, scene, rootUrl);
+    }
+}

+ 4 - 3
src/Materials/standardMaterial.ts

@@ -1297,10 +1297,8 @@ export class StandardMaterial extends PushMaterial {
         ubo.addUniform("vLightmapInfos", 2);
         ubo.addUniform("vSpecularInfos", 2);
         ubo.addUniform("vBumpInfos", 3);
-        ubo.addUniform("vDetailInfos", 3);
 
         ubo.addUniform("diffuseMatrix", 16);
-        ubo.addUniform("detailMatrix", 16);
         ubo.addUniform("ambientMatrix", 16);
         ubo.addUniform("opacityMatrix", 16);
         ubo.addUniform("reflectionMatrix", 16);
@@ -1317,6 +1315,9 @@ export class StandardMaterial extends PushMaterial {
         ubo.addUniform("visibility", 1);
         ubo.addUniform("vDiffuseColor", 4);
 
+        ubo.addUniform("vDetailInfos", 3);
+        ubo.addUniform("detailMatrix", 16);
+
         ubo.create();
     }
 
@@ -1425,7 +1426,7 @@ export class StandardMaterial extends PushMaterial {
                     }
 
                     if (this._detailTexture && StandardMaterial.DetailTextureEnabled) {
-                        ubo.updateFloat3("vDetailInfos", this._detailTexture.coordinatesIndex, 1 - this.detailDiffuseBlendLevel, this.detailBumpLevel);
+                        ubo.updateFloat3("vDetailInfos", this._detailTexture.coordinatesIndex, this.detailDiffuseBlendLevel, this.detailBumpLevel);
                         MaterialHelper.BindTextureMatrix(this._detailTexture, ubo, "detail");
                     }
 

+ 1 - 1
src/Shaders/ShadersInclude/bumpFragment.fx

@@ -61,5 +61,5 @@
         normalW = perturbNormalBase(TBN, blendedNormal, vBumpInfos.y);
 	#endif
 #elif defined(DETAIL)    
-		normalW = perturbNormalBase(TBN, detailNormal, 1.0 / vDetailInfos.z);
+		normalW = perturbNormalBase(TBN, detailNormal, vDetailInfos.z);
 #endif

+ 3 - 2
src/Shaders/ShadersInclude/defaultUboDeclaration.fx

@@ -21,9 +21,7 @@ uniform Material
 	vec2 vLightmapInfos;
 	vec2 vSpecularInfos;
 	vec3 vBumpInfos;
-	vec3 vDetailInfos;
 	mat4 diffuseMatrix;
-	mat4 detailMatrix;
 	mat4 ambientMatrix;
 	mat4 opacityMatrix;
 	mat4 reflectionMatrix;
@@ -39,6 +37,9 @@ uniform Material
 	vec3 vEmissiveColor;
 	float visibility;
 	vec4 vDiffuseColor;
+
+	vec3 vDetailInfos;
+	mat4 detailMatrix;
 };
 
 uniform Scene {

+ 3 - 2
src/Shaders/ShadersInclude/pbrUboDeclaration.fx

@@ -14,9 +14,7 @@ uniform Material
     uniform vec3 vReflectionPosition;
     uniform vec3 vReflectionSize;
     uniform vec3 vBumpInfos;
-    uniform vec4 vDetailInfos;
     uniform mat4 albedoMatrix;
-    uniform mat4 detailMatrix;
     uniform mat4 ambientMatrix;
     uniform mat4 opacityMatrix;
     uniform mat4 emissiveMatrix;
@@ -71,6 +69,9 @@ uniform Material
     uniform vec3 vDiffusionDistance;
     uniform vec4 vTintColor;
     uniform vec3 vSubSurfaceIntensity;
+
+    uniform vec4 vDetailInfos;
+    uniform mat4 detailMatrix;
 };
 
 uniform Scene {