Explorar o código

merged textures, remaining problem with gamma output

Benjamin Guignabert %!s(int64=4) %!d(string=hai) anos
pai
achega
7b0e556dc5

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1700
dist/preview release/babylon.ktx2Decoder.js


+ 6 - 3
src/Materials/Textures/multiRenderTarget.ts

@@ -217,12 +217,15 @@ export class MultiRenderTarget extends RenderTargetTexture {
     }
 
     /**
-     * Replaces a texture within the MRT
+     * Replaces a texture within the MRT.
      * @param texture The new texture to insert in the MRT
      * @param index The index of the texture to replace
      */
-    public _replaceTexture(texture: Texture, index: number) {
-        // TODO
+    public replaceTexture(texture: Texture, index: number) {
+        if (texture._texture) {
+            this._textures[index] = texture;
+            this._internalTextures[index] = texture._texture;
+        }
     }
 
     /**

+ 137 - 10
src/Rendering/geometryBufferRenderer.ts

@@ -5,8 +5,10 @@ import { Mesh } from "../Meshes/mesh";
 import { Constants } from "../Engines/constants";
 import { SmartArray } from "../Misc/smartArray";
 import { Texture } from "../Materials/Textures/texture";
+import { InternalTexture } from "../Materials/Textures/internalTexture";
 import { MultiRenderTarget } from "../Materials/Textures/multiRenderTarget";
 import { Effect } from "../Materials/effect";
+import { PrePassRenderer } from "../Rendering/prePassRenderer";
 import { MaterialHelper } from "../Materials/materialHelper";
 import { Scene } from "../scene";
 import { AbstractMesh } from "../Meshes/abstractMesh";
@@ -32,6 +34,11 @@ interface ISavedTransformationMatrix {
  */
 export class GeometryBufferRenderer {
     /**
+     * Constant used to retrieve the depth + normal texture index in the G-Buffer textures array
+     * using getIndex(GeometryBufferRenderer.DEPTHNORMAL_TYPE)
+     */
+    public static readonly DEPTHNORMAL_TEXTURE_TYPE = 0;
+    /**
      * Constant used to retrieve the position texture index in the G-Buffer textures array
      * using getIndex(GeometryBufferRenderer.POSITION_TEXTURE_INDEX)
      */
@@ -79,10 +86,98 @@ export class GeometryBufferRenderer {
     private _positionIndex: number = -1;
     private _velocityIndex: number = -1;
     private _reflectivityIndex: number = -1;
+    private _depthNormalIndex: number = -1;
+
+    private _linkedWithPrePass: boolean = false;
+    private _prePassRenderer: PrePassRenderer;
+    private _attachments: number[];
 
     protected _effect: Effect;
     protected _cachedDefines: string;
 
+
+    /**
+     * @hidden
+     * Sets up internal structures to share outputs with PrePassRenderer
+     * This method should only be called by the PrePassRenderer itself
+     */
+    public linkPrePassRenderer(prePassRenderer: PrePassRenderer) {
+        this._linkedWithPrePass = true;
+        this._prePassRenderer = prePassRenderer;
+
+        if (this._multiRenderTarget) {
+            // prevents clearing of the RT since it's done by prepass
+            this._multiRenderTarget.onClearObservable.clear();
+            this._multiRenderTarget.onClearObservable.add((engine) => {
+                // pass
+            });
+        }
+    }
+
+    /**
+     * @hidden
+     * Separates internal structures from PrePassRenderer so the geometry buffer can now operate by itself.
+     * This method should only be called by the PrePassRenderer itself
+     */
+    public unlinkPrePassRenderer() {
+        this._linkedWithPrePass = false;
+        this._createRenderTargets();
+    }
+
+    /**
+     * @hidden
+     * Resets the geometry buffer layout
+     */
+    public resetLayout() {
+        this._enablePosition = false;
+        this._enableReflectivity = false;
+        this._enableVelocity = false;
+        this._attachments = [];
+    }
+
+    /**
+     * @hidden
+     * Replaces a texture in the geometry buffer renderer
+     * Useful when linking textures of the prepass renderer
+     */
+    public replaceTexture(texture: Texture, geometryBufferType: number, index: number) {
+        if (geometryBufferType === GeometryBufferRenderer.POSITION_TEXTURE_TYPE) {
+            this._positionIndex = index;
+            this._enablePosition = true;
+        } else if (geometryBufferType === GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE) {
+            this._velocityIndex = index;
+            this._enableVelocity = true;
+        } else if (geometryBufferType === GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE) {
+            this._reflectivityIndex = index;
+            this._enableReflectivity = true;
+        } else if (geometryBufferType === GeometryBufferRenderer.DEPTHNORMAL_TEXTURE_TYPE) {
+            this._depthNormalIndex = index;
+        }
+    }
+
+    /**
+     * @hidden
+     * Sets texture attachments
+     * Useful when linking textures of the prepass renderer
+     */
+    public setAttachments(attachments: number[]) {
+        this._attachments = attachments;
+    }
+
+    /**
+     * @hidden
+     * Replaces the first texture which is hard coded as a depth texture in the geometry buffer
+     * Useful when linking textures of the prepass renderer   
+     */
+    public replaceDepthTexture(texture: Texture, internalTexture: InternalTexture, onlyInternalTexture: boolean) {
+        // TODO change to replace framebuffer
+        // if (!onlyInternalTexture) {
+        //     this.getGBuffer().replaceTexture(texture, 0);
+        // }
+
+        this._multiRenderTarget._texture = internalTexture;
+    }
+
     /**
      * Gets the render list (meshes to be rendered) used in the G buffer.
      */
@@ -131,8 +226,12 @@ export class GeometryBufferRenderer {
      */
     public set enablePosition(enable: boolean) {
         this._enablePosition = enable;
-        this.dispose();
-        this._createRenderTargets();
+
+        // PrePass handles index and texture links
+        if (!this._linkedWithPrePass) {
+            this.dispose();
+            this._createRenderTargets();            
+        }
     }
 
     /**
@@ -152,8 +251,10 @@ export class GeometryBufferRenderer {
             this._previousTransformationMatrices = {};
         }
 
-        this.dispose();
-        this._createRenderTargets();
+        if (!this._linkedWithPrePass) {
+            this.dispose();
+            this._createRenderTargets();            
+        }
     }
 
     /**
@@ -168,8 +269,11 @@ export class GeometryBufferRenderer {
      */
     public set enableReflectivity(enable: boolean) {
         this._enableReflectivity = enable;
-        this.dispose();
-        this._createRenderTargets();
+
+        if (!this._linkedWithPrePass) {
+            this.dispose();
+            this._createRenderTargets();            
+        }
     }
 
     /**
@@ -261,6 +365,12 @@ export class GeometryBufferRenderer {
             }
         }
 
+        // PrePass
+        if (this._linkedWithPrePass) {
+            defines.push("#define PREPASS");
+            defines.push("#define DEPTHNORMAL_INDEX " + this._depthNormalIndex);
+        }
+
         // Buffers
         if (this._enablePosition) {
             defines.push("#define POSITION");
@@ -318,7 +428,11 @@ export class GeometryBufferRenderer {
         }
 
         // Setup textures count
-        defines.push("#define RENDER_TARGET_COUNT " + this._multiRenderTarget.textures.length);
+        if (this._linkedWithPrePass) {
+            defines.push("#define RENDER_TARGET_COUNT " + this._attachments.length);
+        } else {
+            defines.push("#define RENDER_TARGET_COUNT " + this._multiRenderTarget.textures.length);
+        }
 
         // Get correct effect
         var join = defines.join("\n");
@@ -372,9 +486,8 @@ export class GeometryBufferRenderer {
         this.getGBuffer().dispose();
     }
 
-    protected _createRenderTargets(): void {
-        var engine = this._scene.getEngine();
-        var count = 2;
+    private _assignRenderTargetIndices() : number {
+        let count = 2;
 
         if (this._enablePosition) {
             this._positionIndex = count;
@@ -391,6 +504,13 @@ export class GeometryBufferRenderer {
             count++;
         }
 
+        return count
+    }
+
+    protected _createRenderTargets(): void {
+        var engine = this._scene.getEngine();
+        var count = this._assignRenderTargetIndices();
+
         this._multiRenderTarget = new MultiRenderTarget("gBuffer",
             { width: engine.getRenderWidth() * this._ratio, height: engine.getRenderHeight() * this._ratio }, count, this._scene,
             { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_FLOAT });
@@ -526,6 +646,13 @@ export class GeometryBufferRenderer {
         this._multiRenderTarget.customRenderFunction = (opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void => {
             var index;
 
+            if (this._linkedWithPrePass) {
+                if (!this._prePassRenderer.enabled) {
+                    return;
+                }
+                this._scene.getEngine().bindAttachments(this._attachments);
+            }
+
             if (depthOnlySubMeshes.length) {
                 engine.setColorWrite(false);
                 for (index = 0; index < depthOnlySubMeshes.length; index++) {

+ 65 - 6
src/Rendering/prePassRenderer.ts

@@ -131,7 +131,7 @@ export class PrePassRenderer {
     }
 
     private _geometryBuffer: Nullable<GeometryBufferRenderer>;
-    private _useGeometryBufferFallback = false;
+    private _useGeometryBufferFallback = true;
     /**
      * Uses the geometry buffer renderer as a fallback for non prepass capable effects
      */
@@ -152,7 +152,12 @@ export class PrePassRenderer {
             }
 
             this._geometryBuffer.renderList = [];
+            this._geometryBuffer.linkPrePassRenderer(this);
+            this._updateGeometryBufferLayout();
         } else {
+            if (this._geometryBuffer) {
+                this._geometryBuffer.unlinkPrePassRenderer();
+            }
             this._geometryBuffer = null;
             this._scene.disableGeometryBufferRenderer();
         }
@@ -167,7 +172,6 @@ export class PrePassRenderer {
         this._engine = scene.getEngine();
 
         PrePassRenderer._SceneComponentInitialization(this._scene);
-        this.useGeometryBufferFallback = true;
         this._resetLayout();
     }
 
@@ -193,6 +197,11 @@ export class PrePassRenderer {
             { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: this._mrtFormats });
         this.prePassRT.samples = 1;
 
+        if (this._useGeometryBufferFallback && !this._geometryBuffer) {
+            // Initializes the link with geometry buffer
+            this.useGeometryBufferFallback = true;
+        }
+
         this.imageProcessingPostProcess = new ImageProcessingPostProcess("sceneCompositionPass", 1, null, undefined, this._engine);
         this.imageProcessingPostProcess.autoClear = false;
     }
@@ -218,7 +227,7 @@ export class PrePassRenderer {
                 if (this._geometryBuffer) {
                     const material = subMesh.getMaterial();
                     if (material && this.excludedMaterials.indexOf(material) === -1) {
-                        this._geometryBuffer.renderList.push(subMesh.getRenderingMesh());
+                        this._geometryBuffer.renderList!.push(subMesh.getRenderingMesh());
                     }
                 }
             }
@@ -234,7 +243,7 @@ export class PrePassRenderer {
         }
 
         if (this._geometryBuffer) {
-            this._geometryBuffer.renderList.length = 0;
+            this._geometryBuffer.renderList!.length = 0;
         }
 
         this._bindFrameBuffer();
@@ -262,6 +271,7 @@ export class PrePassRenderer {
         if (width !== requiredWidth || height !== requiredHeight) {
             this.prePassRT.resize({ width: requiredWidth, height: requiredHeight });
 
+            this._updateGeometryBufferLayout();
             this._bindPostProcessChain();
         }
     }
@@ -292,7 +302,7 @@ export class PrePassRenderer {
             // Clearing other attachment with 0 on all other attachments
             this._engine.bindAttachments(this._clearAttachments);
             this._engine.clear(this._clearColor, true, false, false);
-            this._engine.bindAttachments(this._multiRenderAttachments);
+            this._engine.bindAttachments(this._defaultAttachments);
         }
     }
 
@@ -305,6 +315,54 @@ export class PrePassRenderer {
         }
     }
 
