Bladeren bron

Merge pull request #7892 from Popov72/effectrenderer

Extend EffectRenderer (set texture w/h, use internal textures only)
mergify[bot] 5 jaren geleden
bovenliggende
commit
5571968a8e
2 gewijzigde bestanden met toevoegingen van 30 en 85 verwijderingen
  1. 2 0
      dist/preview release/what's new.md
  2. 28 85
      src/Materials/effectRenderer.ts

+ 2 - 0
dist/preview release/what's new.md

@@ -101,3 +101,5 @@
 - Fix submesh recreation when it should not ([Popov72](https://github.com/Popov72)
 
 ## Breaking changes
+
+- `EffectRenderer.render` now takes a `RenderTargetTexture` or an `InternalTexture` as the output texture and only a single `EffectWrapper` for its first argument ([Popov72](https://github.com/Popov72))

+ 28 - 85
src/Materials/effectRenderer.ts

@@ -1,5 +1,6 @@
 import { Nullable } from '../types';
-import { Texture } from '../Materials/Textures/texture';
+import { InternalTexture } from './Textures/internalTexture';
+import { RenderTargetTexture } from './Textures/renderTargetTexture';
 import { ThinEngine } from '../Engines/thinEngine';
 import { VertexBuffer } from '../Meshes/buffer';
 import { Viewport } from '../Maths/math.viewport';
@@ -8,8 +9,6 @@ import { Observable } from '../Misc/observable';
 import { Effect } from './effect';
 import { DataBuffer } from '../Meshes/dataBuffer';
 
-import "../Engines/Extensions/engine.renderTarget";
-
 // Prevents ES6 Crash if not imported.
 import "../Shaders/postprocess.vertex";
 
@@ -28,50 +27,21 @@ export interface IEffectRendererOptions {
 }
 
 /**
- * Helper class to render one or more effects
+ * Helper class to render one or more effects.
+ * You can access the previous rendering in your shader by declaring a sampler named textureSampler
  */
 export class EffectRenderer {
     // Fullscreen quad buffers by default.
     private static _DefaultOptions: IEffectRendererOptions = {
         positions: [1, 1, -1, 1, -1, -1, 1, -1],
-        indices: [0, 1, 2, 0, 2, 3]
+        indices: [0, 1, 2, 0, 2, 3],
     };
 
     private _vertexBuffers: {[key: string]: VertexBuffer};
     private _indexBuffer: DataBuffer;
 
-    private _ringBufferIndex = 0;
-    private _ringScreenBuffer: Nullable<Array<Texture>> = null;
     private _fullscreenViewport = new Viewport(0, 0, 1, 1);
 
-    private _getNextFrameBuffer(incrementIndex = true) {
-        if (!this._ringScreenBuffer) {
-            this._ringScreenBuffer = [];
-            for (var i = 0; i < 2; i++) {
-                var internalTexture = this.engine.createRenderTargetTexture(
-                    {
-                        width: this.engine.getRenderWidth(true),
-                        height: this.engine.getRenderHeight(true),
-                    },
-                    {
-                        generateDepthBuffer: false,
-                        generateStencilBuffer: false,
-                        generateMipMaps: false,
-                        samplingMode: Constants.TEXTURE_NEAREST_NEAREST,
-                    },
-                );
-                var texture = new Texture("", null);
-                texture._texture = internalTexture;
-                this._ringScreenBuffer.push(texture);
-            }
-        }
-        var ret = this._ringScreenBuffer[this._ringBufferIndex];
-        if (incrementIndex) {
-            this._ringBufferIndex = (this._ringBufferIndex + 1) % 2;
-        }
-        return ret;
-    }
-
     /**
      * Creates an effect renderer
      * @param engine the engine to use for rendering
@@ -87,10 +57,6 @@ export class EffectRenderer {
             [VertexBuffer.PositionKind]: new VertexBuffer(engine, options.positions!, VertexBuffer.PositionKind, false, false, 2),
         };
         this._indexBuffer = engine.createIndexBuffer(options.indices!);
-
-        // No need here for full screen render.
-        engine.depthCullingState.depthTest = false;
-        engine.stencilState.stencilTest = false;
     }
 
     /**
@@ -116,6 +82,8 @@ export class EffectRenderer {
      * @param effectWrapper Defines the effect to draw with
      */
     public applyEffectWrapper(effectWrapper: EffectWrapper): void {
+        this.engine.depthCullingState.depthTest = false;
+        this.engine.stencilState.stencilTest = false;
         this.engine.enableEffect(effectWrapper.effect);
         this.bindBuffers(effectWrapper.effect);
         effectWrapper.onApplyObservable.notifyObservers({});
@@ -128,68 +96,43 @@ export class EffectRenderer {
         this.engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, 6);
     }
 
+    private isRenderTargetTexture(texture: InternalTexture | RenderTargetTexture): texture is RenderTargetTexture  {
+        return (texture as RenderTargetTexture).renderList !== undefined;
+    }
+
     /**
      * renders one or more effects to a specified texture
-     * @param effectWrappers list of effects to renderer
-     * @param outputTexture texture to draw to, if null it will render to the screen
+     * @param effectWrapper the effect to renderer
+     * @param outputTexture texture to draw to, if null it will render to the screen.
      */
-    public render(effectWrappers: Array<EffectWrapper> | EffectWrapper, outputTexture: Nullable<Texture> = null) {
-        if (!Array.isArray(effectWrappers)) {
-            effectWrappers = [effectWrappers];
+    public render(effectWrapper: EffectWrapper, outputTexture: Nullable<InternalTexture | RenderTargetTexture> = null) {
+        // Ensure effect is ready
+        if (!effectWrapper.effect.isReady()) {
+            return ;
         }
 
-        // Ensure all effects are ready
-        for (var wrapper of effectWrappers) {
-            if (!wrapper.effect.isReady()) {
-                return;
-            }
-        }
+        // Reset state
+        this.setViewport();
 
-        effectWrappers.forEach((effectWrapper, i) => {
-            var renderTo = outputTexture;
+        const out = outputTexture === null ? null : this.isRenderTargetTexture(outputTexture) ? outputTexture.getInternalTexture()! : outputTexture;
 
-            // for any next effect make it's input the output of the previous effect
-            if (i !== 0) {
-                effectWrapper.effect.onBindObservable.addOnce(() => {
-                    effectWrapper.effect.setTexture("textureSampler", this._getNextFrameBuffer(false));
-                });
-            }
-
-            // Set the output to the next screenbuffer
-            if ((effectWrappers as Array<EffectWrapper>).length > 1 && i != (effectWrappers as Array<EffectWrapper>).length - 1) {
-                renderTo = this._getNextFrameBuffer();
-            } else {
-                renderTo = outputTexture;
-            }
-
-            // Reset state
-            this.setViewport();
-
-            if (renderTo) {
-                this.engine.bindFramebuffer(renderTo.getInternalTexture()!);
-            }
+        if (out) {
+            this.engine.bindFramebuffer(out);
+        }
 
-            this.applyEffectWrapper(effectWrapper);
+        this.applyEffectWrapper(effectWrapper);
 
-            this.draw();
+        this.draw();
 
-            if (renderTo) {
-                this.engine.unBindFramebuffer(renderTo.getInternalTexture()!);
-            }
-        });
+        if (out) {
+            this.engine.unBindFramebuffer(out);
+        }
     }
 
     /**
      * Disposes of the effect renderer
      */
     dispose() {
-        if (this._ringScreenBuffer) {
-            this._ringScreenBuffer.forEach((b) => {
-                b.dispose();
-            });
-            this._ringScreenBuffer = null;
-        }
-
         var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];
         if (vertexBuffer) {
             vertexBuffer.dispose();