Benjamin Guignabert 5 سال پیش
والد
کامیت
271063ff9f

+ 12 - 0
src/Engines/Extensions/engine.multiRender.ts

@@ -43,9 +43,21 @@ declare module "../../Engines/thinEngine" {
          * @param attachments attachments to clear
          */
         clearColorAttachments(texture: InternalTexture, color?: IColor4Like) : void;
+
+        /**
+         * Select a subsets of attachments to draw to.
+         * @param attachments gl attachments
+         */
+        renderToAttachments(attachments: any[]) : void;
     }
 }
 
+ThinEngine.prototype.renderToAttachments = function(attachments: any[]): void {
+    const gl = this._gl;
+
+    gl.drawBuffers(attachments);
+};
+
 ThinEngine.prototype.clearColorAttachments = function(texture: InternalTexture, color?: IColor4Like): void {
     // Default clear everything to transparent black
     const gl = this._gl;

+ 8 - 1
src/Materials/PBR/pbrBaseMaterial.ts

@@ -669,6 +669,11 @@ 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;
+    }
+
     /**
      * Force normal to face away from face.
      */
@@ -1296,7 +1301,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         MaterialHelper.PrepareDefinesForMultiview(scene, defines);
 
         // Deferred
-        MaterialHelper.PrepareDefinesForDeferred(scene, defines);
+        if (this.shouldRenderToMRT) {
+            MaterialHelper.PrepareDefinesForDeferred(scene, defines);
+        }
 
         // Textures
         defines.METALLICWORKFLOW = this.isMetallicWorkflow();

+ 14 - 0
src/Materials/material.ts

@@ -218,6 +218,20 @@ export class Material implements IAnimatable {
     public state = "";
 
     /**
+     * The state of the material
+     */
+    protected _shouldRenderToMRT = false;
+
+    public set shouldRenderToMRT(v: 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;
+    }
+
+    /**
      * The alpha value of the material
      */
     @serialize("alpha")

+ 5 - 1
src/Materials/standardMaterial.ts

@@ -815,7 +815,11 @@ export class StandardMaterial extends PushMaterial {
 
         // Multiview
         MaterialHelper.PrepareDefinesForMultiview(scene, defines);
-        MaterialHelper.PrepareDefinesForDeferred(scene, defines);
+
+        // Deferred
+        if (this.shouldRenderToMRT) {
+            MaterialHelper.PrepareDefinesForDeferred(scene, defines);
+        }
 
         // Textures
         if (defines._areTexturesDirty) {

+ 7 - 2
src/Rendering/renderingGroup.ts

@@ -219,9 +219,9 @@ export class RenderingGroup {
         for (subIndex = 0; subIndex < sortedArray.length; subIndex++) {
             subMesh = sortedArray[subIndex];
 
-            if (transparent) {
-                let material = subMesh.getMaterial();
+            let material = subMesh.getMaterial();
 
+            if (transparent) {
                 if (material && material.needDepthPrePass) {
                     let engine = material.getScene().getEngine();
                     engine.setColorWrite(false);
@@ -231,6 +231,11 @@ export class RenderingGroup {
                 }
             }
 
+            // Render to MRT
+            if (material && material.getScene().highDefinitionPipeline) {
+                material.getScene().drawBuffers(material);
+            }
+
             subMesh.render(transparent);
         }
     }

+ 2 - 2
src/Shaders/default.fragment.fx

@@ -44,7 +44,7 @@ varying vec4 vColor;
 #include<lightsFragmentFunctions>
 #include<shadowsFragmentFunctions>
 
-#include<deferredDeclaration>[SCENE_MRT_COUNT]
+// #include<deferredDeclaration>[SCENE_MRT_COUNT]
 
 // Samplers
 #ifdef DIFFUSE
@@ -475,6 +475,6 @@ color.rgb = max(color.rgb, 0.);
 
 gl_FragColor = color;
 
-#include<deferredDefaultOutput>
+// #include<deferredDefaultOutput>
 
 }

+ 13 - 0
src/scene.ts

@@ -260,6 +260,8 @@ export class Scene extends AbstractScene implements IAnimatable {
 
     public mrtCount: number = 4;
     public highDefinitionMRT: MultiRenderTarget;
+    private multiRenderAttachments: any[];
+    private defaultAttachments: any[];
     public sceneCompositorPostProcess: SceneCompositorPostProcess;
     public subSurfaceScatteringPostProcess: SubSurfaceScatteringPostProcess;
 
@@ -1456,6 +1458,9 @@ 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;
+        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];
         this.sceneCompositorPostProcess = new SceneCompositorPostProcess("sceneCompositor", 1, null, undefined, this._engine);
         this.sceneCompositorPostProcess.inputTexture = this.highDefinitionMRT.getInternalTexture()!;
         this.subSurfaceScatteringPostProcess = new SubSurfaceScatteringPostProcess("subSurfaceScattering", this, 1, null, undefined, this._engine);
@@ -3660,6 +3665,14 @@ export class Scene extends AbstractScene implements IAnimatable {
         this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(force));
     }
 
+    public drawBuffers(material: Material) {
+        if (material.shouldRenderToMRT && this.highDefinitionPipeline) {
+            this._engine.renderToAttachments(this.multiRenderAttachments);
+        } else if (this.highDefinitionPipeline) {
+            this._engine.renderToAttachments(this.defaultAttachments);
+        }
+    }
+
     private _bindFrameBuffer() {
         if (this.highDefinitionPipeline) {
             var internalTexture = this.highDefinitionMRT.getInternalTexture();