瀏覽代碼

Fix Prefiltering

sebavan 5 年之前
父節點
當前提交
b9b7e0aa5b

+ 22 - 10
src/Materials/Textures/Filtering/hdrFiltering.ts

@@ -63,9 +63,17 @@ export class HDRFiltering {
     }
 
     private _createRenderTarget(size: number): InternalTexture {
+        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;
+        if (this._engine.getCaps().textureHalfFloatRender) {
+            textureType = Constants.TEXTURETYPE_HALF_FLOAT;
+        }
+        else if (this._engine.getCaps().textureFloatRender) {
+            textureType = Constants.TEXTURETYPE_FLOAT;
+        }
+
         const texture = this._engine.createRenderTargetCubeTexture(size, {
             format: Constants.TEXTUREFORMAT_RGBA,
-            type: Constants.TEXTURETYPE_FLOAT,
+            type: textureType,
             generateMipMaps: false,
             generateDepthBuffer: false,
             generateStencilBuffer: false,
@@ -82,7 +90,6 @@ export class HDRFiltering {
     }
 
     private _prefilterInternal(texture: BaseTexture): BaseTexture {
-        // const nbRoughnessStops = 2;
         const width = texture.getSize().width;
         const mipmapsCount = Math.round(Scalar.Log2(width)) + 1;
 
@@ -129,11 +136,17 @@ export class HDRFiltering {
                 effect.setFloat("linearRoughness", alpha);
 
                 this._effectRenderer.draw();
-                this._effectRenderer.restoreStates();
             }
         }
 
-        texture._texture!._webGLTexture = outputTexture._webGLTexture;
+        // Cleanup
+        this._effectRenderer.restoreStates();
+        this._engine.restoreDefaultFramebuffer();
+        this._engine._releaseFramebufferObjects(outputTexture);
+        this._engine._releaseTexture(texture._texture!);
+
+        // Internal Swap
+        outputTexture._swapAndDie(texture._texture!);
         return texture;
     }
 
@@ -178,9 +191,11 @@ export class HDRFiltering {
       * @param onFinished Callback when filtering is done
       * @return Promise called when prefiltering is done
       */
-    public prefilter(texture: BaseTexture, onFinished?: () => void) {
+    public prefilter(texture: BaseTexture, onFinished: Nullable<() => void> = null) {
         return new Promise((resolve) => {
-            const callback = () => {
+            this._effectRenderer = new EffectRenderer(this._engine);
+            this._effectWrapper = this._createEffect(texture);
+            this._effectWrapper.effect.executeWhenCompiled(() => {
                 this._prefilterInternal(texture);
                 this._effectRenderer.dispose();
                 this._effectWrapper.dispose();
@@ -188,10 +203,7 @@ export class HDRFiltering {
                 if (onFinished) {
                     onFinished();
                 }
-            };
-
-            this._effectRenderer = new EffectRenderer(this._engine);
-            this._effectWrapper = this._createEffect(texture, callback);
+            });
         });
     }
 }

+ 4 - 2
src/Materials/Textures/hdrCubeTexture.ts

@@ -117,7 +117,7 @@ export class HDRCubeTexture extends BaseTexture {
      * @param gammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
      * @param prefilterOnLoad Prefilters HDR texture to allow use of this texture as a PBR reflection texture.
      */
-    constructor(url: string, sceneOrEngine: Scene | ThinEngine, size: number, noMipmap = false, generateHarmonics = true, gammaSpace = false, prefilterOnLoad = true, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
+    constructor(url: string, sceneOrEngine: Scene | ThinEngine, size: number, noMipmap = false, generateHarmonics = true, gammaSpace = false, prefilterOnLoad = false, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
         super(sceneOrEngine);
 
         if (!url) {
@@ -244,7 +244,9 @@ export class HDRCubeTexture extends BaseTexture {
         if (this._prefilterOnLoad) {
             const previousOnLoad = this._onLoad;
             const hdrFiltering = new HDRFiltering(engine);
-            this._onLoad = () => hdrFiltering.prefilter(this, previousOnLoad || undefined);
+            this._onLoad = () => {
+                hdrFiltering.prefilter(this, previousOnLoad);
+            };
         }
 
         this._texture = engine.createRawCubeTextureFromUrl(this.url, this.getScene(), this._size,

+ 13 - 2
src/Probes/reflectionProbe.ts

@@ -91,9 +91,20 @@ export class ReflectionProbe {
         }
         this._scene.reflectionProbes.push(this);
 
-        this._renderTargetTexture = new RenderTargetTexture(name, size, scene, generateMipMaps, true, useFloat ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_INT, true);
+        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;
+        if (useFloat) {
+            const caps = this._scene.getEngine().getCaps();
+            if (caps.textureHalfFloatRender) {
+                textureType = Constants.TEXTURETYPE_HALF_FLOAT;
+            }
+            else if (caps.textureFloatRender) {
+                textureType = Constants.TEXTURETYPE_FLOAT;
+            }
+        }
+        this._renderTargetTexture = new RenderTargetTexture(name, size, scene, generateMipMaps, true, textureType, true);
+
         this._renderTargetTexture.realTimeFiltering = true;
-        
+
         this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex: number) => {
             switch (faceIndex) {
                 case 0: