Parcourir la source

API in material for SSS

Benjamin Guignabert il y a 5 ans
Parent
commit
5caabc5639

+ 4 - 5
src/Materials/PBR/pbrBaseMaterial.ts

@@ -675,9 +675,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);
     }
 
-    public set shouldRenderToMRT(v: boolean) {
-        // Shader is compatible with MRT target
-        this._shouldRenderToMRT = v;
+    public get shouldRenderToMRT() {
+        return true;
     }
 
     /**
@@ -804,7 +803,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     /**
      * Defines the SubSurface parameters for the material.
      */
-    public readonly subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
+    public readonly subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this), this._markSceneDeferredDirty.bind(this));
 
     /**
      * Defines the detail map parameters for the material.
@@ -1316,7 +1315,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         MaterialHelper.PrepareDefinesForMultiview(scene, defines);
 
         // Deferred
-        if (true || this.shouldRenderToMRT) {
+        if (this.shouldRenderToMRT) {
             MaterialHelper.PrepareDefinesForDeferred(scene, defines);
         }
 

+ 13 - 7
src/Materials/PBR/pbrSubSurfaceConfiguration.ts

@@ -64,12 +64,12 @@ export class PBRSubSurfaceConfiguration {
     public isTranslucencyEnabled = false;
 
     private _isScatteringEnabled = false;
-    // /**
-    //  * Defines if the sub surface scattering is enabled in the material.
-    //  */
-    // @serialize()
-    // @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-    // public isScatteringEnabled = false;
+    /**
+     * Defines if the sub surface scattering is enabled in the material.
+     */
+    @serialize()
+    @expandToProperty("_markSceneDeferredDirty")
+    public isScatteringEnabled = false;
 
     /**
      * Defines the refraction intensity of the material.
@@ -223,18 +223,24 @@ export class PBRSubSurfaceConfiguration {
 
     /** @hidden */
     private _internalMarkAllSubMeshesAsTexturesDirty: () => void;
+    private _internalMarkSceneDeferredDirty: () => void;
 
     /** @hidden */
     public _markAllSubMeshesAsTexturesDirty(): void {
         this._internalMarkAllSubMeshesAsTexturesDirty();
     }
+    /** @hidden */
+    public _markSceneDeferredDirty(): void {
+        this._internalMarkSceneDeferredDirty();
+    }
 
     /**
      * Instantiate a new istance of sub surface configuration.
      * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
      */
