فهرست منبع

Fix Prefiltering

sebavan 5 سال پیش
والد
کامیت
b9b7e0aa5b
3فایلهای تغییر یافته به همراه39 افزوده شده و 14 حذف شده
  1. 22 10
      src/Materials/Textures/Filtering/hdrFiltering.ts
  2. 4 2
      src/Materials/Textures/hdrCubeTexture.ts
  3. 13 2
      src/Probes/reflectionProbe.ts

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

@@ -63,9 +63,17 @@ export class HDRFiltering {
     }
     }
 
 
     private _createRenderTarget(size: number): InternalTexture {
     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, {
         const texture = this._engine.createRenderTargetCubeTexture(size, {
             format: Constants.TEXTUREFORMAT_RGBA,
             format: Constants.TEXTUREFORMAT_RGBA,
-            type: Constants.TEXTURETYPE_FLOAT,
+            type: textureType,
             generateMipMaps: false,
             generateMipMaps: false,
             generateDepthBuffer: false,
             generateDepthBuffer: false,
             generateStencilBuffer: false,
             generateStencilBuffer: false,
@@ -82,7 +90,6 @@ export class HDRFiltering {
     }
     }
 
 
     private _prefilterInternal(texture: BaseTexture): BaseTexture {
     private _prefilterInternal(texture: BaseTexture): BaseTexture {
-        // const nbRoughnessStops = 2;
         const width = texture.getSize().width;
         const width = texture.getSize().width;
         const mipmapsCount = Math.round(Scalar.Log2(width)) + 1;
         const mipmapsCount = Math.round(Scalar.Log2(width)) + 1;
 
 
@@ -129,11 +136,17 @@ export class HDRFiltering {
                 effect.setFloat("linearRoughness", alpha);
                 effect.setFloat("linearRoughness", alpha);
 
 
                 this._effectRenderer.draw();
                 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;
         return texture;
     }
     }
 
 
@@ -178,9 +191,11 @@ export class HDRFiltering {
       * @param onFinished Callback when filtering is done
       * @param onFinished Callback when filtering is done
       * @return Promise called when prefiltering 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) => {
         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._prefilterInternal(texture);
                 this._effectRenderer.dispose();
                 this._effectRenderer.dispose();
                 this._effectWrapper.dispose();
                 this._effectWrapper.dispose();
@@ -188,10 +203,7 @@ export class HDRFiltering {
                 if (onFinished) {
                 if (onFinished) {
                     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 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.
      * @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);
         super(sceneOrEngine);
 
 
         if (!url) {
         if (!url) {
@@ -244,7 +244,9 @@ export class HDRCubeTexture extends BaseTexture {
         if (this._prefilterOnLoad) {
         if (this._prefilterOnLoad) {
             const previousOnLoad = this._onLoad;
             const previousOnLoad = this._onLoad;
             const hdrFiltering = new HDRFiltering(engine);
             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,
         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._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.realTimeFiltering = true;
-        
+
         this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex: number) => {
         this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex: number) => {
             switch (faceIndex) {
             switch (faceIndex) {
                 case 0:
                 case 0: