Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c868170

Browse filesBrowse files
authored
Volumetric Lighting: fix lighting volume when light direction changes (#17516)
I also removed the **buildFullVolume** property (at least from the public interface), as there's no point to have it at the time being (maybe we will need it when cascaded shadow generators are supported, that's why I didn't remove it completely).
1 parent 9ed69db commit c868170
Copy full SHA for c868170

File tree

Expand file treeCollapse file tree

4 files changed

+41
-88
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+41
-88
lines changed
Open diff view settings
Collapse file

‎packages/dev/core/src/FrameGraph/Node/Blocks/lightingVolumeBlock.ts‎

Copy file name to clipboardExpand all lines: packages/dev/core/src/FrameGraph/Node/Blocks/lightingVolumeBlock.ts
-13Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,6 @@ export class NodeRenderGraphLightingVolumeBlock extends NodeRenderGraphBlock {
5656
this._frameGraphTask.lightingVolume.frequency = value;
5757
}
5858

59-
/** Indicates whether to build the full volume (true) or only the far plane (false). Default is false. */
60-
@editableInPropertyPage("Build full volume", PropertyTypeForEdition.Boolean, "PROPERTIES")
61-
public get buildFullVolume(): boolean {
62-
return this._frameGraphTask.lightingVolume.buildFullVolume;
63-
}
64-
65-
public set buildFullVolume(value: boolean) {
66-
this._frameGraphTask.lightingVolume.buildFullVolume = value;
67-
}
68-
6959
/**
7060
* Gets the current class name
7161
* @returns the class name
@@ -100,23 +90,20 @@ export class NodeRenderGraphLightingVolumeBlock extends NodeRenderGraphBlock {
10090
const codes: string[] = [];
10191
codes.push(`${this._codeVariableName}.tesselation = ${this.tesselation};`);
10292
codes.push(`${this._codeVariableName}.frequency = ${this.frequency};`);
103-
codes.push(`${this._codeVariableName}.buildFullVolume = ${this.buildFullVolume};`);
10493
return super._dumpPropertiesCode() + codes.join("\n");
10594
}
10695

10796
public override serialize(): any {
10897
const serializationObject = super.serialize();
10998
serializationObject.tesselation = this.tesselation;
11099
serializationObject.frequency = this.frequency;
111-
serializationObject.buildFullVolume = this.buildFullVolume;
112100
return serializationObject;
113101
}
114102

115103
public override _deserialize(serializationObject: any) {
116104
super._deserialize(serializationObject);
117105
this.tesselation = serializationObject.tesselation;
118106
this.frequency = serializationObject.frequency;
119-
this.buildFullVolume = !!serializationObject.buildFullVolume;
120107
}
121108
}
122109

Collapse file

‎packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts‎

Copy file name to clipboardExpand all lines: packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts
+3-43Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,6 @@ export class FrameGraphVolumetricLightingTask extends FrameGraphTask {
166166
});
167167
this._renderLightingVolumeMaterial.backFaceCulling = false;
168168
this._renderLightingVolumeMaterial.alphaMode = Constants.ALPHA_ADD;
169-
this._renderLightingVolumeMaterial.depthFunction = Constants.ALWAYS;
170-
this._renderLightingVolumeMaterial.stencil.enabled = this.enableExtinction;
171-
this._renderLightingVolumeMaterial.stencil.func = Constants.ALWAYS;
172-
this._renderLightingVolumeMaterial.stencil.backFunc = Constants.ALWAYS;
173-
this._renderLightingVolumeMaterial.stencil.funcRef = 1;
174169
this._renderLightingVolumeMaterial.onBindObservable.add(() => {
175170
this._renderLightingVolumeMaterial.bindEyePosition(this._renderLightingVolumeMaterial.getEffect());
176171
});
@@ -212,13 +207,12 @@ export class FrameGraphVolumetricLightingTask extends FrameGraphTask {
212207

213208
const textureManager = this._frameGraph.textureManager;
214209

215-
const targetTextureCreationOptions = textureManager.getTextureCreationOptions(this.targetTexture);
216-
const targetTextureSamples = targetTextureCreationOptions.options.samples || 1;
217-
218210
let lightingVolumeTexture = this.lightingVolumeTexture;
219211
if (!lightingVolumeTexture) {
212+
const targetTextureCreationOptions = textureManager.getTextureCreationOptions(this.targetTexture);
213+
220214
targetTextureCreationOptions.options.labels = ["InScattering"];
221-
targetTextureCreationOptions.options.samples = this.enableExtinction ? targetTextureSamples : 1;
215+
targetTextureCreationOptions.options.samples = 1;
222216

223217
lightingVolumeTexture = textureManager.createRenderTargetTexture(`${this.name} - lighting volume texture`, targetTextureCreationOptions);
224218
}
@@ -238,59 +232,25 @@ export class FrameGraphVolumetricLightingTask extends FrameGraphTask {
238232
this._renderLightingVolumeMaterial.setVector3("lightDir", this.light.direction.normalizeToRef(TmpVectors.Vector3[0]));
239233
});
240234

241-
const ligthingVolumeTextureCreationOptions = textureManager.getTextureCreationOptions(lightingVolumeTexture);
242-
243-
ligthingVolumeTextureCreationOptions.options.formats = [
244-
this._frameGraph.engine.isWebGPU ? Constants.TEXTUREFORMAT_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8,
245-
];
246-
ligthingVolumeTextureCreationOptions.options.labels = ["InScatteringStencil"];
247-
ligthingVolumeTextureCreationOptions.options.samples = targetTextureSamples;
248-
249-
const lightingVolumeStencilTexture = this.enableExtinction
250-
? textureManager.createRenderTargetTexture(`${this.name} - lighting volume stencil texture`, ligthingVolumeTextureCreationOptions)
251-
: undefined;
252-
253235
this._clearLightingVolumeTextureTask.clearColor = true;
254236
this._clearLightingVolumeTextureTask.clearStencil = this.enableExtinction;
255237
this._clearLightingVolumeTextureTask.color = new Color4(0, 0, 0, 1);
256238
this._clearLightingVolumeTextureTask.stencilValue = 0;
257239
this._clearLightingVolumeTextureTask.targetTexture = lightingVolumeTexture;
258-
this._clearLightingVolumeTextureTask.depthTexture = lightingVolumeStencilTexture;
259240
this._clearLightingVolumeTextureTask.record(true);
260241

261242
this._renderLightingVolumeTask.targetTexture = this._clearLightingVolumeTextureTask.outputTexture;
262-
this._renderLightingVolumeTask.depthTexture = this.enableExtinction ? this._clearLightingVolumeTextureTask.outputDepthTexture : undefined;
263243
this._renderLightingVolumeTask.objectList = this.lightingVolumeMesh;
264244
this._renderLightingVolumeTask.camera = this.camera;
265245
this._renderLightingVolumeTask.disableImageProcessing = true;
266246
this._renderLightingVolumeTask.depthTest = false;
267247
this._renderLightingVolumeTask.record(true);
268248

269249
this._blendLightingVolumeTask.sourceTexture = this._renderLightingVolumeTask.outputTexture;
270-
this._blendLightingVolumeTask.depthAttachmentTexture = this.enableExtinction ? this._renderLightingVolumeTask.outputDepthTexture : undefined;
271250
this._blendLightingVolumeTask.sourceSamplingMode = this.sourceSamplingMode;
272251
this._blendLightingVolumeTask.targetTexture = this.targetTexture;
273252
this._blendLightingVolumeTask.depthTexture = this.depthTexture;
274253
this._blendLightingVolumeTask.camera = this.camera;
275-
this._blendLightingVolumeTask.depthTest = false;
276-
this._blendLightingVolumeTask.stencilState = {
277-
enabled: this.enableExtinction,
278-
279-
funcRef: 1,
280-
281-
mask: 0xff,
282-
funcMask: 0xff,
283-
284-
func: Constants.EQUAL,
285-
opStencilFail: Constants.KEEP,
286-
opDepthFail: Constants.KEEP,
287-
opStencilDepthPass: Constants.KEEP,
288-
289-
backFunc: Constants.EQUAL,
290-
backOpStencilFail: Constants.KEEP,
291-
backOpDepthFail: Constants.KEEP,
292-
backOpStencilDepthPass: Constants.KEEP,
293-
};
294254
this._blendLightingVolumeTask.record(true);
295255

296256
if (!skipCreationOfDisabledPasses) {
Collapse file

‎packages/dev/core/src/Lights/lightingVolume.ts‎

Copy file name to clipboardExpand all lines: packages/dev/core/src/Lights/lightingVolume.ts
+38-32Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class LightingVolume {
2525
private readonly _mesh: Mesh;
2626
private readonly _copyTexture?: CopyTextureToTexture;
2727
private readonly _uBuffer?: UniformBuffer;
28+
private readonly _buildFullVolume = true;
2829
private _name: string;
2930
private _cs?: ComputeShader;
3031
private _light?: DirectionalLight;
@@ -35,6 +36,7 @@ export class LightingVolume {
3536
private _readPixelAbortController: Nullable<AbortController> = null;
3637
private _numFrames = 0;
3738
private _firstUpdate = true;
39+
private _currentLightDirection = new Vector3();
3840

3941
private _shadowGenerator?: ShadowGenerator;
4042
/**
@@ -76,27 +78,7 @@ export class LightingVolume {
7678

7779
public set tesselation(n: number) {
7880
this._tesselation = n;
79-
this._createGeometry();
80-
}
81-
82-
private _buildFullVolume = false;
83-
/**
84-
* Indicates whether to build the full volume (true) or only the near plane (false). Default is false.
85-
*/
86-
public get buildFullVolume() {
87-
return this._buildFullVolume;
88-
}
89-
90-
public set buildFullVolume(value: boolean) {
91-
if (this._buildFullVolume === value) {
92-
return;
93-
}
94-
this._buildFullVolume = value;
95-
this._createGeometry();
96-
if (this._engine.isWebGPU) {
97-
this._createComputeShader();
98-
}
99-
this._firstUpdate = true;
81+
this._createGeometry(true);
10082
}
10183

10284
/**
@@ -184,7 +166,7 @@ export class LightingVolume {
184166
}
185167

186168
this._tesselation = tesselation;
187-
this._createGeometry();
169+
this._createGeometry(true);
188170
}
189171

190172
/**
@@ -215,6 +197,8 @@ export class LightingVolume {
215197
this._numFrames = 0;
216198

217199
if (this._cs && this._uBuffer) {
200+
this._recreateGeometry();
201+
218202
const dispatchSize = Math.ceil((this._tesselation + 1) / 8);
219203

220204
const viewProjMatrix = this._shadowGenerator.getTransformMatrix();
@@ -254,6 +238,13 @@ export class LightingVolume {
254238
this._depthCopy?.dispose();
255239
}
256240

241+
private _recreateGeometry() {
242+
if (this._light && !this._currentLightDirection.equals(this._light.direction)) {
243+
this._currentLightDirection.copyFrom(this._light.direction);
244+
this._createGeometry();
245+
}
246+
}
247+
257248
private _createComputeShader() {
258249
this._cs = new ComputeShader("createLightVolume", this._engine, "lightingVolume", {
259250
bindingsMapping: {
@@ -362,6 +353,8 @@ export class LightingVolume {
362353

363354
const factor = 4;
364355

356+
this._recreateGeometry();
357+
365358
let posIndex = startPos;
366359
let stepY = 0;
367360
for (let y = 0; y < numTesselation + 1; ++y) {
@@ -395,7 +388,7 @@ export class LightingVolume {
395388
this._firstUpdate = false;
396389
}
397390

398-
private _createGeometry() {
391+
private _createGeometry(_recreateAll = false) {
399392
if (!this._light) {
400393
return;
401394
}
@@ -423,6 +416,8 @@ export class LightingVolume {
423416
if (this._buildFullVolume) {
424417
let startIndices = 0;
425418

419+
const rightFaceStartIndex = startIndices;
420+
426421
// Right faces of the frustum
427422
for (let i = 0; i <= numTesselation; ++i) {
428423
v.set(max.x, min.y + i * stepY, min.z);
@@ -436,12 +431,10 @@ export class LightingVolume {
436431
}
437432
}
438433

439-
const n0 = 0;
440-
const n1 = positions.length / 3 - 1;
441-
const n2 = n1 + 1;
442-
443434
startIndices = positions.length / 3;
444435

436+
const leftFaceStartIndex = startIndices;
437+
445438
// Left faces of the frustum
446439
for (let i = 0; i <= numTesselation; ++i) {
447440
v.set(min.x, min.y + i * stepY, min.z);
@@ -455,10 +448,10 @@ export class LightingVolume {
455448
}
456449
}
457450

458-
const n3 = positions.length / 3 - 1;
459-
460451
startIndices = positions.length / 3;
461452

453+
const bottomFaceStartIndex = startIndices;
454+
462455
// Bottom faces of the frustum
463456
for (let i = 0; i <= numTesselation; ++i) {
464457
v.set(min.x + i * stepX, min.y, min.z);
@@ -474,6 +467,8 @@ export class LightingVolume {
474467

475468
startIndices = positions.length / 3;
476469

470+
const topFaceStartIndex = startIndices;
471+
477472
// Top faces of the frustum
478473
for (let i = 0; i <= numTesselation; ++i) {
479474
v.set(min.x + i * stepX, max.y, min.z);
@@ -494,8 +489,19 @@ export class LightingVolume {
494489
startIndices = positions.length / 3;
495490

496491
// Near faces of the frustum
497-
indices.push(n0, n2, n1);
498-
indices.push(n2, n3, n1);
492+
for (let i = 0; i < numTesselation; ++i) {
493+
indices.push(leftFaceStartIndex + i, leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i);
494+
if (i < numTesselation - 1) {
495+
indices.push(leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i - 1, topFaceStartIndex + numTesselation - i);
496+
}
497+
}
498+
499+
for (let i = 0; i < numTesselation; ++i) {
500+
indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i, rightFaceStartIndex + numTesselation - i - 1);
501+
if (i < numTesselation - 1) {
502+
indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i - 1, bottomFaceStartIndex + i + 1);
503+
}
504+
}
499505
} else {
500506
let p: Vector3;
501507

@@ -554,7 +560,7 @@ export class LightingVolume {
554560

555561
this._storageBuffer.update(positions);
556562

557-
const vertexBuffer = new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), "position");
563+
const vertexBuffer = new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), "position", { takeBufferOwnership: false });
558564

559565
this._mesh.setVerticesBuffer(vertexBuffer);
560566

Collapse file
-13.6 KB
  • Display the source diff
  • Display the rich diff
Loading

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.