Browse Source

Fix Prefiltering

sebavan 5 năm trước cách đây
mục cha
commit
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: