@onerjs/core 8.48.4 → 8.48.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/Animations/animatable.core.d.ts +13 -0
  2. package/Animations/animatable.core.js +46 -7
  3. package/Animations/animatable.core.js.map +1 -1
  4. package/Cameras/Inputs/geospatialCameraPointersInput.js +10 -8
  5. package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
  6. package/Cameras/geospatialCameraMovement.js +2 -2
  7. package/Cameras/geospatialCameraMovement.js.map +1 -1
  8. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.d.ts +105 -0
  9. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.js +318 -0
  10. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.js.map +1 -0
  11. package/FrameGraph/Node/Blocks/index.d.ts +1 -0
  12. package/FrameGraph/Node/Blocks/index.js +1 -0
  13. package/FrameGraph/Node/Blocks/index.js.map +1 -1
  14. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.d.ts +34 -0
  15. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js +144 -0
  16. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js.map +1 -0
  17. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.d.ts +26 -0
  18. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.js +82 -0
  19. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.js.map +1 -0
  20. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.d.ts +61 -0
  21. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.js +207 -0
  22. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.js.map +1 -0
  23. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.d.ts +104 -0
  24. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.js +218 -0
  25. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.js.map +1 -0
  26. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.d.ts +217 -0
  27. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js +640 -0
  28. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js.map +1 -0
  29. package/FrameGraph/frameGraph.js +1 -0
  30. package/FrameGraph/frameGraph.js.map +1 -1
  31. package/FrameGraph/index.d.ts +1 -0
  32. package/FrameGraph/index.js +1 -0
  33. package/FrameGraph/index.js.map +1 -1
  34. package/Materials/PBR/openpbrMaterial.d.ts +13 -2
  35. package/Materials/PBR/openpbrMaterial.js +47 -16
  36. package/Materials/PBR/openpbrMaterial.js.map +1 -1
  37. package/Materials/PBR/pbrBRDFConfiguration.js +1 -1
  38. package/Materials/PBR/pbrBRDFConfiguration.js.map +1 -1
  39. package/Materials/Textures/Filtering/hdrFiltering.js +6 -0
  40. package/Materials/Textures/Filtering/hdrFiltering.js.map +1 -1
  41. package/Materials/Textures/envCubeTexture.js +13 -13
  42. package/Materials/Textures/envCubeTexture.js.map +1 -1
  43. package/Materials/materialHelper.functions.js +1 -1
  44. package/Materials/materialHelper.functions.js.map +1 -1
  45. package/Misc/textureTools.d.ts +3 -1
  46. package/Misc/textureTools.js +74 -13
  47. package/Misc/textureTools.js.map +1 -1
  48. package/Particles/baseParticleSystem.d.ts +33 -1
  49. package/Particles/baseParticleSystem.js +65 -0
  50. package/Particles/baseParticleSystem.js.map +1 -1
  51. package/Particles/computeShaderParticleSystem.js +6 -0
  52. package/Particles/computeShaderParticleSystem.js.map +1 -1
  53. package/Particles/gpuParticleSystem.d.ts +24 -6
  54. package/Particles/gpuParticleSystem.js +85 -36
  55. package/Particles/gpuParticleSystem.js.map +1 -1
  56. package/Particles/particleSystem.d.ts +0 -7
  57. package/Particles/particleSystem.js +3 -15
  58. package/Particles/particleSystem.js.map +1 -1
  59. package/Particles/thinParticleSystem.d.ts +1 -3
  60. package/Particles/thinParticleSystem.js +1 -27
  61. package/Particles/thinParticleSystem.js.map +1 -1
  62. package/Particles/webgl2ParticleSystem.js +7 -0
  63. package/Particles/webgl2ParticleSystem.js.map +1 -1
  64. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +1 -1
  65. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
  66. package/Rendering/IBLShadows/iblShadowsPluginMaterial.d.ts +3 -1
  67. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js +11 -1
  68. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js.map +1 -1
  69. package/Rendering/IBLShadows/iblShadowsRenderPipeline.d.ts +0 -19
  70. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +21 -65
  71. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
  72. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +15 -52
  73. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +129 -220
  74. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
  75. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +3 -0
  76. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
  77. package/Rendering/geometryBufferRenderer.d.ts +14 -5
  78. package/Rendering/geometryBufferRenderer.js +6 -2
  79. package/Rendering/geometryBufferRenderer.js.map +1 -1
  80. package/Rendering/geometryBufferRendererSceneComponent.d.ts +4 -6
  81. package/Rendering/geometryBufferRendererSceneComponent.js.map +1 -1
  82. package/Rendering/iblCdfGenerator.d.ts +10 -0
  83. package/Rendering/iblCdfGenerator.js +52 -17
  84. package/Rendering/iblCdfGenerator.js.map +1 -1
  85. package/Rendering/index.d.ts +0 -6
  86. package/Rendering/index.js +0 -6
  87. package/Rendering/index.js.map +1 -1
  88. package/Shaders/ShadersInclude/openpbrDirectLighting.js +6 -1
  89. package/Shaders/ShadersInclude/openpbrDirectLighting.js.map +1 -1
  90. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +1 -1
  91. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  92. package/Shaders/gpuUpdateParticles.vertex.js +12 -6
  93. package/Shaders/gpuUpdateParticles.vertex.js.map +1 -1
  94. package/Shaders/iblShadowVoxelTracing.fragment.js +5 -1
  95. package/Shaders/iblShadowVoxelTracing.fragment.js.map +1 -1
  96. package/Shaders/iblVoxelGrid.fragment.d.ts +1 -0
  97. package/Shaders/iblVoxelGrid.fragment.js +33 -5
  98. package/Shaders/iblVoxelGrid.fragment.js.map +1 -1
  99. package/Shaders/lod3D.fragment.d.ts +5 -0
  100. package/Shaders/lod3D.fragment.js +13 -0
  101. package/Shaders/lod3D.fragment.js.map +1 -0
  102. package/Shaders/openpbr.fragment.js +5 -0
  103. package/Shaders/openpbr.fragment.js.map +1 -1
  104. package/ShadersWGSL/ShadersInclude/openpbrDirectLighting.js +6 -1
  105. package/ShadersWGSL/ShadersInclude/openpbrDirectLighting.js.map +1 -1
  106. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +1 -1
  107. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  108. package/ShadersWGSL/gpuUpdateParticles.compute.js +14 -7
  109. package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
  110. package/ShadersWGSL/iblShadowVoxelTracing.fragment.js +5 -1
  111. package/ShadersWGSL/iblShadowVoxelTracing.fragment.js.map +1 -1
  112. package/ShadersWGSL/iblVoxelGrid.fragment.js +1 -1
  113. package/ShadersWGSL/iblVoxelGrid.fragment.js.map +1 -1
  114. package/ShadersWGSL/lod3D.fragment.d.ts +5 -0
  115. package/ShadersWGSL/lod3D.fragment.js +13 -0
  116. package/ShadersWGSL/lod3D.fragment.js.map +1 -0
  117. package/ShadersWGSL/openpbr.fragment.js +5 -0
  118. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  119. package/package.json +1 -1
@@ -0,0 +1,207 @@
1
+
2
+ import { Matrix, Vector4 } from "../../../../Maths/math.vector.js";
3
+ import { ThinCustomPostProcess } from "../../../../PostProcesses/thinCustomPostProcess.js";
4
+ import { FrameGraphTask } from "../../../frameGraphTask.js";
5
+ import { Color4 } from "../../../../Maths/math.color.js";
6
+ /**
7
+ * Task used to trace IBL shadows from a voxel grid.
8
+ * @internal
9
+ */
10
+ export class FrameGraphIblShadowsTracingTask extends FrameGraphTask {
11
+ get sampleDirections() {
12
+ return this._sampleDirections;
13
+ }
14
+ set sampleDirections(value) {
15
+ this._sampleDirections = Math.max(1, Math.round(value));
16
+ }
17
+ get ssShadowSampleCount() {
18
+ return this._ssShadowSampleCount;
19
+ }
20
+ set ssShadowSampleCount(value) {
21
+ this._ssShadowSampleCount = Math.max(1, Math.round(value));
22
+ }
23
+ get ssShadowStride() {
24
+ return this._ssShadowStride;
25
+ }
26
+ set ssShadowStride(value) {
27
+ this._ssShadowStride = Math.max(1, Math.round(value));
28
+ }
29
+ constructor(name, frameGraph) {
30
+ super(name, frameGraph);
31
+ this._sampleDirections = 2;
32
+ this.voxelShadowOpacity = 1;
33
+ this.ssShadowOpacity = 1;
34
+ this._ssShadowSampleCount = 16;
35
+ this._ssShadowStride = 8;
36
+ /** Scale factor applied to voxelGridSize / 2^resolutionExp to get the max SSS ray distance. */
37
+ this.ssShadowDistanceScale = 1.25;
38
+ /** Scale factor applied to voxelGridSize to get the SSS surface thickness. */
39
+ this.ssShadowThicknessScale = 1.0;
40
+ this.envRotation = 0;
41
+ this.voxelNormalBias = 1.4;
42
+ this.voxelDirectionBias = 1.75;
43
+ this.worldScaleMatrix = Matrix.Identity();
44
+ this._shadowParameters = new Vector4(0, 0, 0, 0);
45
+ this._sssParameters = new Vector4(0, 0, 0, 0);
46
+ this._opacityParameters = new Vector4(0, 0, 0, 0);
47
+ this._voxelBiasParameters = new Vector4(0, 0, 0, 0);
48
+ this._cameraInvView = Matrix.Identity();
49
+ this._cameraInvProj = Matrix.Identity();
50
+ this._cameraInvViewProjection = Matrix.Identity();
51
+ this._frameId = 0;
52
+ this._coloredShadows = false;
53
+ this._currentDefines = "";
54
+ this.postProcess = new ThinCustomPostProcess(name, frameGraph.engine, {
55
+ fragmentShader: "iblShadowVoxelTracing",
56
+ uniforms: [
57
+ "viewMtx",
58
+ "projMtx",
59
+ "invProjMtx",
60
+ "invViewMtx",
61
+ "invVPMtx",
62
+ "wsNormalizationMtx",
63
+ "shadowParameters",
64
+ "voxelBiasParameters",
65
+ "sssParameters",
66
+ "shadowOpacity",
67
+ ],
68
+ samplers: ["depthSampler", "worldNormalSampler", "blueNoiseSampler", "icdfSampler", "voxelGridSampler", "iblSampler"],
69
+ shaderLanguage: frameGraph.engine.isWebGPU ? 1 /* ShaderLanguage.WGSL */ : 0 /* ShaderLanguage.GLSL */,
70
+ });
71
+ this._postProcessDrawWrapper = this.postProcess.drawWrapper;
72
+ this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();
73
+ }
74
+ getClassName() {
75
+ return "FrameGraphIblShadowsTracingTask";
76
+ }
77
+ // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
78
+ initAsync() {
79
+ if (this._frameGraph.engine.isWebGPU) {
80
+ return import("../../../../ShadersWGSL/iblShadowVoxelTracing.fragment.js");
81
+ }
82
+ return import("../../../../Shaders/iblShadowVoxelTracing.fragment.js");
83
+ }
84
+ get coloredShadows() {
85
+ return this._coloredShadows;
86
+ }
87
+ set coloredShadows(value) {
88
+ if (this._coloredShadows === value) {
89
+ return;
90
+ }
91
+ this._coloredShadows = value;
92
+ this._updateDefines();
93
+ }
94
+ isReady() {
95
+ return this.postProcess.isReady();
96
+ }
97
+ record() {
98
+ if (this.camera === undefined ||
99
+ this.voxelGridTexture === undefined ||
100
+ this.depthTexture === undefined ||
101
+ this.normalTexture === undefined ||
102
+ this.icdfTexture === undefined) {
103
+ throw new Error(`FrameGraphIblShadowsTracingTask ${this.name}: camera, voxelGridTexture, depthTexture, normalTexture and icdfTexture are required`);
104
+ }
105
+ const textureManager = this._frameGraph.textureManager;
106
+ const size = textureManager.getTextureAbsoluteDimensions(this.depthTexture);
107
+ const creationOptions = {
108
+ size,
109
+ sizeIsPercentage: false,
110
+ isHistoryTexture: false,
111
+ options: {
112
+ createMipMaps: false,
113
+ samples: 1,
114
+ types: [0],
115
+ formats: [5],
116
+ useSRGBBuffers: [false],
117
+ creationFlags: [0],
118
+ labels: [`${this.name} Output`],
119
+ },
120
+ };
121
+ textureManager.resolveDanglingHandle(this.outputTexture, undefined, `${this.name} Output`, creationOptions);
122
+ this._updateDefines();
123
+ const pass = this._frameGraph.addRenderPass(this.name);
124
+ const dependencies = [this.voxelGridTexture, this.depthTexture, this.normalTexture, this.icdfTexture];
125
+ if (this.environmentTexture !== undefined) {
126
+ dependencies.push(this.environmentTexture);
127
+ }
128
+ if (this.blueNoiseTexture !== undefined) {
129
+ dependencies.push(this.blueNoiseTexture);
130
+ }
131
+ pass.addDependencies(dependencies);
132
+ pass.setRenderTarget(this.outputTexture);
133
+ pass.setExecuteFunc((context) => {
134
+ if (this.icdfTexture === undefined || this.blueNoiseTexture === undefined || (this.coloredShadows && this.environmentTexture === undefined)) {
135
+ context.clear(new Color4(1, 1, 1, 1), true, false, false);
136
+ return;
137
+ }
138
+ context.setTextureSamplingMode(this.depthTexture, 1);
139
+ context.setTextureSamplingMode(this.normalTexture, 1);
140
+ context.setTextureSamplingMode(this.icdfTexture, 1);
141
+ context.setTextureSamplingMode(this.blueNoiseTexture, 1);
142
+ const view = this.camera.getViewMatrix();
143
+ const projection = this.camera.getProjectionMatrix();
144
+ projection.invertToRef(this._cameraInvProj);
145
+ view.invertToRef(this._cameraInvView);
146
+ this.camera.getTransformationMatrix().invertToRef(this._cameraInvViewProjection);
147
+ const voxelGridSize = textureManager.getTextureAbsoluteDimensions(this.voxelGridTexture);
148
+ const highestMip = Math.floor(Math.log2(Math.max(1, voxelGridSize.width)));
149
+ this._frameId++;
150
+ let rotation = 0.0;
151
+ if (this.environmentTexture) {
152
+ rotation = this._frameGraph.scene.environmentTexture.rotationY ?? 0;
153
+ }
154
+ rotation = this._frameGraph.scene.useRightHandedSystem ? -(rotation + 0.5 * Math.PI) : rotation - 0.5 * Math.PI;
155
+ rotation = rotation % (2.0 * Math.PI);
156
+ this._shadowParameters.set(this.sampleDirections, this._frameId, 1.0, rotation);
157
+ this._voxelBiasParameters.set(this.voxelNormalBias, this.voxelDirectionBias, highestMip, 0.0);
158
+ const gridSize = this.voxelizationTask?.voxelGridSize ?? 1.0;
159
+ const resExp = this.voxelizationTask?.resolutionExp ?? 6;
160
+ const sssMaxDist = (this.ssShadowDistanceScale * gridSize) / (1 << resExp);
161
+ const sssThickness = this.ssShadowThicknessScale * 0.005 * gridSize;
162
+ this._sssParameters.set(this.ssShadowSampleCount, this.ssShadowStride, sssMaxDist, sssThickness);
163
+ this._opacityParameters.set(this.voxelShadowOpacity, this.ssShadowOpacity, 0.0, 0.0);
164
+ context.applyFullScreenEffect(this._postProcessDrawWrapper, () => {
165
+ const effect = this._postProcessDrawWrapper.effect;
166
+ context.bindTextureHandle(effect, "voxelGridSampler", this.voxelGridTexture);
167
+ context.bindTextureHandle(effect, "depthSampler", this.depthTexture);
168
+ context.bindTextureHandle(effect, "worldNormalSampler", this.normalTexture);
169
+ context.bindTextureHandle(effect, "icdfSampler", this.icdfTexture);
170
+ context.bindTextureHandle(effect, "blueNoiseSampler", this.blueNoiseTexture);
171
+ if (this.coloredShadows && this.environmentTexture !== undefined) {
172
+ context.bindTextureHandle(effect, "iblSampler", this.environmentTexture);
173
+ }
174
+ effect.setMatrix("viewMtx", view);
175
+ effect.setMatrix("projMtx", projection);
176
+ effect.setMatrix("invProjMtx", this._cameraInvProj);
177
+ effect.setMatrix("invViewMtx", this._cameraInvView);
178
+ effect.setMatrix("invVPMtx", this._cameraInvViewProjection);
179
+ effect.setMatrix("wsNormalizationMtx", this.worldScaleMatrix);
180
+ effect.setVector4("shadowParameters", this._shadowParameters);
181
+ effect.setVector4("voxelBiasParameters", this._voxelBiasParameters);
182
+ effect.setVector4("sssParameters", this._sssParameters);
183
+ effect.setVector4("shadowOpacity", this._opacityParameters);
184
+ this.postProcess.bind();
185
+ }, undefined, false, false, true);
186
+ });
187
+ }
188
+ dispose() {
189
+ this.postProcess.dispose();
190
+ super.dispose();
191
+ }
192
+ _updateDefines() {
193
+ const defines = ["#define WORLD_NORMAL_UNSIGNED"];
194
+ if (this._frameGraph.scene.useRightHandedSystem) {
195
+ defines.push("#define RIGHT_HANDED");
196
+ }
197
+ if (this.coloredShadows) {
198
+ defines.push("#define COLOR_SHADOWS 1u");
199
+ }
200
+ const defineString = defines.join("\n");
201
+ if (defineString !== this._currentDefines) {
202
+ this._currentDefines = defineString;
203
+ this.postProcess.updateEffect(this._currentDefines);
204
+ }
205
+ }
206
+ }
207
+ //# sourceMappingURL=iblShadowsTracingTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iblShadowsTracingTask.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Camera, type DrawWrapper, type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type FrameGraphIblShadowsVoxelizationTask } from \"./iblShadowsVoxelizationTask\";\r\nimport { Matrix, Vector4 } from \"core/Maths/math.vector\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinCustomPostProcess } from \"core/PostProcesses/thinCustomPostProcess\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { type CubeTexture } from \"core/Materials/Textures/cubeTexture\";\r\n\r\n/**\r\n * Task used to trace IBL shadows from a voxel grid.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsTracingTask extends FrameGraphTask {\r\n public camera?: Camera;\r\n public voxelGridTexture?: FrameGraphTextureHandle;\r\n public depthTexture?: FrameGraphTextureHandle;\r\n public normalTexture?: FrameGraphTextureHandle;\r\n public icdfTexture?: FrameGraphTextureHandle;\r\n public environmentTexture?: FrameGraphTextureHandle;\r\n public blueNoiseTexture?: FrameGraphTextureHandle;\r\n\r\n private _sampleDirections = 2;\r\n\r\n public get sampleDirections(): number {\r\n return this._sampleDirections;\r\n }\r\n\r\n public set sampleDirections(value: number) {\r\n this._sampleDirections = Math.max(1, Math.round(value));\r\n }\r\n\r\n public voxelShadowOpacity = 1;\r\n public ssShadowOpacity = 1;\r\n\r\n private _ssShadowSampleCount = 16;\r\n\r\n public get ssShadowSampleCount(): number {\r\n return this._ssShadowSampleCount;\r\n }\r\n\r\n public set ssShadowSampleCount(value: number) {\r\n this._ssShadowSampleCount = Math.max(1, Math.round(value));\r\n }\r\n\r\n private _ssShadowStride = 8;\r\n\r\n public get ssShadowStride(): number {\r\n return this._ssShadowStride;\r\n }\r\n\r\n public set ssShadowStride(value: number) {\r\n this._ssShadowStride = Math.max(1, Math.round(value));\r\n }\r\n /** Scale factor applied to voxelGridSize / 2^resolutionExp to get the max SSS ray distance. */\r\n public ssShadowDistanceScale = 1.25;\r\n /** Scale factor applied to voxelGridSize to get the SSS surface thickness. */\r\n public ssShadowThicknessScale = 1.0;\r\n /** Voxelization task providing dynamic voxelGridSize and resolutionExp for SSS parameter derivation. */\r\n public voxelizationTask?: FrameGraphIblShadowsVoxelizationTask;\r\n public envRotation = 0;\r\n public voxelNormalBias = 1.4;\r\n public voxelDirectionBias = 1.75;\r\n public worldScaleMatrix = Matrix.Identity();\r\n\r\n public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n public readonly postProcess: ThinCustomPostProcess;\r\n protected readonly _postProcessDrawWrapper: DrawWrapper;\r\n protected readonly _shadowParameters = new Vector4(0, 0, 0, 0);\r\n protected readonly _sssParameters = new Vector4(0, 0, 0, 0);\r\n protected readonly _opacityParameters = new Vector4(0, 0, 0, 0);\r\n protected readonly _voxelBiasParameters = new Vector4(0, 0, 0, 0);\r\n protected readonly _cameraInvView = Matrix.Identity();\r\n protected readonly _cameraInvProj = Matrix.Identity();\r\n protected readonly _cameraInvViewProjection = Matrix.Identity();\r\n protected _frameId = 0;\r\n protected _coloredShadows = false;\r\n protected _currentDefines = \"\";\r\n\r\n constructor(name: string, frameGraph: FrameGraph) {\r\n super(name, frameGraph);\r\n\r\n this.postProcess = new ThinCustomPostProcess(name, frameGraph.engine, {\r\n fragmentShader: \"iblShadowVoxelTracing\",\r\n uniforms: [\r\n \"viewMtx\",\r\n \"projMtx\",\r\n \"invProjMtx\",\r\n \"invViewMtx\",\r\n \"invVPMtx\",\r\n \"wsNormalizationMtx\",\r\n \"shadowParameters\",\r\n \"voxelBiasParameters\",\r\n \"sssParameters\",\r\n \"shadowOpacity\",\r\n ],\r\n samplers: [\"depthSampler\", \"worldNormalSampler\", \"blueNoiseSampler\", \"icdfSampler\", \"voxelGridSampler\", \"iblSampler\"],\r\n shaderLanguage: frameGraph.engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n });\r\n this._postProcessDrawWrapper = this.postProcess.drawWrapper;\r\n\r\n this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n }\r\n\r\n public override getClassName(): string {\r\n return \"FrameGraphIblShadowsTracingTask\";\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n public override initAsync(): Promise<unknown> {\r\n if (this._frameGraph.engine.isWebGPU) {\r\n return import(\"../../../../ShadersWGSL/iblShadowVoxelTracing.fragment\");\r\n }\r\n\r\n return import(\"../../../../Shaders/iblShadowVoxelTracing.fragment\");\r\n }\r\n\r\n public get coloredShadows(): boolean {\r\n return this._coloredShadows;\r\n }\r\n\r\n public set coloredShadows(value: boolean) {\r\n if (this._coloredShadows === value) {\r\n return;\r\n }\r\n\r\n this._coloredShadows = value;\r\n this._updateDefines();\r\n }\r\n\r\n public override isReady(): boolean {\r\n return this.postProcess.isReady();\r\n }\r\n\r\n public override record() {\r\n if (\r\n this.camera === undefined ||\r\n this.voxelGridTexture === undefined ||\r\n this.depthTexture === undefined ||\r\n this.normalTexture === undefined ||\r\n this.icdfTexture === undefined\r\n ) {\r\n throw new Error(`FrameGraphIblShadowsTracingTask ${this.name}: camera, voxelGridTexture, depthTexture, normalTexture and icdfTexture are required`);\r\n }\r\n\r\n const textureManager = this._frameGraph.textureManager;\r\n const size = textureManager.getTextureAbsoluteDimensions(this.depthTexture);\r\n const creationOptions: FrameGraphTextureCreationOptions = {\r\n size,\r\n sizeIsPercentage: false,\r\n isHistoryTexture: false,\r\n options: {\r\n createMipMaps: false,\r\n samples: 1,\r\n types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n formats: [Constants.TEXTUREFORMAT_RGBA],\r\n useSRGBBuffers: [false],\r\n creationFlags: [0],\r\n labels: [`${this.name} Output`],\r\n },\r\n };\r\n\r\n textureManager.resolveDanglingHandle(this.outputTexture, undefined, `${this.name} Output`, creationOptions);\r\n\r\n this._updateDefines();\r\n\r\n const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n const dependencies: FrameGraphTextureHandle[] = [this.voxelGridTexture, this.depthTexture, this.normalTexture, this.icdfTexture];\r\n if (this.environmentTexture !== undefined) {\r\n dependencies.push(this.environmentTexture);\r\n }\r\n if (this.blueNoiseTexture !== undefined) {\r\n dependencies.push(this.blueNoiseTexture);\r\n }\r\n pass.addDependencies(dependencies);\r\n pass.setRenderTarget(this.outputTexture);\r\n pass.setExecuteFunc((context) => {\r\n if (this.icdfTexture === undefined || this.blueNoiseTexture === undefined || (this.coloredShadows && this.environmentTexture === undefined)) {\r\n context.clear(new Color4(1, 1, 1, 1), true, false, false);\r\n return;\r\n }\r\n\r\n context.setTextureSamplingMode(this.depthTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n context.setTextureSamplingMode(this.normalTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n context.setTextureSamplingMode(this.icdfTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n context.setTextureSamplingMode(this.blueNoiseTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n\r\n const view = this.camera!.getViewMatrix();\r\n const projection = this.camera!.getProjectionMatrix();\r\n projection.invertToRef(this._cameraInvProj);\r\n view.invertToRef(this._cameraInvView);\r\n this.camera!.getTransformationMatrix().invertToRef(this._cameraInvViewProjection);\r\n\r\n const voxelGridSize = textureManager.getTextureAbsoluteDimensions(this.voxelGridTexture!);\r\n const highestMip = Math.floor(Math.log2(Math.max(1, voxelGridSize.width)));\r\n\r\n this._frameId++;\r\n let rotation = 0.0;\r\n if (this.environmentTexture) {\r\n rotation = (this._frameGraph.scene.environmentTexture as CubeTexture).rotationY ?? 0;\r\n }\r\n rotation = this._frameGraph.scene.useRightHandedSystem ? -(rotation + 0.5 * Math.PI) : rotation - 0.5 * Math.PI;\r\n rotation = rotation % (2.0 * Math.PI);\r\n this._shadowParameters.set(this.sampleDirections, this._frameId, 1.0, rotation);\r\n this._voxelBiasParameters.set(this.voxelNormalBias, this.voxelDirectionBias, highestMip, 0.0);\r\n const gridSize = this.voxelizationTask?.voxelGridSize ?? 1.0;\r\n const resExp = this.voxelizationTask?.resolutionExp ?? 6;\r\n const sssMaxDist = (this.ssShadowDistanceScale * gridSize) / (1 << resExp);\r\n const sssThickness = this.ssShadowThicknessScale * 0.005 * gridSize;\r\n this._sssParameters.set(this.ssShadowSampleCount, this.ssShadowStride, sssMaxDist, sssThickness);\r\n this._opacityParameters.set(this.voxelShadowOpacity, this.ssShadowOpacity, 0.0, 0.0);\r\n\r\n context.applyFullScreenEffect(\r\n this._postProcessDrawWrapper,\r\n () => {\r\n const effect = this._postProcessDrawWrapper.effect!;\r\n\r\n context.bindTextureHandle(effect, \"voxelGridSampler\", this.voxelGridTexture!);\r\n context.bindTextureHandle(effect, \"depthSampler\", this.depthTexture!);\r\n context.bindTextureHandle(effect, \"worldNormalSampler\", this.normalTexture!);\r\n context.bindTextureHandle(effect, \"icdfSampler\", this.icdfTexture!);\r\n context.bindTextureHandle(effect, \"blueNoiseSampler\", this.blueNoiseTexture!);\r\n if (this.coloredShadows && this.environmentTexture !== undefined) {\r\n context.bindTextureHandle(effect, \"iblSampler\", this.environmentTexture);\r\n }\r\n\r\n effect.setMatrix(\"viewMtx\", view);\r\n effect.setMatrix(\"projMtx\", projection);\r\n effect.setMatrix(\"invProjMtx\", this._cameraInvProj);\r\n effect.setMatrix(\"invViewMtx\", this._cameraInvView);\r\n effect.setMatrix(\"invVPMtx\", this._cameraInvViewProjection);\r\n effect.setMatrix(\"wsNormalizationMtx\", this.worldScaleMatrix);\r\n effect.setVector4(\"shadowParameters\", this._shadowParameters);\r\n effect.setVector4(\"voxelBiasParameters\", this._voxelBiasParameters);\r\n effect.setVector4(\"sssParameters\", this._sssParameters);\r\n effect.setVector4(\"shadowOpacity\", this._opacityParameters);\r\n\r\n this.postProcess.bind();\r\n },\r\n undefined,\r\n false,\r\n false,\r\n true\r\n );\r\n });\r\n }\r\n\r\n public override dispose(): void {\r\n this.postProcess.dispose();\r\n super.dispose();\r\n }\r\n\r\n protected _updateDefines(): void {\r\n const defines: string[] = [\"#define WORLD_NORMAL_UNSIGNED\"];\r\n\r\n if (this._frameGraph.scene.useRightHandedSystem) {\r\n defines.push(\"#define RIGHT_HANDED\");\r\n }\r\n if (this.coloredShadows) {\r\n defines.push(\"#define COLOR_SHADOWS 1u\");\r\n }\r\n\r\n const defineString = defines.join(\"\\n\");\r\n if (defineString !== this._currentDefines) {\r\n this._currentDefines = defineString;\r\n this.postProcess.updateEffect(this._currentDefines);\r\n }\r\n }\r\n}\r\n"]}
@@ -0,0 +1,104 @@
1
+ import { type FrameGraph, type FrameGraphObjectList, type FrameGraphTextureHandle } from "../../../../index.js";
2
+ import { Matrix } from "../../../../Maths/math.vector.js";
3
+ import { Observable } from "../../../../Misc/observable.js";
4
+ import { FrameGraphTask } from "../../../frameGraphTask.js";
5
+ /**
6
+ * Task used to voxelize shadow casting objects for IBL shadows.
7
+ * @internal
8
+ */
9
+ export declare class FrameGraphIblShadowsVoxelizationTask extends FrameGraphTask {
10
+ /**
11
+ * Observable raised when voxelization completes.
12
+ */
13
+ readonly onVoxelizationCompleteObservable: Observable<void>;
14
+ /**
15
+ * Input object list containing the meshes to voxelize.
16
+ */
17
+ objectList: FrameGraphObjectList;
18
+ /**
19
+ * World-space voxel grid size.
20
+ */
21
+ voxelGridSize: number;
22
+ /**
23
+ * Voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
24
+ */
25
+ private _resolutionExp;
26
+ /**
27
+ * Sets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
28
+ */
29
+ set resolutionExp(value: number);
30
+ /**
31
+ * Gets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
32
+ */
33
+ get resolutionExp(): number;
34
+ /**
35
+ * Enables tri-planar voxelization mode.
36
+ */
37
+ triPlanarVoxelization: boolean;
38
+ /**
39
+ * Indicates whether voxelization should be refreshed.
40
+ */
41
+ dirty: boolean;
42
+ private _refreshRate;
43
+ /**
44
+ * Controls how often voxelization is refreshed.
45
+ * - -1: manual only (requires setting `dirty = true`)
46
+ * - 0: every frame
47
+ * - 1: skip 1 frame between updates
48
+ * - N: skip N frames between updates
49
+ */
50
+ get refreshRate(): number;
51
+ set refreshRate(value: number);
52
+ /**
53
+ * World-to-voxel normalization matrix used by tracing.
54
+ */
55
+ readonly worldScaleMatrix: Matrix;
56
+ /**
57
+ * Output voxel grid texture handle.
58
+ */
59
+ readonly outputVoxelGridTexture: FrameGraphTextureHandle;
60
+ private _voxelRenderer?;
61
+ private _voxelRendererResolutionExp?;
62
+ private _voxelRendererTriPlanar?;
63
+ private _voxelizationCompleteObserver;
64
+ private _voxelRTTextureHandle?;
65
+ private _voxelGridTextureHandle?;
66
+ private _frameCounter;
67
+ /**
68
+ * Creates a new voxelization task.
69
+ * @param name The task name.
70
+ * @param frameGraph The frame graph this task belongs to.
71
+ */
72
+ constructor(name: string, frameGraph: FrameGraph);
73
+ /**
74
+ * Gets the class name.
75
+ * @returns The class name.
76
+ */
77
+ getClassName(): string;
78
+ /**
79
+ * Checks whether the task has all required inputs.
80
+ * @returns True when ready.
81
+ */
82
+ isReady(): boolean;
83
+ /**
84
+ * Requests a voxelization update on the next eligible frame.
85
+ */
86
+ requestVoxelizationUpdate(): void;
87
+ /**
88
+ * Recomputes voxel world bounds from the current object list and updates worldScaleMatrix.
89
+ */
90
+ updateSceneBounds(): void;
91
+ /**
92
+ * Records the voxelization passes.
93
+ */
94
+ record(): void;
95
+ /**
96
+ * Disposes internal resources.
97
+ */
98
+ dispose(): void;
99
+ private _ensureVoxelRenderer;
100
+ private _attachVoxelizationObserver;
101
+ private _detachVoxelizationObserver;
102
+ private _updateWorldScaleMatrix;
103
+ private _updateOutputTextureHandlesFromRenderer;
104
+ }
@@ -0,0 +1,218 @@
1
+ import { Matrix, Quaternion, Vector3 } from "../../../../Maths/math.vector.js";
2
+ import { Observable } from "../../../../Misc/observable.js";
3
+ import { _IblShadowsVoxelRenderer } from "../../../../Rendering/IBLShadows/iblShadowsVoxelRenderer.js";
4
+ import { FrameGraphTask } from "../../../frameGraphTask.js";
5
+ /**
6
+ * Task used to voxelize shadow casting objects for IBL shadows.
7
+ * @internal
8
+ */
9
+ export class FrameGraphIblShadowsVoxelizationTask extends FrameGraphTask {
10
+ /**
11
+ * Sets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
12
+ */
13
+ set resolutionExp(value) {
14
+ const newValue = Math.round(Math.max(1, Math.min(value, 8)));
15
+ if (newValue === this._resolutionExp) {
16
+ return;
17
+ }
18
+ this._resolutionExp = newValue;
19
+ if (this._voxelRenderer) {
20
+ this._voxelRenderer.voxelResolutionExp = this._resolutionExp;
21
+ }
22
+ this.dirty = true;
23
+ }
24
+ /**
25
+ * Gets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
26
+ */
27
+ get resolutionExp() {
28
+ return this._resolutionExp;
29
+ }
30
+ /**
31
+ * Controls how often voxelization is refreshed.
32
+ * - -1: manual only (requires setting `dirty = true`)
33
+ * - 0: every frame
34
+ * - 1: skip 1 frame between updates
35
+ * - N: skip N frames between updates
36
+ */
37
+ get refreshRate() {
38
+ return this._refreshRate;
39
+ }
40
+ set refreshRate(value) {
41
+ this._refreshRate = Math.max(-1, Math.round(value));
42
+ }
43
+ /**
44
+ * Creates a new voxelization task.
45
+ * @param name The task name.
46
+ * @param frameGraph The frame graph this task belongs to.
47
+ */
48
+ constructor(name, frameGraph) {
49
+ super(name, frameGraph);
50
+ /**
51
+ * Observable raised when voxelization completes.
52
+ */
53
+ this.onVoxelizationCompleteObservable = new Observable();
54
+ /**
55
+ * World-space voxel grid size.
56
+ */
57
+ this.voxelGridSize = 1;
58
+ /**
59
+ * Voxel grid resolution exponent. Actual resolution is 2^resolutionExp.
60
+ */
61
+ this._resolutionExp = 6;
62
+ /**
63
+ * Enables tri-planar voxelization mode.
64
+ */
65
+ this.triPlanarVoxelization = true;
66
+ /**
67
+ * Indicates whether voxelization should be refreshed.
68
+ */
69
+ this.dirty = true;
70
+ this._refreshRate = -1;
71
+ /**
72
+ * World-to-voxel normalization matrix used by tracing.
73
+ */
74
+ this.worldScaleMatrix = Matrix.Identity();
75
+ this._voxelizationCompleteObserver = null;
76
+ this._frameCounter = 0;
77
+ this.outputVoxelGridTexture = this._frameGraph.textureManager.createDanglingHandle();
78
+ }
79
+ /**
80
+ * Gets the class name.
81
+ * @returns The class name.
82
+ */
83
+ getClassName() {
84
+ return "FrameGraphIblShadowsVoxelizationTask";
85
+ }
86
+ /**
87
+ * Checks whether the task has all required inputs.
88
+ * @returns True when ready.
89
+ */
90
+ isReady() {
91
+ return true;
92
+ }
93
+ /**
94
+ * Requests a voxelization update on the next eligible frame.
95
+ */
96
+ requestVoxelizationUpdate() {
97
+ this.dirty = true;
98
+ }
99
+ /**
100
+ * Recomputes voxel world bounds from the current object list and updates worldScaleMatrix.
101
+ */
102
+ updateSceneBounds() {
103
+ this._updateWorldScaleMatrix();
104
+ }
105
+ /**
106
+ * Records the voxelization passes.
107
+ */
108
+ record() {
109
+ if (this.objectList === undefined) {
110
+ throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: objectList is required`);
111
+ }
112
+ this._ensureVoxelRenderer();
113
+ this._updateWorldScaleMatrix();
114
+ this._updateOutputTextureHandlesFromRenderer();
115
+ const voxelRT = this._voxelRenderer.getRT();
116
+ const voxelRTInternalTexture = voxelRT.getInternalTexture();
117
+ if (!voxelRTInternalTexture) {
118
+ throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer RT texture is unavailable`);
119
+ }
120
+ this._voxelRTTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel RT`, voxelRTInternalTexture, this._voxelRTTextureHandle);
121
+ const pass = this._frameGraph.addRenderPass(this.name);
122
+ pass.setRenderTarget(this._voxelRTTextureHandle);
123
+ pass.addDependencies(this.outputVoxelGridTexture);
124
+ pass.setExecuteFunc((context) => {
125
+ context.restoreDefaultFramebuffer();
126
+ this._frameCounter++;
127
+ const shouldRefreshFromRate = this.refreshRate >= 0 && (this._frameCounter - 1) % (this.refreshRate + 1) === 0;
128
+ if (this._voxelRenderer.isVoxelizationInProgress()) {
129
+ this._voxelRenderer.processVoxelization();
130
+ return;
131
+ }
132
+ if (this.dirty || shouldRefreshFromRate) {
133
+ const meshes = this.objectList.meshes;
134
+ if (meshes.length === 0) {
135
+ return;
136
+ }
137
+ this._ensureVoxelRenderer();
138
+ this._updateWorldScaleMatrix();
139
+ this._voxelRenderer.setWorldScaleMatrix(this.worldScaleMatrix);
140
+ this._voxelRenderer.updateVoxelGrid(meshes, false);
141
+ this.dirty = false;
142
+ }
143
+ if (this._voxelRenderer.isVoxelizationInProgress()) {
144
+ this._voxelRenderer.processVoxelization();
145
+ }
146
+ });
147
+ }
148
+ /**
149
+ * Disposes internal resources.
150
+ */
151
+ dispose() {
152
+ this._detachVoxelizationObserver();
153
+ this._voxelRenderer?.dispose();
154
+ this._voxelRenderer = undefined;
155
+ this.onVoxelizationCompleteObservable.clear();
156
+ super.dispose();
157
+ }
158
+ _ensureVoxelRenderer() {
159
+ const needsNewRenderer = !this._voxelRenderer || this._voxelRendererResolutionExp !== this.resolutionExp || this._voxelRendererTriPlanar !== this.triPlanarVoxelization;
160
+ if (!needsNewRenderer) {
161
+ return;
162
+ }
163
+ this._voxelRenderer?.dispose();
164
+ this._voxelRenderer = new _IblShadowsVoxelRenderer(this._frameGraph.scene, {}, this.resolutionExp, this.triPlanarVoxelization);
165
+ this._attachVoxelizationObserver();
166
+ this._voxelRendererResolutionExp = this.resolutionExp;
167
+ this._voxelRendererTriPlanar = this.triPlanarVoxelization;
168
+ }
169
+ _attachVoxelizationObserver() {
170
+ this._detachVoxelizationObserver();
171
+ if (!this._voxelRenderer) {
172
+ return;
173
+ }
174
+ this._voxelizationCompleteObserver = this._voxelRenderer.onVoxelizationCompleteObservable.add(() => {
175
+ this._updateOutputTextureHandlesFromRenderer();
176
+ this.onVoxelizationCompleteObservable.notifyObservers();
177
+ });
178
+ }
179
+ _detachVoxelizationObserver() {
180
+ if (this._voxelRenderer && this._voxelizationCompleteObserver) {
181
+ this._voxelRenderer.onVoxelizationCompleteObservable.remove(this._voxelizationCompleteObserver);
182
+ }
183
+ this._voxelizationCompleteObserver = null;
184
+ }
185
+ _updateWorldScaleMatrix() {
186
+ const meshes = this.objectList?.meshes;
187
+ if (!meshes || meshes.length === 0 || !isFinite(this.voxelGridSize) || this.voxelGridSize <= 0) {
188
+ this.worldScaleMatrix.copyFrom(Matrix.Identity());
189
+ return;
190
+ }
191
+ const bounds = {
192
+ min: new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE),
193
+ max: new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE),
194
+ };
195
+ for (const mesh of meshes) {
196
+ const localBounds = mesh.getHierarchyBoundingVectors(true);
197
+ bounds.min = Vector3.Minimize(bounds.min, localBounds.min);
198
+ bounds.max = Vector3.Maximize(bounds.max, localBounds.max);
199
+ }
200
+ const size = bounds.max.subtract(bounds.min);
201
+ this.voxelGridSize = Math.max(size.x, size.y, size.z);
202
+ const halfSize = this.voxelGridSize / 2.0;
203
+ const centerOffset = bounds.max.add(bounds.min).multiplyByFloats(-0.5, -0.5, -0.5);
204
+ const invWorldScaleMatrix = Matrix.Compose(new Vector3(1.0 / halfSize, 1.0 / halfSize, 1.0 / halfSize), new Quaternion(), Vector3.Zero());
205
+ const invTranslationMatrix = Matrix.Compose(new Vector3(1.0, 1.0, 1.0), new Quaternion(), centerOffset);
206
+ invTranslationMatrix.multiplyToRef(invWorldScaleMatrix, this.worldScaleMatrix);
207
+ }
208
+ _updateOutputTextureHandlesFromRenderer() {
209
+ const voxelTexture = this._voxelRenderer.getVoxelGrid();
210
+ const voxelInternalTexture = voxelTexture.getInternalTexture();
211
+ if (!voxelInternalTexture) {
212
+ throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer texture is unavailable`);
213
+ }
214
+ this._voxelGridTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel Grid`, voxelInternalTexture, this._voxelGridTextureHandle);
215
+ this._frameGraph.textureManager.resolveDanglingHandle(this.outputVoxelGridTexture, this._voxelGridTextureHandle);
216
+ }
217
+ }
218
+ //# sourceMappingURL=iblShadowsVoxelizationTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iblShadowsVoxelizationTask.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.ts"],"names":[],"mappings":"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","sourcesContent":["import { type FrameGraph, type FrameGraphObjectList, type FrameGraphTextureHandle, type Mesh, type Observer } from \"core/index\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { _IblShadowsVoxelRenderer } from \"core/Rendering/IBLShadows/iblShadowsVoxelRenderer\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to voxelize shadow casting objects for IBL shadows.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsVoxelizationTask extends FrameGraphTask {\r\n /**\r\n * Observable raised when voxelization completes.\r\n */\r\n public readonly onVoxelizationCompleteObservable = new Observable<void>();\r\n\r\n /**\r\n * Input object list containing the meshes to voxelize.\r\n */\r\n public objectList: FrameGraphObjectList;\r\n\r\n /**\r\n * World-space voxel grid size.\r\n */\r\n public voxelGridSize = 1;\r\n\r\n /**\r\n * Voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n */\r\n private _resolutionExp = 6;\r\n /**\r\n * Sets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n */\r\n public set resolutionExp(value: number) {\r\n const newValue = Math.round(Math.max(1, Math.min(value, 8)));\r\n if (newValue === this._resolutionExp) {\r\n return;\r\n }\r\n this._resolutionExp = newValue;\r\n if (this._voxelRenderer) {\r\n this._voxelRenderer.voxelResolutionExp = this._resolutionExp;\r\n }\r\n this.dirty = true;\r\n }\r\n /**\r\n * Gets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n */\r\n public get resolutionExp(): number {\r\n return this._resolutionExp;\r\n }\r\n\r\n /**\r\n * Enables tri-planar voxelization mode.\r\n */\r\n public triPlanarVoxelization = true;\r\n\r\n /**\r\n * Indicates whether voxelization should be refreshed.\r\n */\r\n public dirty = true;\r\n\r\n private _refreshRate = -1;\r\n\r\n /**\r\n * Controls how often voxelization is refreshed.\r\n * - -1: manual only (requires setting `dirty = true`)\r\n * - 0: every frame\r\n * - 1: skip 1 frame between updates\r\n * - N: skip N frames between updates\r\n */\r\n public get refreshRate(): number {\r\n return this._refreshRate;\r\n }\r\n\r\n public set refreshRate(value: number) {\r\n this._refreshRate = Math.max(-1, Math.round(value));\r\n }\r\n\r\n /**\r\n * World-to-voxel normalization matrix used by tracing.\r\n */\r\n public readonly worldScaleMatrix = Matrix.Identity();\r\n\r\n /**\r\n * Output voxel grid texture handle.\r\n */\r\n public readonly outputVoxelGridTexture: FrameGraphTextureHandle;\r\n\r\n private _voxelRenderer?: _IblShadowsVoxelRenderer;\r\n private _voxelRendererResolutionExp?: number;\r\n private _voxelRendererTriPlanar?: boolean;\r\n private _voxelizationCompleteObserver: Observer<void> | null = null;\r\n private _voxelRTTextureHandle?: FrameGraphTextureHandle;\r\n private _voxelGridTextureHandle?: FrameGraphTextureHandle;\r\n private _frameCounter = 0;\r\n\r\n /**\r\n * Creates a new voxelization task.\r\n * @param name The task name.\r\n * @param frameGraph The frame graph this task belongs to.\r\n */\r\n constructor(name: string, frameGraph: FrameGraph) {\r\n super(name, frameGraph);\r\n\r\n this.outputVoxelGridTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n }\r\n\r\n /**\r\n * Gets the class name.\r\n * @returns The class name.\r\n */\r\n public override getClassName(): string {\r\n return \"FrameGraphIblShadowsVoxelizationTask\";\r\n }\r\n\r\n /**\r\n * Checks whether the task has all required inputs.\r\n * @returns True when ready.\r\n */\r\n public override isReady(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Requests a voxelization update on the next eligible frame.\r\n */\r\n public requestVoxelizationUpdate(): void {\r\n this.dirty = true;\r\n }\r\n\r\n /**\r\n * Recomputes voxel world bounds from the current object list and updates worldScaleMatrix.\r\n */\r\n public updateSceneBounds(): void {\r\n this._updateWorldScaleMatrix();\r\n }\r\n\r\n /**\r\n * Records the voxelization passes.\r\n */\r\n public override record() {\r\n if (this.objectList === undefined) {\r\n throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: objectList is required`);\r\n }\r\n\r\n this._ensureVoxelRenderer();\r\n this._updateWorldScaleMatrix();\r\n\r\n this._updateOutputTextureHandlesFromRenderer();\r\n\r\n const voxelRT = this._voxelRenderer!.getRT();\r\n const voxelRTInternalTexture = voxelRT.getInternalTexture();\r\n if (!voxelRTInternalTexture) {\r\n throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer RT texture is unavailable`);\r\n }\r\n this._voxelRTTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel RT`, voxelRTInternalTexture, this._voxelRTTextureHandle);\r\n\r\n const pass = this._frameGraph.addRenderPass(this.name);\r\n pass.setRenderTarget(this._voxelRTTextureHandle);\r\n pass.addDependencies(this.outputVoxelGridTexture);\r\n pass.setExecuteFunc((context) => {\r\n context.restoreDefaultFramebuffer();\r\n\r\n this._frameCounter++;\r\n const shouldRefreshFromRate = this.refreshRate >= 0 && (this._frameCounter - 1) % (this.refreshRate + 1) === 0;\r\n\r\n if (this._voxelRenderer!.isVoxelizationInProgress()) {\r\n this._voxelRenderer!.processVoxelization();\r\n return;\r\n }\r\n\r\n if (this.dirty || shouldRefreshFromRate) {\r\n const meshes = this.objectList!.meshes as Mesh[];\r\n if (meshes.length === 0) {\r\n return;\r\n }\r\n\r\n this._ensureVoxelRenderer();\r\n this._updateWorldScaleMatrix();\r\n this._voxelRenderer!.setWorldScaleMatrix(this.worldScaleMatrix);\r\n this._voxelRenderer!.updateVoxelGrid(meshes, false);\r\n this.dirty = false;\r\n }\r\n\r\n if (this._voxelRenderer!.isVoxelizationInProgress()) {\r\n this._voxelRenderer!.processVoxelization();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Disposes internal resources.\r\n */\r\n public override dispose(): void {\r\n this._detachVoxelizationObserver();\r\n this._voxelRenderer?.dispose();\r\n this._voxelRenderer = undefined;\r\n this.onVoxelizationCompleteObservable.clear();\r\n super.dispose();\r\n }\r\n\r\n private _ensureVoxelRenderer(): void {\r\n const needsNewRenderer = !this._voxelRenderer || this._voxelRendererResolutionExp !== this.resolutionExp || this._voxelRendererTriPlanar !== this.triPlanarVoxelization;\r\n\r\n if (!needsNewRenderer) {\r\n return;\r\n }\r\n\r\n this._voxelRenderer?.dispose();\r\n this._voxelRenderer = new _IblShadowsVoxelRenderer(this._frameGraph.scene, {} as never, this.resolutionExp, this.triPlanarVoxelization);\r\n this._attachVoxelizationObserver();\r\n this._voxelRendererResolutionExp = this.resolutionExp;\r\n this._voxelRendererTriPlanar = this.triPlanarVoxelization;\r\n }\r\n\r\n private _attachVoxelizationObserver(): void {\r\n this._detachVoxelizationObserver();\r\n\r\n if (!this._voxelRenderer) {\r\n return;\r\n }\r\n\r\n this._voxelizationCompleteObserver = this._voxelRenderer.onVoxelizationCompleteObservable.add(() => {\r\n this._updateOutputTextureHandlesFromRenderer();\r\n this.onVoxelizationCompleteObservable.notifyObservers();\r\n });\r\n }\r\n\r\n private _detachVoxelizationObserver(): void {\r\n if (this._voxelRenderer && this._voxelizationCompleteObserver) {\r\n this._voxelRenderer.onVoxelizationCompleteObservable.remove(this._voxelizationCompleteObserver);\r\n }\r\n\r\n this._voxelizationCompleteObserver = null;\r\n }\r\n\r\n private _updateWorldScaleMatrix(): void {\r\n const meshes = this.objectList?.meshes as Mesh[] | undefined;\r\n if (!meshes || meshes.length === 0 || !isFinite(this.voxelGridSize) || this.voxelGridSize <= 0) {\r\n this.worldScaleMatrix.copyFrom(Matrix.Identity());\r\n return;\r\n }\r\n\r\n const bounds = {\r\n min: new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE),\r\n max: new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE),\r\n };\r\n\r\n for (const mesh of meshes) {\r\n const localBounds = mesh.getHierarchyBoundingVectors(true);\r\n bounds.min = Vector3.Minimize(bounds.min, localBounds.min);\r\n bounds.max = Vector3.Maximize(bounds.max, localBounds.max);\r\n }\r\n\r\n const size = bounds.max.subtract(bounds.min);\r\n this.voxelGridSize = Math.max(size.x, size.y, size.z);\r\n\r\n const halfSize = this.voxelGridSize / 2.0;\r\n const centerOffset = bounds.max.add(bounds.min).multiplyByFloats(-0.5, -0.5, -0.5);\r\n const invWorldScaleMatrix = Matrix.Compose(new Vector3(1.0 / halfSize, 1.0 / halfSize, 1.0 / halfSize), new Quaternion(), Vector3.Zero());\r\n const invTranslationMatrix = Matrix.Compose(new Vector3(1.0, 1.0, 1.0), new Quaternion(), centerOffset);\r\n invTranslationMatrix.multiplyToRef(invWorldScaleMatrix, this.worldScaleMatrix);\r\n }\r\n\r\n private _updateOutputTextureHandlesFromRenderer(): void {\r\n const voxelTexture = this._voxelRenderer!.getVoxelGrid();\r\n const voxelInternalTexture = voxelTexture.getInternalTexture();\r\n if (!voxelInternalTexture) {\r\n throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer texture is unavailable`);\r\n }\r\n\r\n this._voxelGridTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel Grid`, voxelInternalTexture, this._voxelGridTextureHandle);\r\n this._frameGraph.textureManager.resolveDanglingHandle(this.outputVoxelGridTexture, this._voxelGridTextureHandle);\r\n }\r\n}\r\n"]}