Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate CDF Renderer from IBL Shadows and use for realtime filtering #15878

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ export class ReflectionBlock extends ReflectionTextureBaseBlock {
#endif
#ifdef REALTIME_FILTERING
, ${this._vReflectionFilteringInfoName}
#ifdef IBL_CDF_FILTERING
, icdfxSampler // ** not handled **
${isWebGPU ? `, icdfxSamplerSampler` : ""}
, icdfySampler // ** not handled **
${isWebGPU ? `, icdfySamplerSampler` : ""}
#endif
#endif
);
#endif\n`;
Expand Down
13 changes: 13 additions & 0 deletions packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export class PBRMaterialDefines extends MaterialDefines implements IImageProcess

public NUM_SAMPLES = "0";
public REALTIME_FILTERING = false;
public IBL_CDF_FILTERING = false;

public MAINUV1 = false;
public MAINUV2 = false;
Expand Down Expand Up @@ -1488,6 +1489,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
"morphTargets",
"oitDepthSampler",
"oitFrontColorSampler",
"icdfxSampler",
"icdfySampler",
];

const uniformBuffers = ["Material", "Scene", "Mesh"];
Expand Down Expand Up @@ -1653,6 +1656,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
}

defines.REALTIME_FILTERING = true;
if (this.getScene().iblCdfGenerator) {
defines.IBL_CDF_FILTERING = true;
}
} else {
defines.REALTIME_FILTERING = false;
}
Expand Down Expand Up @@ -2297,6 +2303,13 @@ export abstract class PBRBaseMaterial extends PushMaterial {
if (defines.USEIRRADIANCEMAP) {
ubo.setTexture("irradianceSampler", reflectionTexture.irradianceTexture);
}

//if realtime filtering and using CDF maps, set them.
const cdfGenerator = this.getScene().iblCdfGenerator;
if (this.realTimeFiltering && cdfGenerator) {
ubo.setTexture("icdfxSampler", cdfGenerator.getIcdfxTexture());
ubo.setTexture("icdfySampler", cdfGenerator.getIcdfyTexture());
}
}

if (defines.ENVIRONMENTBRDF) {
Expand Down
100 changes: 32 additions & 68 deletions packages/dev/core/src/Rendering/IBLShadows/iblShadowsRenderPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import { EngineStore } from "../../Engines/engineStore";
import { Matrix, Vector3, Vector4, Quaternion } from "../../Maths/math.vector";
import type { Mesh } from "../../Meshes/mesh";
import type { Scene } from "../../scene";
import type { BaseTexture } from "../../Materials/Textures/baseTexture";
import { Texture } from "../../Materials/Textures/texture";
import { Logger } from "../../Misc/logger";
import { _IblShadowsVoxelRenderer } from "./iblShadowsVoxelRenderer";
import { _IblShadowsVoxelTracingPass } from "./iblShadowsVoxelTracingPass";

import { PostProcess } from "../../PostProcesses/postProcess";
import type { PostProcessOptions } from "../../PostProcesses/postProcess";
import { _IblShadowsImportanceSamplingRenderer } from "./iblShadowsImportanceSamplingRenderer";
import { _IblShadowsSpatialBlurPass } from "./iblShadowsSpatialBlurPass";
import { _IblShadowsAccumulationPass } from "./iblShadowsAccumulationPass";
import { PostProcessRenderPipeline } from "../../PostProcesses/RenderPipeline/postProcessRenderPipeline";
Expand Down Expand Up @@ -128,7 +126,6 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
private _shadowCastingMeshes: Mesh[] = [];

private _voxelRenderer: _IblShadowsVoxelRenderer;
private _importanceSamplingRenderer: _IblShadowsImportanceSamplingRenderer;
private _voxelTracingPass: _IblShadowsVoxelTracingPass;
private _spatialBlurPass: _IblShadowsSpatialBlurPass;
private _accumulationPass: _IblShadowsAccumulationPass;
Expand Down Expand Up @@ -276,16 +273,6 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
this._updateSSShadowParams();
}

/**
* Set the IBL image to be used for shadowing. It can be either a cubemap
* or a 2D equirectangular texture.
* @param iblSource The texture to use for IBL shadowing
*/
public setIblTexture(iblSource: BaseTexture) {
if (!this._importanceSamplingRenderer) return;
this._importanceSamplingRenderer.iblSource = iblSource;
}

/**
* Returns the texture containing the voxel grid data
* @returns The texture containing the voxel grid data
Expand All @@ -299,32 +286,6 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
return this._dummyTexture3d;
}

/**
* Returns the texture containing the importance sampling CDF data for the IBL shadow pipeline
* @returns The texture containing the importance sampling CDF data for the IBL shadow pipeline
* @internal
*/
public _getIcdfyTexture(): Texture {
const tex = this._importanceSamplingRenderer!.getIcdfyTexture();
if (tex && tex.isReady()) {
return tex;
}
return this._dummyTexture2d;
}

/**
* Returns the texture containing the importance sampling CDF data for the IBL shadow pipeline
* @returns The texture containing the importance sampling CDF data for the IBL shadow pipeline
* @internal
*/
public _getIcdfxTexture(): Texture {
const tex = this._importanceSamplingRenderer.getIcdfxTexture();
if (tex && tex.isReady()) {
return tex;
}
return this._dummyTexture2d;
}

/**
* Returns the noise texture.
* @returns The noise texture.
Expand Down Expand Up @@ -405,25 +366,25 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
/**
* Turn on or off the debug view of the CDF importance sampling data
*/
public get importanceSamplingDebugEnabled(): boolean {
return this._importanceSamplingRenderer?.debugEnabled;
public get cdfDebugEnabled(): boolean {
return this.scene.iblCdfGenerator ? this.scene.iblCdfGenerator.debugEnabled : false;
}

/**
* Turn on or off the debug view of the CDF importance sampling data
*/
public set importanceSamplingDebugEnabled(enabled: boolean) {
if (!this._importanceSamplingRenderer) return;
public set cdfDebugEnabled(enabled: boolean) {
if (!this.scene.iblCdfGenerator) return;
if (enabled && !this.allowDebugPasses) {
Logger.Warn("Can't enable importance sampling debug view without setting allowDebugPasses to true.");
return;
}
if (enabled === this._importanceSamplingRenderer.debugEnabled) return;
this._importanceSamplingRenderer.debugEnabled = enabled;
if (enabled === this.scene.iblCdfGenerator.debugEnabled) return;
this.scene.iblCdfGenerator.debugEnabled = enabled;
if (enabled) {
this._enableEffect(this._importanceSamplingRenderer.debugPassName, this.cameras);
this._enableEffect(this.scene.iblCdfGenerator.debugPassName, this.cameras);
} else {
this._disableEffect(this._importanceSamplingRenderer.debugPassName, this.cameras);
this._disableEffect(this.scene.iblCdfGenerator.debugPassName, this.cameras);
}
}

Expand Down Expand Up @@ -657,11 +618,11 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
public set allowDebugPasses(value: boolean) {
if (this._allowDebugPasses === value) return;
this._allowDebugPasses = value;
if (value) {
if (this._importanceSamplingRenderer.isReady()) {
if (value && this.scene.iblCdfGenerator) {
if (this.scene.iblCdfGenerator.isReady()) {
this._createDebugPasses();
} else {
this._importanceSamplingRenderer.onReadyObservable.addOnce(() => {
this.scene.iblCdfGenerator.onGeneratedObservable.addOnce(() => {
this._createDebugPasses();
});
}
Expand Down Expand Up @@ -788,15 +749,14 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
this._geometryBufferRenderer.enablePosition = true;
this._geometryBufferRenderer.enableNormal = true;
this._geometryBufferRenderer.generateNormalsInWorldSpace = true;

this.scene.enableIblCdfGenerator();
this.shadowOpacity = options.shadowOpacity || 0.8;
this._voxelRenderer = new _IblShadowsVoxelRenderer(
this.scene,
this,
options ? options.resolutionExp : 6,
options.triPlanarVoxelization !== undefined ? options.triPlanarVoxelization : true
);
this._importanceSamplingRenderer = new _IblShadowsImportanceSamplingRenderer(this.scene);
this._voxelTracingPass = new _IblShadowsVoxelTracingPass(this.scene, this);
this._spatialBlurPass = new _IblShadowsSpatialBlurPass(this.scene, this);
this._accumulationPass = new _IblShadowsAccumulationPass(this.scene, this);
Expand All @@ -814,9 +774,6 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
this.ssShadowThicknessScale = options.ssShadowThicknessScale || 1.0;
this.shadowRemanence = options.shadowRemanence ?? 0.75;
this._noiseTexture = new Texture("https://assets.babylonjs.com/textures/blue_noise/blue_noise_rgb.png", this.scene, false, true, Constants.TEXTURE_NEAREST_SAMPLINGMODE);
if (this.scene.environmentTexture) {
this._importanceSamplingRenderer.iblSource = this.scene.environmentTexture;
}

scene.postProcessRenderPipelineManager.addPipeline(this);

Expand All @@ -827,10 +784,12 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
this.scene.getEngine().onResizeObservable.add(this._handleResize.bind(this));

// Assigning the shadow texture to the materials needs to be done after the RT's are created.
this._importanceSamplingRenderer.onReadyObservable.add(() => {
this._setPluginParameters();
this.onNewIblReadyObservable.notifyObservers();
});
if (this.scene.iblCdfGenerator) {
this.scene.iblCdfGenerator.onGeneratedObservable.add(() => {
this._setPluginParameters();
this.onNewIblReadyObservable.notifyObservers();
});
}
}

private _handleResize() {
Expand Down Expand Up @@ -887,14 +846,19 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
}

private _createDebugPasses() {
this._debugPasses = [
{ pass: this._importanceSamplingRenderer.getDebugPassPP(), enabled: this.importanceSamplingDebugEnabled },
if (this.scene.iblCdfGenerator) {
this._debugPasses = [{ pass: this.scene.iblCdfGenerator.getDebugPassPP(), enabled: this.cdfDebugEnabled }];
} else {
this._debugPasses = [];
}

this._debugPasses.push(
{ pass: this._voxelRenderer.getDebugPassPP(), enabled: this.voxelDebugEnabled },
{ pass: this._voxelTracingPass.getDebugPassPP(), enabled: this.voxelTracingDebugEnabled },
{ pass: this._spatialBlurPass.getDebugPassPP(), enabled: this.spatialBlurPassDebugEnabled },
{ pass: this._accumulationPass.getDebugPassPP(), enabled: this.accumulationPassDebugEnabled },
{ pass: this._getGBufferDebugPass(), enabled: this.gbufferDebugEnabled },
];
{ pass: this._getGBufferDebugPass(), enabled: this.gbufferDebugEnabled }
);
for (let i = 0; i < this._debugPasses.length; i++) {
if (!this._debugPasses[i].pass) continue;
this.addEffect(
Expand Down Expand Up @@ -938,7 +902,7 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
private _updateDebugPasses() {
let count = 0;
if (this._gbufferDebugEnabled) count++;
if (this.importanceSamplingDebugEnabled) count++;
if (this.cdfDebugEnabled) count++;
if (this.voxelDebugEnabled) count++;
if (this.voxelTracingDebugEnabled) count++;
if (this.spatialBlurPassDebugEnabled) count++;
Expand All @@ -959,8 +923,8 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
}
}

if (this.importanceSamplingDebugEnabled) {
this._importanceSamplingRenderer.setDebugDisplayParams(x, y, cols, rows);
if (this.cdfDebugEnabled && this.scene.iblCdfGenerator) {
this.scene.iblCdfGenerator.setDebugDisplayParams(x, y, cols, rows);
x -= width;
if (x <= -1) {
x = 0;
Expand Down Expand Up @@ -1111,7 +1075,8 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
return (
this._noiseTexture.isReady() &&
this._voxelRenderer.isReady() &&
this._importanceSamplingRenderer.isReady() &&
this.scene.iblCdfGenerator &&
this.scene.iblCdfGenerator.isReady() &&
(!this._voxelTracingPass || this._voxelTracingPass.isReady()) &&
(!this._spatialBlurPass || this._spatialBlurPass.isReady()) &&
(!this._accumulationPass || this._accumulationPass.isReady())
Expand All @@ -1137,7 +1102,6 @@ export class IblShadowsRenderPipeline extends PostProcessRenderPipeline {
this._disposeEffectPasses();
this._noiseTexture.dispose();
this._voxelRenderer.dispose();
this._importanceSamplingRenderer.dispose();
this._voxelTracingPass.dispose();
this._spatialBlurPass.dispose();
this._accumulationPass.dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,11 @@ export class _IblShadowsVoxelTracingPass {
this._outputTexture.setVector4("shadowOpacity", this._opacityParameters);
this._outputTexture.setTexture("voxelGridSampler", voxelGrid);
this._outputTexture.setTexture("blueNoiseSampler", this._renderPipeline!._getNoiseTexture());
this._outputTexture.setTexture("icdfySampler", this._renderPipeline!._getIcdfyTexture());
this._outputTexture.setTexture("icdfxSampler", this._renderPipeline!._getIcdfxTexture());
const cdfGenerator = this._scene.iblCdfGenerator;
if (cdfGenerator) {
this._outputTexture.setTexture("icdfySampler", cdfGenerator.getIcdfyTexture());
this._outputTexture.setTexture("icdfxSampler", cdfGenerator.getIcdfxTexture());
}
if (this._debugVoxelMarchEnabled) {
this._outputTexture.defines += "#define VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION 1u\n";
}
Expand Down Expand Up @@ -395,8 +398,9 @@ export class _IblShadowsVoxelTracingPass {
return (
this._outputTexture.isReady() &&
!(this._debugPassPP && !this._debugPassPP.isReady()) &&
this._renderPipeline!._getIcdfyTexture().isReady() &&
this._renderPipeline!._getIcdfxTexture().isReady() &&
this._scene.iblCdfGenerator &&
this._scene.iblCdfGenerator.getIcdfyTexture().isReady() &&
this._scene.iblCdfGenerator.getIcdfxTexture().isReady() &&
this._renderPipeline!._getVoxelGridTexture().isReady()
);
}
Expand Down
Loading