+    private _updateGeometryBufferLayout() {
+        if (this._geometryBuffer) {
+            this._geometryBuffer.resetLayout();
+
+            const attachments = this._defaultAttachments.slice();
+            const gl = this._scene.getEngine()._gl;
+            attachments[0] = gl.NONE;
+
+            // Depth + normal is always index 0 in geometry buffer
+            let index = this.getIndex(Constants.PREPASS_DEPTHNORMAL_TEXTURE_TYPE);
+            if (index !== -1) {
+                this._geometryBuffer.replaceDepthTexture(this.prePassRT.textures[index], this.prePassRT.getInternalTexture()!, false);
+            } else {
+                this._geometryBuffer.replaceDepthTexture(this.prePassRT.textures[0], this.prePassRT.getInternalTexture()!, true);
+            }
+
+            const matches = [
+                {
+                    prePassConstant: Constants.PREPASS_DEPTHNORMAL_TEXTURE_TYPE,
+                    geometryBufferConstant: GeometryBufferRenderer.DEPTHNORMAL_TEXTURE_TYPE,
+                },
+                {
+                    prePassConstant: Constants.PREPASS_POSITION_TEXTURE_TYPE,
+                    geometryBufferConstant: GeometryBufferRenderer.POSITION_TEXTURE_TYPE,
+                },
+                {
+                    prePassConstant: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,
+                    geometryBufferConstant: GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE,
+                },
+                {
+                    prePassConstant: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,
+                    geometryBufferConstant: GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE,
+                }
+            ];
+
+            // replace textures in the geometryBuffer RT
+            for (let i = 0; i < matches.length; i++) {
+                const index = this._mrtLayout.indexOf(matches[i].prePassConstant);
+                if (index !== -1) {
+                    this._geometryBuffer.replaceTexture(this.prePassRT.textures[index], matches[i].geometryBufferConstant, index);
+                    attachments[index] = (<any>gl)["COLOR_ATTACHMENT" + index];
+                }
+            }
+
+            this._geometryBuffer.setAttachments(attachments);
+        }
+    }
+
     /**
      * Adds an effect configuration to the prepass.
      * If an effect has already been added, it won't add it twice and will return the configuration
@@ -346,6 +404,7 @@ export class PrePassRenderer {
             this.prePassRT.updateCount(this.mrtCount, { types: this._mrtFormats });
         }
 
+        this._updateGeometryBufferLayout();
         this._resetPostProcessChain();
 
         for (let i = 0; i < this._effectConfigurations.length; i++) {
@@ -466,7 +525,7 @@ export class PrePassRenderer {
 
         if (!this.enabled) {
             // Prepass disabled, we render only on 1 color attachment
-            this._engine.bindAttachments([this._engine._gl.COLOR_ATTACHMENT0]);
+            this._engine.bindAttachments([this._engine._gl.BACK]);
         }
     }
 

+ 10 - 5
src/Shaders/geometry.fragment.fx

@@ -53,15 +53,20 @@ void main() {
 		discard;
     #endif
 
-    gl_FragData[0] = vec4(vViewPos.z / vViewPos.w, 0.0, 0.0, 1.0);
-    //color0 = vec4(vViewPos.z / vViewPos.w, 0.0, 0.0, 1.0);
-
+    vec3 normalOutput;
     #ifdef BUMP
     vec3 normalW = normalize(vNormalW);
     #include<bumpFragment>
-    gl_FragData[1] = vec4(normalize(vec3(vWorldView * vec4(normalW, 0.0))), 1.0);
+    normalOutput = normalize(vec3(vWorldView * vec4(normalW, 0.0)));
+    #else
+    normalOutput = normalize(vNormalV);
+    #endif
+
+    #ifdef PREPASS
+    gl_FragData[DEPTHNORMAL_INDEX] = vec4(vViewPos.z / vViewPos.w, normalOutput);
     #else
-    gl_FragData[1] = vec4(normalize(vNormalV), 1.0);
+    gl_FragData[0] = vec4(vViewPos.z / vViewPos.w, 0.0, 0.0, 1.0);
+    gl_FragData[1] = vec4(normalOutput, 1.0);
     #endif
 
     #ifdef POSITION