소스 검색

experimenting with drawing on MRT before compositing

Benjamin Guignabert 5 년 전
부모
커밋
c771b5ac6a
5개의 변경된 파일109개의 추가작업 그리고 9개의 파일을 삭제
  1. 8 0
      src/Materials/PBR/pbrBaseMaterial.ts
  2. 41 0
      src/PostProcesses/sceneCompositorPostProcess.ts
  3. 15 3
      src/Shaders/pbr.fragment.fx
  4. 8 0
      src/Shaders/sceneCompositor.fragment.fx
  5. 37 6
      src/scene.ts

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

@@ -153,6 +153,8 @@ export class PBRMaterialDefines extends MaterialDefines
     public HORIZONOCCLUSION = false;
 
     public INSTANCES = false;
+    
+    public HIGH_DEFINITION_PIPELINE = false;
 
     public NUM_BONE_INFLUENCERS = 0;
     public BonesPerMesh = 0;
@@ -1546,6 +1548,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             this._imageProcessingConfiguration.prepareDefines(defines);
         }
 
+        if (scene.highDefinitionPipeline) {
+            defines.HIGH_DEFINITION_PIPELINE = true;            
+        } else {
+            defines.HIGH_DEFINITION_PIPELINE = false;            
+        }
+
         defines.FORCENORMALFORWARD = this._forceNormalForward;
 
         defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;

+ 41 - 0
src/PostProcesses/sceneCompositorPostProcess.ts

@@ -0,0 +1,41 @@
+import { Nullable } from "../types";
+import { Camera } from "../Cameras/camera";
+import { Effect } from "../Materials/effect";
+import { Texture } from "../Materials/Textures/texture";
+import { PostProcess, PostProcessOptions } from "./postProcess";
+import { Engine } from "../Engines/engine";
+import { Constants } from "../Engines/constants";
+
+import "../Shaders/sceneCompositor.fragment";
+import "../Shaders/postprocess.vertex";
+
+/**
+ * Scene compositor post process
+ */
+export class SceneCompositorPostProcess extends PostProcess {
+    /** @hidden */
+    public texelWidth: number;
+    /** @hidden */
+    public texelHeight: number;
+
+    constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
+        super(name, "sceneCompositor", ["texelSize"], null, options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
+
+        const defines = this._getDefines();
+        this.updateEffect(defines);
+
+        this.onApplyObservable.add((effect: Effect) => {
+            var texelSize = this.texelSize;
+            effect.setFloat2("texelSize", texelSize.x, texelSize.y);
+        });
+    }
+
+    private _getDefines(): Nullable<string> {
+        const engine = this.getEngine();
+        if (!engine) {
+            return null;
+        }
+
+        return "";
+    }
+}

+ 15 - 3
src/Shaders/pbr.fragment.fx

@@ -14,6 +14,11 @@
 
 precision highp float;
 
+#ifdef HIGH_DEFINITION_PIPELINE
+#extension GL_EXT_draw_buffers : require
+#include<mrtFragmentDeclaration>[5]
+#endif
+
 // Forces linear space for image processing
 #ifndef FROMLINEARSPACE
     #define FROMLINEARSPACE
@@ -482,14 +487,21 @@ void main(void) {
 
     #include<pbrBlockFinalColorComposition>
 
-    #include<logDepthFragment>
+        #include<logDepthFragment>
     #include<fogFragment>(color, finalColor)
 
     #include<pbrBlockImageProcessing>
 
-    #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
 
+#ifdef HIGH_DEFINITION_PIPELINE
+    gl_FragData[0] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[1] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[2] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[3] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[4] = vec4(1.0, 0.0, 0.0, 1.0);
+#else
+    // #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
     gl_FragColor = finalColor;
-
+#endif
     #include<pbrDebug>
 }

+ 8 - 0
src/Shaders/sceneCompositor.fragment.fx

@@ -0,0 +1,8 @@
+// Samplers
+varying vec2 vUV;
+uniform sampler2D textureSampler;
+
+void main(void) 
+{
+	gl_FragColor = texture2D(textureSampler, vUV);
+}

+ 37 - 6
src/scene.ts