-    constructor(markAllSubMeshesAsTexturesDirty: () => void) {
+    constructor(markAllSubMeshesAsTexturesDirty: () => void, markSceneDeferredDirty: () => void) {
         this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
+        this._internalMarkSceneDeferredDirty = markSceneDeferredDirty;
     }
 
     /**

+ 12 - 8
src/Materials/material.ts

@@ -229,18 +229,14 @@ export class Material implements IAnimatable {
     @serialize()
     public state = "";
 
+
     /**
-     * The state of the material
+     * If the material should be rendered to several textures with MRT extension
      */
-    protected _shouldRenderToMRT = false;
-
-    public set shouldRenderToMRT(v: boolean) {
+    public get shouldRenderToMRT() : boolean {
         // By default, shader are not compatible with MRTs
         // Base classes should override that if their shader supports MRT
-    }
-
-    public get shouldRenderToMRT() : boolean {
-        return this._shouldRenderToMRT;
+        return false;
     }
 
     /**
@@ -1246,6 +1242,14 @@ export class Material implements IAnimatable {
         }
     }
 
+    protected _markSceneDeferredDirty() {
+        if (this.getScene().blockMaterialDirtyMechanism) {
+            return;
+        }
+        
+        this.getScene().markDeferredDirty();
+    }
+
     /**
  * Indicates that we need to re-calculated for all submeshes
  */

+ 1 - 3
src/Meshes/mesh.ts

@@ -1799,9 +1799,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         }
 
         // Render to MRT
-        if (scene.highDefinitionPipeline) {
-            scene.drawBuffers(material);
-        }
+        scene.drawBuffers(material);
 
         // Material
         if (!instanceDataStorage.isFrozen || !this._effectiveMaterial || this._effectiveMaterial !== material) {

+ 41 - 6
src/scene.ts

@@ -28,6 +28,7 @@ import { Material } from "./Materials/material";
 import { ImageProcessingConfiguration } from "./Materials/imageProcessingConfiguration";
 import { Effect } from "./Materials/effect";
 import { UniformBuffer } from "./Materials/uniformBuffer";
+import { PBRBaseMaterial } from "./Materials/PBR/pbrBaseMaterial";
 import { MultiMaterial } from "./Materials/multiMaterial";
 import { Light } from "./Lights/light";
 import { PickingInfo } from "./Collisions/pickingInfo";
@@ -249,15 +250,43 @@ export class Scene extends AbstractScene implements IAnimatable {
         return this._imageProcessingConfiguration;
     }
 
-    private _highDefinitionPipeline: boolean = true;
+    private _highDefinitionPipeline: boolean = false;
 
     public get highDefinitionPipeline() {
         return this._highDefinitionPipeline;
     }
+
     public set highDefinitionPipeline(b: boolean) {
         this._highDefinitionPipeline = b;
     }
 
+    private _isDeferredDirty: boolean = false;
+    public markDeferredDirty() {
+        this._isDeferredDirty = true;
+    }
+
+    private _updateDeferred() {
+        this.highDefinitionPipeline = false;
+
+        // Subsurface scattering
+        for (let i = 0; i < this.materials.length; i++) {
+            const material = this.materials[i] as PBRBaseMaterial;
+
+            if (material.subSurface && material.subSurface.isScatteringEnabled) {
+                this.highDefinitionPipeline = true;
+            }
+        }
+
+        // SSAO 2
+        // TODO
+
+        this._isDeferredDirty = false;
+
+        if (!this.highDefinitionPipeline) {
+            this._engine.renderToAttachments(this.defaultAttachments);
+        }
+    }
+
     public mrtCount: number = 4;
     public highDefinitionMRT: MultiRenderTarget;
     private multiRenderAttachments: any[];
@@ -1457,7 +1486,7 @@ export class Scene extends AbstractScene implements IAnimatable {
 
         this.highDefinitionMRT = new MultiRenderTarget("sceneHighDefinitionMRT", { width: engine.getRenderWidth(), height: engine.getRenderHeight() }, this.mrtCount, this,
             { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: types });
-        this.highDefinitionMRT.samples = 1;
+        this.highDefinitionMRT.samples = 8;
         let gl = this._engine._gl;
         this.multiRenderAttachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3];
         this.defaultAttachments = [gl.COLOR_ATTACHMENT0, gl.NONE, gl.NONE, gl.NONE];
@@ -3666,10 +3695,12 @@ export class Scene extends AbstractScene implements IAnimatable {
     }
 
     public drawBuffers(material: Material) {
-        if (material.shouldRenderToMRT && this.highDefinitionPipeline) {
-            this._engine.renderToAttachments(this.multiRenderAttachments);
-        } else if (this.highDefinitionPipeline) {
-            this._engine.renderToAttachments(this.defaultAttachments);
+        if (this.highDefinitionPipeline) {
+            if (material.shouldRenderToMRT) {
+                this._engine.renderToAttachments(this.multiRenderAttachments);
+            } else {
+                this._engine.renderToAttachments(this.defaultAttachments);      
+            }
         }
     }
 
@@ -3792,6 +3823,10 @@ export class Scene extends AbstractScene implements IAnimatable {
             }
         }
 
+        if (this._isDeferredDirty) {
+            this._updateDeferred();
+        }
+
         // Restore framebuffer after rendering to targets
         if (needRebind || this.highDefinitionPipeline) {
             this._bindFrameBuffer();