Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 39 additions & 10 deletions packages/dev/addons/src/atmosphere/atmosphere.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ import "./Shaders/ShadersInclude/depthFunctions";

const MaterialPlugin = "atmo-pbr";

const AerialPerspectiveLutLayers = 32;

let UniqueId = 0;

/**
* Renders a physically based atmosphere.
* Use {@link IsSupported} to check if the atmosphere is supported before creating an instance.
Expand Down Expand Up @@ -84,6 +88,7 @@ export class Atmosphere implements IDisposable {
private _aerialPerspectiveRenderingGroup: number;
private _globeAtmosphereRenderingGroup: number;
private _isEnabled = true;
private _aerialPerspectiveLutHasBeenRendered = false;

private _hasRenderedMultiScatteringLut = false;
private _multiScatteringEffectWrapper: Nullable<EffectWrapper> = null;
Expand Down Expand Up @@ -114,6 +119,11 @@ export class Atmosphere implements IDisposable {
return !engine._badOS && !engine.isWebGPU && engine.version >= 2;
}

/**
* The unique ID of this atmosphere instance.
*/
public readonly uniqueId = UniqueId++;

/**
* Called after the atmosphere variables have been updated for the specified camera.
*/
Expand Down Expand Up @@ -340,7 +350,7 @@ export class Atmosphere implements IDisposable {

const scene = this.scene;
const name = "atmo-aerialPerspective";
const renderTarget = (this._aerialPerspectiveLutRenderTarget = CreateRenderTargetTexture(name, { width: 16, height: 64, layers: 32 }, scene, {}));
const renderTarget = (this._aerialPerspectiveLutRenderTarget = CreateRenderTargetTexture(name, { width: 16, height: 64, layers: AerialPerspectiveLutLayers }, scene, {}));
this._aerialPerspectiveLutEffectWrapper = CreateAerialPerspectiveEffectWrapper(this._engine, this.uniformBuffer);

return renderTarget;
Expand Down Expand Up @@ -637,8 +647,6 @@ export class Atmosphere implements IDisposable {
return this._cameraAtmosphereVariables;
}

public readonly uniqueId: number;

/**
* Constructs the {@link Atmosphere}.
* @param name - The name of this instance.
Expand All @@ -653,7 +661,6 @@ export class Atmosphere implements IDisposable {
options?: IAtmosphereOptions
) {
const engine = (this._engine = scene.getEngine());
this.uniqueId = scene.getUniqueId();

if (engine.isWebGPU) {
throw new Error("Atmosphere is not supported on WebGPU.");
Expand Down Expand Up @@ -1233,9 +1240,19 @@ export class Atmosphere implements IDisposable {
this._drawSkyViewLut();
}

// Only need to render aerial perspective LUT when inside the atmosphere.
if (this._isAerialPerspectiveLutEnabled && this._cameraAtmosphereVariables.clampedCameraRadius <= this._physicalProperties.atmosphereRadius) {
this._drawAerialPerspectiveLut();
if (this._isAerialPerspectiveLutEnabled) {
// Only need to fully render aerial perspective LUT when inside the atmosphere,
// otherwise it won't be used for rendering so is unnecessary overhead.
if (this._cameraAtmosphereVariables.clampedCameraRadius <= this._physicalProperties.atmosphereRadius) {
this._drawAerialPerspectiveLut();
} else {
// Make sure to clear the LUT to some initial value if this would have otherwise been the first time rendering it.
// This prevents some GL warnings about uninitialized textures when the LUT is bound to a shader (even if it's not used).
if (!this._aerialPerspectiveLutHasBeenRendered) {
this._clearAerialPerspectiveLut();
}
}
this._aerialPerspectiveLutHasBeenRendered = true;
}
}

Expand Down Expand Up @@ -1350,10 +1367,9 @@ export class Atmosphere implements IDisposable {
this._aerialPerspectiveLutRenderTarget,
(effectRenderer, renderTarget, effect, engine) => {
this.bindUniformBufferToEffect(effect);
const layers = 32;
effect.setTexture("transmittanceLut", transmittanceLut);
effect.setTexture("multiScatteringLut", multiScatteringLut);
for (let layer = 0; layer < layers; layer++) {
for (let layer = 0; layer < AerialPerspectiveLutLayers; layer++) {
engine.bindFramebuffer(renderTarget!, undefined, undefined, undefined, true, undefined, layer);
effectRenderer.bindBuffers(effect);
effect.setFloat("layerIdx", layer);
Expand All @@ -1363,6 +1379,17 @@ export class Atmosphere implements IDisposable {
);
}

private _clearAerialPerspectiveLut(): void {
const renderTarget = this._aerialPerspectiveLutRenderTarget?.renderTarget;
if (renderTarget) {
const engine = this._engine;
for (let layer = 0; layer < AerialPerspectiveLutLayers; layer++) {
engine.bindFramebuffer(renderTarget, undefined, undefined, undefined, true, undefined, layer);
engine.clear({ r: 0, g: 0, b: 0, a: 0 }, true, false, false);
}
}
}

/**
* Draws the sky view LUT using {@link EffectWrapper} and {@link EffectRenderer}.
*/
Expand Down Expand Up @@ -1422,13 +1449,15 @@ const CreateRenderTargetTexture = (
scene: Scene,
options?: RenderTargetTextureOptions
): RenderTargetTexture => {
//const caps = scene.getEngine().getCaps();
const textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE; // caps.textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : caps.textureFloatRender ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE;
const rtOptions: RenderTargetTextureOptions = {
generateMipMaps: false,
generateDepthBuffer: false,
generateStencilBuffer: false,
gammaSpace: false,
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
type: Constants.TEXTURETYPE_HALF_FLOAT,
type: textureType,
format: Constants.TEXTUREFORMAT_RGBA,
...options,
};
Expand Down
6 changes: 4 additions & 2 deletions packages/dev/addons/src/atmosphere/diffuseSkyIrradianceLut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,19 @@ export class DiffuseSkyIrradianceLut {
const engine = scene.getEngine();

const name = "atmo-diffuseSkyIrradiance";
//const caps = engine.getCaps();
const textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;
const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {
generateMipMaps: false,
type: Constants.TEXTURETYPE_HALF_FLOAT,
type: textureType,
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
generateDepthBuffer: false,
gammaSpace: false,
}));
renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
renderTarget.anisotropicFilteringLevel = 1;
renderTarget.skipInitialClear = true;
//renderTarget.skipInitialClear = true;

const useUbo = atmosphere.uniformBuffer.useUbo;

Expand Down
5 changes: 3 additions & 2 deletions packages/dev/addons/src/atmosphere/transmittanceLut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,19 @@ export class TransmittanceLut {

const scene = this._atmosphere.scene;
const engine = scene.getEngine();
const useHalfFloat = UseHalfFloat && engine.getCaps().textureHalfFloatRender;

const name = "atmo-transmittance";
const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {
type: UseHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,
type: useHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
generateDepthBuffer: false,
gammaSpace: false,
}));
renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
renderTarget.anisotropicFilteringLevel = 1;
renderTarget.skipInitialClear = true;
//renderTarget.skipInitialClear = true;

const useUbo = this._atmosphere.uniformBuffer.useUbo;
this._effectWrapper = new EffectWrapper({
Expand Down
Loading