@@ -21,6 +21,8 @@ import { AbstractScene } from "./abstractScene";
 import { BaseTexture } from "./Materials/Textures/baseTexture";
 import { Texture } from "./Materials/Textures/texture";
 import { RenderTargetTexture } from "./Materials/Textures/renderTargetTexture";
+import { MultiRenderTarget } from "./Materials/Textures/multiRenderTarget";
+import { SceneCompositorPostProcess } from "./PostProcesses/sceneCompositorPostProcess";
 import { Material } from "./Materials/material";
 import { ImageProcessingConfiguration } from "./Materials/imageProcessingConfiguration";
 import { Effect } from "./Materials/effect";
@@ -246,6 +248,15 @@ export class Scene extends AbstractScene implements IAnimatable {
         return this._imageProcessingConfiguration;
     }
 
+    private _highDefinitionPipeline: boolean = true;
+
+    public get highDefinitionPipeline () {
+        return this._highDefinitionPipeline;
+    }
+
+    public highDefinitionMRT: MultiRenderTarget;
+    public sceneCompositorPostProcess: SceneCompositorPostProcess;
+
     private _forceWireframe = false;
     /**
      * Gets or sets a boolean indicating if all rendering must be done in wireframe
@@ -1427,6 +1438,13 @@ export class Scene extends AbstractScene implements IAnimatable {
         if (!options || !options.virtual) {
             this._engine.onNewSceneAddedObservable.notifyObservers(this);
         }
+
+        // TODO : TEMPORARY
+        this.highDefinitionMRT = new MultiRenderTarget("sceneHighDefinitionMRT", { width: engine.getRenderWidth(), height: engine.getRenderHeight() }, 5, this,
+            { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT });
+
+        this.sceneCompositorPostProcess = new SceneCompositorPostProcess("sceneCompositor", 1, null, undefined, this._engine);
+        this.sceneCompositorPostProcess.inputTexture = this.highDefinitionMRT.getInternalTexture()!;
     }
 
     /**
@@ -3622,6 +3640,15 @@ export class Scene extends AbstractScene implements IAnimatable {
     }
 
     private _bindFrameBuffer() {
+        if (this.highDefinitionPipeline) {
+            var internalTexture = this.highDefinitionMRT.getInternalTexture();
+            if (internalTexture) {
+                this.getEngine().bindFramebuffer(internalTexture);
+            } else {
+                Logger.Error("High Definition pipeline error.");
+            }
+            return;
+        }
         if (this.activeCamera && this.activeCamera._multiviewTexture) {
             this.activeCamera._multiviewTexture._bindFrameBuffer();
         } else if (this.activeCamera && this.activeCamera.outputRenderTarget) {
@@ -3699,9 +3726,9 @@ export class Scene extends AbstractScene implements IAnimatable {
             step.action(this._renderTargets);
         }
 
+        let needRebind = false;
         if (this.renderTargetsEnabled) {
             this._intermediateRendering = true;
-            let needRebind = false;
 
             if (this._renderTargets.length > 0) {
                 Tools.StartPerformanceCounter("Render targets", this._renderTargets.length > 0);
@@ -3729,12 +3756,11 @@ export class Scene extends AbstractScene implements IAnimatable {
             if (this.activeCamera && this.activeCamera.outputRenderTarget) {
                 needRebind = true;
             }
+        }
 
-            // Restore framebuffer after rendering to targets
-            if (needRebind) {
-                this._bindFrameBuffer();
-            }
-
+        // Restore framebuffer after rendering to targets
+        if (needRebind || this.highDefinitionPipeline) {
+            this._bindFrameBuffer();
         }
 
         this.onAfterRenderTargetsRenderObservable.notifyObservers(this);
@@ -3759,6 +3785,11 @@ export class Scene extends AbstractScene implements IAnimatable {
             step.action(this.activeCamera);
         }
 
+        if (this.highDefinitionPipeline) {
+            // this.sceneCompositorPostProcess.activate(this.activeCamera);
+            this.postProcessManager.directRender([this.sceneCompositorPostProcess]);
+        }
+
         // Finalize frame
         if (this.postProcessManager && !camera._multiviewTexture) {
             this.postProcessManager._finalizeFrame(camera.isIntermediate);