• Content Count

  • Joined

  • Last visited

About BMWPilote

  • Rank
    Advanced Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I need to freeze my materials for my static scene. However I am not sure when to freeze them safely? I tried to call freezeMateiral right after assigning the textures. But the result was that the textures could never been displayed. I tried to free them using BABYLON.Texture.WhenAllReady callback. But it did not worker either. I needed to add a large timeout to make sure that all the materials were ready. So my question is whether we have a way by which we can 100% be sure that the material is really ready (including opengl texture) so that I can call freeze safely?
  2. No. I just have PBR materials + shadow mapping + A post pipeline. Very simple stuff.
  3. Hi Sebavan, thank you for the answer. I would like to make a playground but the messages occur only when my viewer is integrated into a React application. Could it be the fact that the render loop is started too early?
  4. BMWPilote

    FXAA quality

    I am really interested. What kind of AA will you integrate? SMAA?
  5. BMWPilote

    FXAA quality

    Is it the same as SSAA?
  6. BMWPilote

    FXAA quality

    With FXAA without FXAA Sorry I don't really have time to write a playground as all my code is in Typescript. But please look at the above two screenshots. We can see that FXAA does have some benefit but really not good enough. Any idea? Thanks
  7. BMWPilote

    FXAA quality

    Yes I am using it through a pipeline.
  8. BMWPilote

    FXAA quality

    Hi Babylonjs masters, I would like to know if it is as expected that FXAA gives quite poor quality. Please take a look at the screenshot. It seems that the quality is really poor. Did I miss something so that the FXAA does not work as it should be? I tried both half float and float as texture type but it did not change anything... Note that I cannot use MSAA for performance reason...
  9. Hello folks, When I launch my app, I always get a lot of such errors. Although later the app can work correctly, I would like to solve the problem. I guess the reason might be starting the render loop before the default frame buffer is ready. My question is how can I know that the frame buffer is ready so that I can start the render loop at the right timing?
  10. There is one thing that I am still confused which is the "reusable" flag. Although I don't use it. I am not sure how to modify the code to adapt to MRT.
  11. Yes, I know. So I modified the shader as below. gl_FragData[0] = finalColor; #if defined(ID_BUFFER) #if defined(PACK_ID) gl_FragData[1] = dbId_modelId; #else gl_FragData[1] = vec4(dbId, modelId, 0.0, 1.0); #endif #endif #ifndef ALPHABLEND #ifdef LOGARITHMICDEPTH gl_FragData[DEPTH_INDEX] = vec4(vDepthMetric, log2(vFragmentDepth) * logarithmicDepthConstant * 0.5, vViewPos.z, 1.0); #else gl_FragData[DEPTH_INDEX] = vec4(vDepthMetric, gl_FragCoord.z, vViewPos.z, 1.0); #endif gl_FragData[DEPTH_INDEX + 1] = vec4(normalize(vNormalV), 1.0); #endif And I wrote a MRTPostProcess import * as BABYLON from 'babylonjs'; export class MRTPostProcess extends BABYLON.PostProcess { private _textureCount: number; private _externalTextures: BABYLON.Texture[]; constructor(name: string, textureCount: number, fragmentUrl: string, parameters: BABYLON.Nullable<string[]>, samplers: BABYLON.Nullable<string[]>, options: number | BABYLON.PostProcessOptions, camera: BABYLON.Nullable<BABYLON.Camera>, samplingMode: number = BABYLON.Texture.NEAREST_SAMPLINGMODE, engine?: BABYLON.Engine, reusable?: boolean, defines: BABYLON.Nullable<string> = null, textureType: number = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, vertexUrl: string = "postprocess", indexParameters?: any, blockCompilation = false) { super(name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation); this._textureCount = textureCount; this.onAfterRenderObservable.add(() => { this.unbindFrameBuffer(engine); }); } get textures(): BABYLON.SmartArray<BABYLON.InternalTexture> { return this._textures; } get externalTextures(): BABYLON.Texture[] { return this._externalTextures; } private _createExternalTextures(scene: BABYLON.Scene): void { this._externalTextures = []; for (var i = 0; i < this._textureCount; i++) { var texture = new BABYLON.Texture(null, scene, false, false, this.renderTargetSamplingMode); texture._texture =[i]; this._externalTextures.push(texture); } } activate(camera: BABYLON.Nullable<BABYLON.Camera>, sourceTexture: BABYLON.Nullable<BABYLON.InternalTexture> = null, forceDepthStencil?: boolean): BABYLON.InternalTexture { camera = camera || this._camera; var scene = camera.getScene(); var engine = scene.getEngine(); var maxSize = engine.getCaps().maxTextureSize; var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * <number>this._options) | 0; var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * <number>this._options) | 0; // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen var webVRCamera = (<BABYLON.WebVRFreeCamera>camera.parent); if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) { requiredWidth /= 2; } var desiredWidth = ((<BABYLON.PostProcessOptions>this._options).width || requiredWidth); var desiredHeight = (<BABYLON.PostProcessOptions>this._options).height || requiredHeight; if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) { if (this.adaptScaleToCurrentViewport) { let currentViewport = engine.currentViewport; if (currentViewport) { desiredWidth *= currentViewport.width; desiredHeight *= currentViewport.height; } } if (this.renderTargetSamplingMode === BABYLON.Texture.TRILINEAR_SAMPLINGMODE || this.alwaysForcePOT) { if (!(<BABYLON.PostProcessOptions>this._options).width) { desiredWidth = engine.needPOTTextures ? BABYLON.Tools.GetExponentOfTwo(desiredWidth, maxSize, this.scaleMode) : desiredWidth; } if (!(<BABYLON.PostProcessOptions>this._options).height) { desiredHeight = engine.needPOTTextures ? BABYLON.Tools.GetExponentOfTwo(desiredHeight, maxSize, this.scaleMode) : desiredHeight; } } if (this.width !== desiredWidth || this.height !== desiredHeight) { if (this._textures.length > 0) { for (var i = 0; i < this._textures.length; i++) { this._engine._releaseTexture([i]); } this._textures.reset(); } this.width = desiredWidth; this.height = desiredHeight; let textureSize = { width: this.width, height: this.height }; var types = []; var samplingModes = []; for (var i = 0; i < this._textureCount; i++) { types.push(this._textureType); samplingModes.push(this.renderTargetSamplingMode); } let textureOptions = { generateMipMaps: false, generateDepthBuffer: forceDepthStencil || camera._postProcesses.indexOf(this) === 0, generateStencilBuffer: (forceDepthStencil || camera._postProcesses.indexOf(this) === 0) && this._engine.isStencilEnable, samplingModes: samplingModes, types: types, textureCount: this._textureCount }; this._textures.concat(this._engine.createMultipleRenderTarget(textureSize, textureOptions)); this._createExternalTextures(scene); if (this._reusable) { this._textures.concat(this._engine.createMultipleRenderTarget(textureSize, textureOptions)); } this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height); this.onSizeChangedObservable.notifyObservers(this); } this._textures.forEach(texture => { if (texture.samples !== this.samples) { this._engine.updateRenderTargetTextureSampleCount(texture, this.samples); } }); } var target: BABYLON.InternalTexture; if (this._shareOutputWithPostProcess) { target = this._shareOutputWithPostProcess.inputTexture; } else if (this._forcedOutputTexture) { target = this._forcedOutputTexture; this.width = this._forcedOutputTexture.width; this.height = this._forcedOutputTexture.height; } else { target = this.inputTexture; } // Bind the input of this post process to be used as the output of the previous post process. if (this.enablePixelPerfectMode) { this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight); this._engine.bindFramebuffer(target, 0, requiredWidth, requiredHeight, true); } else { this._scaleRatio.copyFromFloats(1, 1); this._engine.bindFramebuffer(target, 0, undefined, undefined, true); } this.onActivateObservable.notifyObservers(camera); // Clear if (this.autoClear && this.alphaMode === BABYLON.Engine.ALPHA_DISABLE) { this._engine.clear(this.clearColor ? this.clearColor : scene.clearColor, true, true, true); } if (this._reusable) { this._currentRenderTextureInd = (this._currentRenderTextureInd + this._textureCount) % (this._textureCount + 1); } return target; } unbindFrameBuffer(engine: BABYLON.Engine): void { let internalTextures: BABYLON.InternalTexture[] = []; for (var i = 0; i < this._textureCount; i++) { internalTextures.push([i]); } engine.unBindMultiColorAttachmentFramebuffer(internalTextures, false, () => { }); } } It seems to work so far...
  12. I don’t want to create any Post process. I just want to have color depth and normal in one pass instead of two.
  13. I found this ( But it seems that this works only with WebGL1.0 + extension. How can it work with WebGL2.0? Is it possible to overwrite the below function so that I can inject the "MRT stuff"? Another way I am thinking is that if I write a class which inherit PostProcess and I override the activate function. Instead of creating a RenderTargetTexture, I can create a MultiRenderTargetTexutre. Is it feasible though? I really need this because performance is the first priority in my project. Thanks you in advance.
  14. If we use post process (such as SSAO), we might want to render directly the depth and the normal when doing the main pass. Then we can avoid doing another pass by GeometryBufferRenderer. I know that we don't support the feature with built-in shaders. My question is if I use my own shaders. Is it feasible in the current Babylon code base? I can overwrite Babylon's built-in classes if needed.