Benjamin Guignabert 5 年之前
父节点
当前提交
4c003136ac
共有 1 个文件被更改,包括 154 次插入0 次删除
  1. 154 0
      src/Rendering/prePassRenderer.ts

+ 154 - 0
src/Rendering/prePassRenderer.ts

@@ -0,0 +1,154 @@
+import { PBRBaseMaterial } from "../Materials/PBR/PBRBaseMaterial";
+import { MultiRenderTarget } from "../Materials/Textures/multiRenderTarget";
+import { Scene } from "../scene";
+import { Engine } from "../Engines/Engine";
+import { Constants } from "../Engines/constants";
+import { SceneCompositorPostProcess } from "../PostProcesses/sceneCompositorPostProcess";
+import { SubSurfaceScatteringPostProcess } from "../PostProcesses/subSurfaceScatteringPostProcess";
+import { Effect } from "../Materials/effect";
+import { Logger } from "../Misc/logger";
+import { _DevTools } from '../Misc/devTools';
+
+export class PrePassRenderer {
+    /** @hidden */
+    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
+        throw _DevTools.WarnImport("PrePassRendererSceneComponent");
+    }
+
+    private _scene: Scene;
+    private _engine: Engine;
+    private _isDirty: boolean = false;
+
+    public mrtCount: number = 4;
+    public prePassRT: MultiRenderTarget;
+    private _mrtTypes = [
+        Constants.TEXTURETYPE_UNSIGNED_INT, // Original color
+        Constants.TEXTURETYPE_HALF_FLOAT, // Irradiance
+        Constants.TEXTURETYPE_HALF_FLOAT, // Depth (world units)
+        Constants.TEXTURETYPE_UNSIGNED_INT
+    ];
+    private _multiRenderAttachments: any[];
+    private _defaultAttachments: any[];
+
+    public sceneCompositorPostProcess: SceneCompositorPostProcess;
+    public subSurfaceScatteringPostProcess: SubSurfaceScatteringPostProcess;
+    private _enabled: boolean = false;
+
+    public get enabled() {
+        return this._enabled;
+    }
+
+    public set enabled(b: boolean) {
+        this._enabled = b;
+    }
+
+    constructor(scene: Scene) {
+        this._scene = scene;
+        this._engine = scene.getEngine();
+
+        this.prePassRT = new MultiRenderTarget("sceneprePassRT", { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() }, this.mrtCount, this._scene,
+            { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: this._mrtTypes });
+        this.prePassRT.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.prePassRT.getInternalTexture()!;
+        this.subSurfaceScatteringPostProcess = new SubSurfaceScatteringPostProcess("subSurfaceScattering", this._scene, 1, null, undefined, this._engine);
+    }
+
+    public get isSupported() {
+        // TODO
+        return true;
+    }
+
+    public drawBuffers(effect: Effect) {
+        if (this.enabled) {
+            if (effect._multiTarget) {
+                this._engine.renderToAttachments(this._multiRenderAttachments);
+            } else {
+                this._engine.renderToAttachments(this._defaultAttachments);      
+            }
+        }
+    }
+
+    public _beforeCameraDraw() {
+        if (this._isDirty) {
+            this._update();
+        }
+
+        this._bindFrameBuffer();
+    }
+
+    public _afterCameraDraw() {
+        if (this._enabled) {
+            // this.sceneCompositorPostProcess.activate(this._scene.activeCamera);
+            this.sceneCompositorPostProcess.autoClear = false;
+            this.sceneCompositorPostProcess.activate(this._scene.activeCamera);
+            this.subSurfaceScatteringPostProcess.activate(this._scene.activeCamera);
+            this._scene.postProcessManager.directRender([this.sceneCompositorPostProcess], this.subSurfaceScatteringPostProcess.inputTexture);
+            // this.getEngine().restoreDefaultFramebuffer(); // Restore back buffer if needed
+            this._scene.postProcessManager._prepareFrame();
+            this._scene.postProcessManager.directRender([this.subSurfaceScatteringPostProcess], null, false, 0, 0, true);
+        }
+    }
+
+    private _checkRTSize() {
+        var requiredWidth = this._engine.getRenderWidth(true);
+        var requiredHeight = this._engine.getRenderHeight(true);
+        var width = this.prePassRT.getRenderWidth();
+        var height = this.prePassRT.getRenderHeight();
+
+        if (width !== requiredWidth || height !== requiredHeight) {
+            this.prePassRT.resize({ width: requiredWidth, height: requiredHeight });
+            this.sceneCompositorPostProcess.inputTexture = this.prePassRT.getInternalTexture()!;
+        }
+    }
+
+    private _bindFrameBuffer() {
+        if (this._enabled) {
+            this._checkRTSize();
+            var internalTexture = this.prePassRT.getInternalTexture();
+            if (internalTexture) {
+                this._engine.bindFramebuffer(internalTexture);
+            } else {
+                Logger.Error("High Definition pipeline error.");
+            }
+            return;
+        }
+    }
+
+    public markDeferredDirty() {
+        this._isDirty = true;
+    }
+
+    private _update() {
+        this.enabled = false;
+
+        // Subsurface scattering
+        for (let i = 0; i < this._scene.materials.length; i++) {
+            const material = this._scene.materials[i] as PBRBaseMaterial;
+
+            if (material.subSurface && material.subSurface.isScatteringEnabled) {
+                this.enabled = true;
+            }
+        }
+
+        // SSAO 2
+        // TODO
+
+        this._isDirty = false;
+
+        if (!this.enabled) {
+            this._engine.renderToAttachments(this._defaultAttachments);
+        }
+    }
+
+    public dispose() {
+        this.sceneCompositorPostProcess.dispose();
+        this.subSurfaceScatteringPostProcess.dispose();
+        this.prePassRT.dispose();
+    }
+
+}