BlackMojito

Members
  • Content count

    131
  • Joined

  • Last visited

About BlackMojito

  • Rank
    Advanced Member
  • Birthday 03/23/1987

Profile Information

  • Gender
    Male
  • Location
    Shanghai
  1. About GeometryBufferRenderer and MRT

    Hum....I am sorry. But how can I "discard" only "depth" for transparent meshes in this shader ?
  2. Yes sir but I need to handle highlighting and selection too. This meas I need to maintain two scene graphs ? For big models I am not sure if the limited browser memory can allow it
  3. Is the sorting done only once then the new order will always be used from that moment, or we need to execute sorting every frame ? As my meshes are mostly static. Is the sorting is done only once, it will be so cool for me
  4. Should I use Occlusion Queries

    Thanks! It is really useful for me to implement progressive rendering when the model is too big. I will read the source code too.
  5. About GeometryBufferRenderer and MRT

    OK but I would like to say how is it possible? If we want position for transparent objects too, their depth will also be written, right?
  6. Hi Folks, Just by curiosity, how do we avoid expensive glUseProgram calls internally in Babylonjs? Do we sort meshes by shader so that we can minimize shader changes?
  7. With MRT support, we should be able to render directly color buffer, depth buffer, normal buffer in one pass. Is there a way to implement it? With ShaderMaterial, I can write whatever I want but how can I customize Babylonjs (scene, camera etc.) so that I can write to a MultiRenderTarget just as GeometryBufferRenderer? I really want to gain every millisecond in my app. Thanks in advance.
  8. Transparent objects are ignored in GeometryBufferRenderer. I know it is for that we can see ambient occlusion though transparent objects. But this class allows us to write positions too (the 3rd buffer). How can I get positions for transparent objects though? I mean I would like to ignore depth values and normal values for those transparent meshes but I want their positions in the output. Is it possible?
  9. Should I use Occlusion Queries

    So cool! Could you please tell me where I can find related code? Or would you mind give me some simple sample code, please?
  10. Should I use Occlusion Queries

    Hi @Deltakosh, is the container available now in alpha7?
  11. No worry. Super thanks for the quick fix
  12. About ground shadow

    Wow! Thanks!
  13. import * as BABYLON from 'babylonjs' import { RenderOptions, SceneOptions } from '../../Preferences' import { RenderScene } from '../../Scene/RenderScene' import * as Capabilities from '../Device/Capabilities' import * as ssao_frag from '../Shaders/glsl/custom_ssao_frag.glsl' import * as gamma_correction_frag from '../Shaders/glsl/gamma_correction_frag.glsl' import * as final_merge_frag from '../Shaders/glsl/final_merge_frag.glsl'; import * as WebUtils from '../../../Utils/WebUtils' export class BasicPostProcessRenderPipeline extends BABYLON.PostProcessRenderPipeline { private _renderScene: RenderScene; private _selectionGroupRenderTarget: BABYLON.RenderTargetTexture; private _overlayGroupRenderTarget: BABYLON.RenderTargetTexture; // SSAO readonly SSAOOriginalSceneColorEffect: string = 'SSAOOriginalSceneColorEffect'; readonly SSAORenderEffect: string = 'SSAORenderEffect'; readonly SSAOBlurHRenderEffect: string = 'SSAOBlurHRenderEffect'; readonly SSAOBlurVRenderEffect: string = 'SSAOBlurVRenderEffect'; readonly SSAOCombineRenderEffect: string = 'SSAOCombineRenderEffect'; private _originalColorPostProcess: BABYLON.PassPostProcess; private _ssaoPostProcess: BABYLON.PostProcess; private _blurHPostProcess: BABYLON.BlurPostProcess; private _blurVPostProcess: BABYLON.BlurPostProcess; private _ssaoCombinePostProcess: BABYLON.PostProcess; private _firstUpdate: boolean = true; private _ssaoFallOff: number; private _ssaoArea: number; private _ssaoRadius: number; private _ssaoTotalStrength: number; private _ssaoBase: number; private _depthTexture: BABYLON.Texture; private _normalTexture: BABYLON.Texture | null = null; private _randomTexture: BABYLON.DynamicTexture; // FXAA readonly FxaaPostProcessId: string = 'FxaaPostProcessEffect'; private _fxaaEnabled: boolean = true; private _fxaa: BABYLON.FxaaPostProcess; // Tone Mapping readonly ToneMappingPostProcessId: string = 'ToneMappingPostProcessEffect'; private _toneMappingEnabled: boolean = true; private _toneMapping: BABYLON.TonemapPostProcess; // Final Merge readonly FinalMergePostProcessId: string = 'FinalMergePostProcessEffect'; private _finalMerge: BABYLON.PostProcess; // Gamma Correction readonly GammaCorrectionPostProcessId: string = 'GammaCorrectionPostProcessEffect'; private _gammaCorrection: BABYLON.PostProcess; private _defaultPipelineTextureType: number; private _hdr: boolean = false; /** * @constructor * @param {string} name - The rendering pipeline name * @param {BABYLON.Scene} scene - The scene linked to this pipeline * @param {any} ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, blurRatio: 1.0 } * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to */ constructor(name: string, renderScene: RenderScene, ratio: any, cameras?: BABYLON.Camera[], hdr?: boolean) { super(renderScene.scene.getEngine(), name); this._renderScene = renderScene; var caps = this.internalScene.getEngine().getCaps(); if (hdr) { this._hdr = hdr && (caps.textureHalfFloatRender || caps.textureFloatRender); } if (this._hdr) { if (caps.textureHalfFloatRender) { this._defaultPipelineTextureType = BABYLON.Engine.TEXTURETYPE_HALF_FLOAT; } else if (caps.textureFloatRender) { this._defaultPipelineTextureType = BABYLON.Engine.TEXTURETYPE_FLOAT; } } else { this._defaultPipelineTextureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; } this._ssaoFallOff = RenderOptions.ssaoFallOff; this._ssaoArea = RenderOptions.ssaoArea; this._ssaoRadius = RenderOptions.ssaoRadius; this._ssaoTotalStrength = RenderOptions.ssaoTotalStrength; this._ssaoBase = RenderOptions.ssaoBase; var ssaoRatio = ratio.ssaoRatio || ratio; var combineRatio = ratio.combineRatio || ratio; // Set up assets this._createRandomTexture(); if (Capabilities.isMRTSupported()) { let geometryBufferRenderer = <BABYLON.GeometryBufferRenderer>renderScene.scene.enableGeometryBufferRenderer(); this._depthTexture = geometryBufferRenderer.getGBuffer().textures[0]; this._normalTexture = geometryBufferRenderer.getGBuffer().textures[1]; } else { let depthRenderer = this.internalScene.enableDepthRenderer(); this._depthTexture = depthRenderer.getDepthMap(); } this._createColorBufferPostProcess(); this._createSSAOPostProcess(ssaoRatio); this._createBlurPostProcess(ssaoRatio); this._createSSAOCombinePostProcess(combineRatio); this._createFinalMergePostProcess(); this._createFXAAPostProcess(); this._createToneMappingPostProcess(); this._createGammaCorrectionPostProcess(); // Set up pipeline this._setupPipeline(); // Finish this.internalScene.postProcessRenderPipelineManager.addPipeline(this); if (cameras) { this.internalScene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras); } this._createSelectionRenderTarget(); this._createOverlayRenderTarget(); } private get internalScene(): BABYLON.Scene { return this._renderScene.scene; } get fxaaEnabled(): boolean { return this._fxaaEnabled; } set fxaaEnabled(enabled: boolean) { if (this._fxaaEnabled === enabled) { return; } this._fxaaEnabled = enabled; this._setupPipeline(); } get ssaoFallOff(): number { return this._ssaoFallOff; } set ssaoFallOff(value: number) { this._ssaoFallOff = value; } get ssaoArea(): number { return this._ssaoArea; } set ssaoArea(value: number) { this._ssaoArea = value; } get ssaoRadius(): number { return this._ssaoRadius; } set ssaoRadius(value: number) { this._ssaoRadius = value; } get ssaoTotalStrength(): number { return this._ssaoTotalStrength; } set ssaoTotalStrength(value: number) { this._ssaoTotalStrength = value; } get ssaoBase(): number { return this._ssaoBase; } set ssaoBase(value: number) { this._ssaoBase = value; } enableSSAO(enabled: boolean): void { if (enabled) { this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.SSAORenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.SSAOBlurHRenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.SSAOBlurVRenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.SSAOCombineRenderEffect, this.internalScene.activeCamera); } else { this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.SSAORenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.SSAOBlurHRenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.SSAOBlurVRenderEffect, this.internalScene.activeCamera); this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.SSAOCombineRenderEffect, this.internalScene.activeCamera); } } enableToneMapping(enabled: boolean): void { if (enabled) { this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.ToneMappingPostProcessId, this.internalScene.activeCamera); } else { this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.ToneMappingPostProcessId, this.internalScene.activeCamera); } } enableGammaCorrection(enabled: boolean): void { if (enabled) { this.internalScene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.GammaCorrectionPostProcessId, this.internalScene.activeCamera); } else { this.internalScene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.GammaCorrectionPostProcessId, this.internalScene.activeCamera); } } private _setupPipeline(): void { this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.SSAOOriginalSceneColorEffect, () => { return this._originalColorPostProcess; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.SSAORenderEffect, () => { return this._ssaoPostProcess; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.SSAOBlurHRenderEffect, () => { return this._blurHPostProcess; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.SSAOBlurVRenderEffect, () => { return this._blurVPostProcess; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.SSAOCombineRenderEffect, () => { return this._ssaoCombinePostProcess; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.ToneMappingPostProcessId, () => { return this._toneMapping; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.FinalMergePostProcessId, () => { return this._finalMerge; }, true)); if (this.fxaaEnabled) { this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.FxaaPostProcessId, () => { return this._fxaa; }, true)); } this.addEffect(new BABYLON.PostProcessRenderEffect(this.internalScene.getEngine(), this.GammaCorrectionPostProcessId, () => { return this._gammaCorrection; }, true)); } // Public Methods /** * Removes the internal pipeline assets and detatches the pipeline from the scene cameras */ dispose(disableDepthRender: boolean = false): void { for (var i = 0; i < this.internalScene.cameras.length; i++) { var camera = this.internalScene.cameras[i]; this._originalColorPostProcess.dispose(camera); this._ssaoPostProcess.dispose(camera); this._blurHPostProcess.dispose(camera); this._blurVPostProcess.dispose(camera); this._ssaoCombinePostProcess.dispose(camera); this._fxaa.dispose(camera); this._toneMapping.dispose(camera); this._finalMerge.dispose(camera); this._gammaCorrection.dispose(camera); } this._randomTexture.dispose(); if (disableDepthRender) { this.internalScene.disableDepthRenderer(); } this.internalScene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this.internalScene.cameras); this._selectionGroupRenderTarget.dispose(); this._overlayGroupRenderTarget.dispose(); super.dispose(); } private _createSelectionRenderTarget(): void { let canvas = this.internalScene.getEngine().getRenderingCanvas(); this._selectionGroupRenderTarget = new BABYLON.RenderTargetTexture('selectionRenderTarget', { width: canvas.width, height: canvas.height }, this.internalScene, false, false, this._defaultPipelineTextureType, false, BABYLON.Texture.BILINEAR_SAMPLINGMODE); this._selectionGroupRenderTarget.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; this._selectionGroupRenderTarget.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE; this._selectionGroupRenderTarget.hasAlpha = true; this._selectionGroupRenderTarget.clearColor = new BABYLON.Color4(0.0, 0.0, 0.0, 0.0); this.internalScene.customRenderTargets.push(this._selectionGroupRenderTarget); this._selectionGroupRenderTarget.onBeforeRender = () => { let overlayMeshes = this._renderScene.secondarySceneRoot.getChildMeshes().slice(); overlayMeshes = overlayMeshes.filter(e => e.renderingGroupId === 2 && (!e.metadata || e.metadata['renderTarget'] == 'selection')); this._selectionGroupRenderTarget.renderList = []; for (let mesh of overlayMeshes) { this._selectionGroupRenderTarget.renderList.push(mesh); } let secondaryMeshes = this._renderScene.secondarySceneRoot.getChildMeshes(false); for (let mesh of secondaryMeshes) { if (mesh.renderingGroupId === 2 && (!mesh.metadata || mesh.metadata['renderTarget'] == 'selection')) { mesh.visibility = 1.0; } } }; this._selectionGroupRenderTarget.onAfterRender = () => { let secondaryMeshes = this._renderScene.secondarySceneRoot.getChildMeshes(false); for (let mesh of secondaryMeshes) { if (mesh.renderingGroupId === 2 && (!mesh.metadata || mesh.metadata['renderTarget'] == 'selection')) { mesh.visibility = 0.0; } } }; if (this.supportsMultiSampleRenderTargets()) { this._selectionGroupRenderTarget.samples = RenderOptions.msaaSampleCount; } } private _createOverlayRenderTarget(): void { let canvas = this.internalScene.getEngine().getRenderingCanvas(); this._overlayGroupRenderTarget = new BABYLON.RenderTargetTexture('overlayRenderTarget', { width: canvas.width, height: canvas.height }, this.internalScene, false, false, this._defaultPipelineTextureType, false, BABYLON.Texture.BILINEAR_SAMPLINGMODE); this._overlayGroupRenderTarget.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; this._overlayGroupRenderTarget.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE; this._overlayGroupRenderTarget.hasAlpha = true; this._overlayGroupRenderTarget.clearColor = new BABYLON.Color4(0.0, 0.0, 0.0, 0.0); this.internalScene.customRenderTargets.push(this._overlayGroupRenderTarget); this._overlayGroupRenderTarget.onBeforeRender = () => { let overlayMeshes = this._renderScene.secondarySceneRoot.getChildMeshes().slice(); overlayMeshes = overlayMeshes.filter(e => e.renderingGroupId === 2 && (e.metadata && e.metadata['renderTarget'] == 'overlay')); this._overlayGroupRenderTarget.renderList = []; for (let mesh of overlayMeshes) { this._overlayGroupRenderTarget.renderList.push(mesh); } let secondaryMeshes = this._renderScene.secondarySceneRoot.getChildMeshes(false); for (let mesh of secondaryMeshes) { if (mesh.renderingGroupId === 2 && (mesh.metadata && mesh.metadata['renderTarget'] == 'overlay')) { mesh.visibility = 1.0; } } }; this._overlayGroupRenderTarget.onAfterRender = () => { let secondaryMeshes = this._renderScene.secondarySceneRoot.getChildMeshes(false); for (let mesh of secondaryMeshes) { if (mesh.renderingGroupId === 2 && (mesh.metadata && mesh.metadata['renderTarget'] == 'overlay')) { mesh.visibility = 0.0; } } }; if (this.supportsMultiSampleRenderTargets()) { this._overlayGroupRenderTarget.samples = RenderOptions.msaaSampleCount; } } private _createColorBufferPostProcess(): void { this._originalColorPostProcess = new BABYLON.PassPostProcess('SSAOOriginalSceneColor', 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, this._defaultPipelineTextureType); if (this.supportsMultiSampleRenderTargets()) { this._originalColorPostProcess.samples = RenderOptions.msaaSampleCount; } } // Private Methods private _createBlurPostProcess(ratio: number): void { var size = 16; this._blurHPostProcess = new BABYLON.BlurPostProcess('BlurH', new BABYLON.Vector2(1, 0), size, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, this._defaultPipelineTextureType); this._blurVPostProcess = new BABYLON.BlurPostProcess('BlurV', new BABYLON.Vector2(0, 1), size, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, this._defaultPipelineTextureType); this._blurHPostProcess.onActivateObservable.add(() => { let dw = this._blurHPostProcess.width / this.internalScene.getEngine().getRenderWidth(); this._blurHPostProcess.kernel = size * dw; }); this._blurVPostProcess.onActivateObservable.add(() => { let dw = this._blurVPostProcess.height / this.internalScene.getEngine().getRenderHeight(); this._blurVPostProcess.kernel = size * dw; }); if (this.supportsMultiSampleRenderTargets()) { this._blurHPostProcess.samples = RenderOptions.msaaSampleCount; this._blurVPostProcess.samples = RenderOptions.msaaSampleCount; } } _rebuild() { this._firstUpdate = true; super._rebuild(); } private _createSSAOPostProcess(ratio: number): void { var numSamples = 16; var sampleSphere = [ 0.5381, 0.1856, -0.4319, 0.1379, 0.2486, 0.4430, 0.3371, 0.5679, -0.0057, -0.6999, -0.0451, -0.0019, 0.0689, -0.1598, -0.8547, 0.0560, 0.0069, -0.1843, -0.0146, 0.1402, 0.0762, 0.0100, -0.1924, -0.0344, -0.3577, -0.5301, -0.4358, -0.3169, 0.1063, 0.0158, 0.0103, -0.5869, 0.0046, -0.0897, -0.4940, 0.3287, 0.7119, -0.0154, -0.0918, -0.0533, 0.0596, -0.5411, 0.0352, -0.0631, 0.5460, -0.4776, 0.2847, -0.0271 ]; var samplesFactor = 1.0 / numSamples; let shader = BABYLON.Effect.ShadersStore['custom_ssao' + 'FragmentShader']; if (!shader) { let ssao_frag_shader: string = ssao_frag; BABYLON.Effect.ShadersStore['custom_ssao' + 'FragmentShader'] = ssao_frag_shader; } let uniforms = [ 'sampleSphere', 'samplesFactor', 'randTextureTiles', 'totalStrength', 'radius', 'area', 'fallOff', 'base' ]; let samplers = ['randomSampler']; let defines = []; defines.push('#define SAMPLES ' + numSamples); if (this._normalTexture) { samplers.push('normalSampler'); defines.push('#define NORMAL_TEXTURE'); } this._ssaoPostProcess = new BABYLON.PostProcess('ssao', 'custom_ssao', uniforms, samplers, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, defines.join('\n'), this._defaultPipelineTextureType); this._ssaoPostProcess.onApply = (effect: BABYLON.Effect) => { if (this._firstUpdate) { effect.setArray3('sampleSphere', sampleSphere); effect.setFloat('samplesFactor', samplesFactor); effect.setFloat('randTextureTiles', 4.0); } effect.setFloat('totalStrength', this._ssaoTotalStrength); effect.setFloat('radius', this._ssaoRadius); effect.setFloat('area', this._ssaoArea); effect.setFloat('fallOff', this._ssaoFallOff); effect.setFloat('base', this._ssaoBase); effect.setTexture('textureSampler', this._depthTexture); effect.setTexture('randomSampler', this._randomTexture); if (this._normalTexture) { effect.setTexture('normalSampler', this._normalTexture); } }; if (this.supportsMultiSampleRenderTargets()) { this._ssaoPostProcess.samples = RenderOptions.msaaSampleCount; } } private _createSSAOCombinePostProcess(ratio: number): void { this._ssaoCombinePostProcess = new BABYLON.PostProcess('ssaoCombine', 'ssaoCombine', [], ['originalColor'], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, '', this._defaultPipelineTextureType); this._ssaoCombinePostProcess.onApply = (effect: BABYLON.Effect) => { effect.setTextureFromPostProcess('originalColor', this._originalColorPostProcess); }; if (this.supportsMultiSampleRenderTargets()) { this._ssaoCombinePostProcess.samples = RenderOptions.msaaSampleCount; } } private _createRandomTexture(): void { var size = 512; this._randomTexture = new BABYLON.DynamicTexture('SSAORandomTexture', size, this.internalScene, false, BABYLON.Texture.TRILINEAR_SAMPLINGMODE); this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE; this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; var context = this._randomTexture.getContext(); var rand = (min: number, max: number) => { return Math.random() * (max - min) + min; } var randVector = BABYLON.Vector3.Zero(); for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { randVector.x = rand(0.0, 1.0); randVector.y = rand(0.0, 1.0); randVector.z = 0.0; randVector.normalize(); randVector.scaleInPlace(255); randVector.x = Math.floor(randVector.x); randVector.y = Math.floor(randVector.y); context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')'; context.fillRect(x, y, 1, 1); } } this._randomTexture.update(false); } private _createFXAAPostProcess(): void { this._fxaa = new BABYLON.FxaaPostProcess('fxaa', 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, this._defaultPipelineTextureType); if (this.supportsMultiSampleRenderTargets()) { this._fxaa.samples = RenderOptions.msaaSampleCount; } } private _createGammaCorrectionPostProcess(): void { let shader = BABYLON.Effect.ShadersStore['gamma_correction' + 'FragmentShader']; if (!shader) { let gamma_correction_frag_shader: string = gamma_correction_frag; BABYLON.Effect.ShadersStore['gamma_correction' + 'FragmentShader'] = gamma_correction_frag_shader; } this._gammaCorrection = new BABYLON.PostProcess('gamma_correction', 'gamma_correction', [ 'gamma' ], [], 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, '', this._defaultPipelineTextureType); this._gammaCorrection.onApply = (effect: BABYLON.Effect) => { effect.setFloat('gamma', RenderOptions.gammaValue); }; if (this.supportsMultiSampleRenderTargets()) { this._gammaCorrection.samples = RenderOptions.msaaSampleCount; } } // Final Merge private _createFinalMergePostProcess(): void { let shader = BABYLON.Effect.ShadersStore['final_merge' + 'FragmentShader']; if (!shader) { let final_merge_frag_shader: string = final_merge_frag; BABYLON.Effect.ShadersStore['final_merge' + 'FragmentShader'] = final_merge_frag_shader; } this._finalMerge = new BABYLON.PostProcess('final_merge', 'final_merge', [ 'selectionColor', 'resolution' ], [ 'selectionSampler', 'overlaySampler' ], 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), false, '', this._defaultPipelineTextureType); this._finalMerge.onApply = (effect: BABYLON.Effect) => { effect.setFloat3('selectionColor', SceneOptions.selectionColor.r, SceneOptions.selectionColor.g, SceneOptions.selectionColor.b); effect.setFloat2('resolution', 1 / this._finalMerge.width, 1 / this._finalMerge.height); effect.setTexture('selectionSampler', this._selectionGroupRenderTarget); effect.setTexture('overlaySampler', this._overlayGroupRenderTarget); }; if (this.supportsMultiSampleRenderTargets()) { this._finalMerge.samples = RenderOptions.msaaSampleCount; } } private _createToneMappingPostProcess(): void { this._toneMapping = new BABYLON.TonemapPostProcess('tone_mapping', RenderOptions.toneMappingMethod, RenderOptions.toneMappingExposureAdjustment, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this.internalScene.getEngine(), this._defaultPipelineTextureType); if (this.supportsMultiSampleRenderTargets()) { this._finalMerge.samples = RenderOptions.msaaSampleCount; } } private supportsMultiSampleRenderTargets(): boolean { return RenderOptions.msaaEnabled && Capabilities.WebGLVersion(this.internalScene.getEngine()) >= 2.0 && WebUtils.isChrome(); } } And when I call enableGammaCorrection(false), it does not work with alpha6 but it did work with alpha4.
  14. About ground shadow

    Hi folks, I would like to have a totally transparent ground plane but I need to draw the shadow (only the shadow) on it. How can I do it? I am currently using the BackgroundMaterial but when the ground is transparent, the shadow disappear too...
  15. Hi Guys, I updated from 3.2.0-alpha4 to alpha6 and this function seems not to work anymore. Just want to confirm if it is the case though...