babylonjs-editor-tools 5.5.1 → 5.5.2

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 (44) hide show
  1. package/build/index.node.js +407 -121
  2. package/build/src/decorators/apply.js +2 -2
  3. package/build/src/decorators/apply.js.map +1 -1
  4. package/build/src/decorators/scene.js +16 -16
  5. package/build/src/decorators/scene.js.map +1 -1
  6. package/build/src/decorators/sound.js +2 -2
  7. package/build/src/decorators/sound.js.map +1 -1
  8. package/build/src/index.js +1 -0
  9. package/build/src/index.js.map +1 -1
  10. package/build/src/loading/loader.js +21 -7
  11. package/build/src/loading/loader.js.map +1 -1
  12. package/build/src/rendering/order.js +110 -0
  13. package/build/src/rendering/order.js.map +1 -0
  14. package/build/src/rendering/ssao.js +1 -1
  15. package/build/src/rendering/ssao.js.map +1 -1
  16. package/build/src/rendering/tools.js +3 -0
  17. package/build/src/rendering/tools.js.map +1 -1
  18. package/build/src/rendering/volumetric/pipeline.js +403 -26
  19. package/build/src/rendering/volumetric/pipeline.js.map +1 -1
  20. package/build/src/rendering/volumetric/selector.js +2 -1
  21. package/build/src/rendering/volumetric/selector.js.map +1 -1
  22. package/build/src/rendering/volumetric/shaders-wgsl.js +197 -60
  23. package/build/src/rendering/volumetric/shaders-wgsl.js.map +1 -1
  24. package/build/src/rendering/volumetric/shaders.js +179 -5
  25. package/build/src/rendering/volumetric/shaders.js.map +1 -1
  26. package/build/src/rendering/volumetric/types.js +27 -1
  27. package/build/src/rendering/volumetric/types.js.map +1 -1
  28. package/build/src/rendering/volumetric-lighting.js.map +1 -1
  29. package/build/src/tools/scene.js +18 -5
  30. package/build/src/tools/scene.js.map +1 -1
  31. package/declaration/src/decorators/apply.d.ts +8 -4
  32. package/declaration/src/decorators/scene.d.ts +18 -9
  33. package/declaration/src/decorators/sound.d.ts +10 -1
  34. package/declaration/src/index.d.ts +1 -0
  35. package/declaration/src/loading/loader.d.ts +1 -1
  36. package/declaration/src/rendering/order.d.ts +31 -0
  37. package/declaration/src/rendering/volumetric/pipeline.d.ts +83 -1
  38. package/declaration/src/rendering/volumetric/selector.d.ts +6 -2
  39. package/declaration/src/rendering/volumetric/shaders-wgsl.d.ts +5 -1
  40. package/declaration/src/rendering/volumetric/shaders.d.ts +16 -2
  41. package/declaration/src/rendering/volumetric/types.d.ts +46 -1
  42. package/declaration/src/rendering/volumetric-lighting.d.ts +1 -1
  43. package/declaration/src/tools/scene.d.ts +2 -1
  44. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { maxVolumetricShadowSlots } from "./types";
2
2
  /**
3
- * WGSL version of the four passes of the volumetric lighting rendering pipeline, for WebGPU.
3
+ * WGSL version of the passes of the volumetric lighting rendering pipeline, for WebGPU.
4
4
  *
5
5
  * This is a hand written port of the GLSL in "shaders.ts" rather than a transpilation: Babylon.js can only
6
6
  * turn GLSL into WGSL by downloading twgsl from its CDN, which an offline Electron application can't rely on.
@@ -12,9 +12,12 @@ import { maxVolumetricShadowSlots } from "./types";
12
12
  * address the textures exactly like their GLSL counterparts.
13
13
  */
14
14
  /**
15
- * Unpacks a depth packed in the four channels of an 8 bits RGBA texture, the same way Babylon.js does.
15
+ * Defines how the linear depth is stored. @see the GLSL version.
16
16
  */
17
17
  const packingHelpers = /* wgsl */ `
18
+ // Stored scaled down by a power of two, which is exact. @see the GLSL version.
19
+ const volLinearDepthScale: f32 = 1.0 / 1024.0;
20
+
18
21
  fn volUnpack(color: vec4f) -> f32 {
19
22
  let bitShift = vec4f(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
20
23
  return dot(color, bitShift);
@@ -63,7 +66,7 @@ fn volReadLinearDepth(coordinates: vec2i) -> f32 {
63
66
  #ifdef VOL_LINEAR_DEPTH_PACKED
64
67
  return volUnpack(textureLoad(${texture}, coordinates, 0)) * uniforms.volCameraMinMaxZ.y;
65
68
  #else
66
- return textureLoad(${texture}, coordinates, 0).r;
69
+ return textureLoad(${texture}, coordinates, 0).r * (1.0 / volLinearDepthScale);
67
70
  #endif
68
71
  }
69
72
 
@@ -88,6 +91,9 @@ var depthSampler: texture_2d<f32>;
88
91
  uniform volCameraMinMaxZ: vec2f;
89
92
  uniform volDepthUnpack: vec2f;
90
93
 
94
+ // (1 when the pipeline has nothing to draw this frame, unused, unused, unused)
95
+ uniform volPassParams: vec4f;
96
+
91
97
  ${packingHelpers}
92
98
  ${depthMapHelpers}
93
99
 
@@ -103,13 +109,19 @@ fn volPack(depth: f32) -> vec4f {
103
109
 
104
110
  @fragment
105
111
  fn main(input: FragmentInputs) -> FragmentOutputs {
106
- let viewZ = volLinearDepth(volSampleDepth(input.vUV));
112
+ // Nothing reads the linear depth while the pipeline has nothing to draw.
113
+ if (uniforms.volPassParams.x > 0.5) {
114
+ fragmentOutputs.color = vec4f(0.0);
115
+ } else {
116
+ let viewZ = volLinearDepth(volSampleDepth(input.vUV));
107
117
 
108
- #ifdef VOL_LINEAR_DEPTH_PACKED
109
- fragmentOutputs.color = volPack(clamp(viewZ / uniforms.volCameraMinMaxZ.y, 0.0, 0.9999999));
110
- #else
111
- fragmentOutputs.color = vec4f(viewZ, 0.0, 0.0, 1.0);
112
- #endif
118
+ #ifdef VOL_LINEAR_DEPTH_PACKED
119
+ fragmentOutputs.color = volPack(clamp(viewZ / uniforms.volCameraMinMaxZ.y, 0.0, 0.9999999));
120
+ #else
121
+ // Bounded by the largest 16 bits float.
122
+ fragmentOutputs.color = vec4f(min(viewZ * volLinearDepthScale, 65504.0), 0.0, 0.0, 1.0);
123
+ #endif
124
+ }
113
125
  }
114
126
  `;
115
127
  }
@@ -345,6 +357,9 @@ uniform volCameraForward: vec3f;
345
357
  uniform volCameraMinMaxZ: vec2f;
346
358
  uniform volFrameIndex: f32;
347
359
 
360
+ // Offset of the current frame along the golden ratio sequence the samples walk with the temporal accumulation.
361
+ uniform volTemporalOffset: f32;
362
+
348
363
  uniform volFogInfos: vec4f;
349
364
  uniform volFogColor: vec3f;
350
365
  uniform volLinearFogEps: f32;
@@ -359,6 +374,9 @@ uniform volAmbient: vec3f;
359
374
  // (maximum distance, dithering strength, light extinction clamp, number of point and spot lights in the arrays)
360
375
  uniform volParams: vec4f;
361
376
 
377
+ // (1 when the pipeline has nothing to draw this frame, unused, unused, unused)
378
+ uniform volPassParams: vec4f;
379
+
362
380
  #if VOL_MAX_ARRAY_LIGHTS > 0
363
381
  uniform volLightData: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
364
382
  uniform volLightDiffuse: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
@@ -958,8 +976,9 @@ fn main(input: FragmentInputs) -> FragmentOutputs {
958
976
  var finalTransmittance = 1.0;
959
977
  var evaluatedLights = 0.0;
960
978
 
961
- // WGSL has no early return from the fragment entry point, the whole integration is guarded instead.
962
- if (tEnd > tStart) {
979
+ // WGSL has no early return from the fragment entry point, the whole integration is guarded instead. Nothing is
980
+ // drawn either while no light reaches the view and the medium neither glows nor attenuates anything.
981
+ if (tEnd > tStart && uniforms.volPassParams.x < 0.5) {
963
982
  // Offsets the samples inside their segments to trade the banding produced by a low sample count for noise.
964
983
  volNoise = 0.0;
965
984
  #if VOL_DITHER == 1
@@ -971,6 +990,11 @@ fn main(input: FragmentInputs) -> FragmentOutputs {
971
990
  #endif
972
991
  volNoise = volInterleavedGradientNoise(ditherPosition);
973
992
  #endif
993
+
994
+ #ifdef VOL_TEMPORAL_ACCUMULATION
995
+ // Each pixel walks the golden ratio sequence from the offset of its dithering pattern. @see the GLSL version.
996
+ volNoise = fract(volNoise + uniforms.volTemporalOffset);
997
+ #endif
974
998
  volJitter = volNoise * uniforms.volParams.y;
975
999
 
976
1000
  #ifdef VOL_SCREEN_SHADOWS
@@ -1033,59 +1057,162 @@ ${localSlotContributions.join("")}
1033
1057
  `;
1034
1058
  }
1035
1059
  /**
1036
- * The separable bilateral blur pass. @see buildVolumetricLightingBlurShader.
1060
+ * The temporal accumulation pass. @see buildVolumetricLightingTemporalShader.
1037
1061
  */
1038
- export function buildVolumetricLightingBlurShaderWGSL() {
1062
+ export function buildVolumetricLightingTemporalShaderWGSL() {
1039
1063
  return /* wgsl */ `
1040
1064
  varying vUV: vec2f;
1041
1065
 
1042
1066
  var textureSampler: texture_2d<f32>;
1067
+ var volHistorySamplerSampler: sampler;
1068
+ var volHistorySampler: texture_2d<f32>;
1043
1069
  var volLinearDepthSampler: texture_2d<f32>;
1044
1070
 
1045
1071
  uniform volCameraMinMaxZ: vec2f;
1046
1072
  uniform volDepthRatio: vec2f;
1047
- uniform volBlurDirection: vec2f;
1048
- uniform volBlurParams: vec2f;
1073
+ uniform volInverseViewProjection: mat4x4f;
1074
+ uniform volCameraPosition: vec3f;
1075
+ uniform volCameraForward: vec3f;
1076
+ uniform volPreviousViewProjection: mat4x4f;
1077
+
1078
+ // (weight of the current frame, width of the clipping in standard deviations, maximum distance of the march,
1079
+ // 1 when the history holds the previous frame, 2 when the previous frame had nothing to draw)
1080
+ uniform volTemporalParams: vec4f;
1081
+
1082
+ // (distance the camera moved since the previous frame, part of the medium along the view ray whose change the
1083
+ // delay of the history may lag behind)
1084
+ uniform volTemporalMotion: vec2f;
1049
1085
 
1050
1086
  ${packingHelpers}
1051
1087
  ${buildLinearDepthHelpers("volLinearDepthSampler")}
1052
1088
 
1053
1089
  @fragment
1054
1090
  fn main(input: FragmentInputs) -> FragmentOutputs {
1055
- // Every tap is an exact texel compared using the depth the raymarching used for it. @see the GLSL version.
1091
+ let texel = vec2i(fragmentInputs.position.xy);
1056
1092
  let size = vec2i(textureDimensions(textureSampler));
1057
- let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1058
- let center = vec2i(fragmentInputs.position.xy);
1059
- let direction = vec2i(uniforms.volBlurDirection);
1060
1093
 
1061
- let centerDepth = volReadLinearDepth(volScatterToDepthTexel(center, depthSize));
1062
- let inverseDepthThreshold = 1.0 / max(uniforms.volBlurParams.y * max(centerDepth, uniforms.volCameraMinMaxZ.x), 1e-4);
1063
- let sigma = max(uniforms.volBlurParams.x, 1e-4);
1064
- let inverseTwoSigma2 = 1.0 / (2.0 * sigma * sigma);
1094
+ // Bounded so a light next to the camera, which a half float can't hold, never turns the history infinite.
1095
+ let current = min(textureLoad(textureSampler, texel, 0), vec4f(65000.0));
1096
+ var result = current;
1065
1097
 
1066
- var result = textureLoad(textureSampler, center, 0);
1067
- var totalWeight = 1.0;
1098
+ // WGSL has no early return from the fragment entry point, the accumulation is guarded instead.
1099
+ if (uniforms.volTemporalParams.w > 0.5) {
1100
+ // The end of the marched part of the view ray is reprojected in the previous frame. @see the GLSL version.
1101
+ let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1102
+ let viewZ = volReadLinearDepth(volScatterToDepthTexel(texel, depthSize));
1068
1103
 
1069
- for (var i: i32 = 1; i <= VOL_BLUR_RADIUS; i++) {
1070
- let spatialWeight = exp(-f32(i * i) * inverseTwoSigma2);
1104
+ let farPoint = uniforms.volInverseViewProjection * vec4f(input.vUV * 2.0 - 1.0, 1.0, 1.0);
1105
+ let rayDir = normalize(farPoint.xyz / farPoint.w - uniforms.volCameraPosition);
1106
+ let t = min(viewZ / max(dot(rayDir, uniforms.volCameraForward), 1e-4), uniforms.volTemporalParams.z);
1071
1107
 
1072
- let positive = center + direction * i;
1073
- let negative = center - direction * i;
1108
+ let previousClip = uniforms.volPreviousViewProjection * vec4f(rayDir * t, 1.0);
1109
+ let previousUV = (previousClip.xy / previousClip.w) * 0.5 + 0.5;
1074
1110
 
1075
- if (positive.x < size.x && positive.y < size.y) {
1076
- let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(positive, depthSize)) - centerDepth) * inverseDepthThreshold);
1077
- result += textureLoad(textureSampler, positive, 0) * weight;
1078
- totalWeight += weight;
1079
- }
1111
+ // Clamped so a position reprojected off the screen still reads a valid texel: whether the history is used
1112
+ // at all is decided below. Nothing to draw the previous frame: no light at all, seen through the same medium.
1113
+ let sampled = textureSampleLevel(volHistorySampler, volHistorySamplerSampler, clamp(previousUV, vec2f(0.0), vec2f(1.0)), 0.0);
1114
+ let history = select(sampled, vec4f(0.0, 0.0, 0.0, current.a), uniforms.volTemporalParams.w > 1.5);
1080
1115
 
1081
- if (negative.x >= 0 && negative.y >= 0) {
1082
- let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(negative, depthSize)) - centerDepth) * inverseDepthThreshold);
1083
- result += textureLoad(textureSampler, negative, 0) * weight;
1084
- totalWeight += weight;
1116
+ let inside = previousClip.w > 0.0 && all(previousUV >= vec2f(0.0)) && all(previousUV <= vec2f(1.0));
1117
+
1118
+ // A history holding an infinity or a NaN would never recover from it.
1119
+ let finite = all(abs(history) < vec4f(1e20));
1120
+
1121
+ if (inside && finite) {
1122
+ // Variance clipping: the history is kept within what the current frame shows around the pixel.
1123
+ var m1 = vec4f(0.0);
1124
+ var m2 = vec4f(0.0);
1125
+
1126
+ for (var y: i32 = -1; y <= 1; y++) {
1127
+ for (var x: i32 = -1; x <= 1; x++) {
1128
+ let c = min(textureLoad(textureSampler, clamp(texel + vec2i(x, y), vec2i(0), size - 1), 0), vec4f(65000.0));
1129
+ m1 += c;
1130
+ m2 += c * c;
1131
+ }
1132
+ }
1133
+
1134
+ let mean = m1 * (1.0 / 9.0);
1135
+ let sigma = sqrt(max(m2 * (1.0 / 9.0) - mean * mean, vec4f(0.0)));
1136
+ let clipped = clamp(history, mean - uniforms.volTemporalParams.y * sigma, mean + uniforms.volTemporalParams.y * sigma);
1137
+
1138
+ // Moving the camera changes the medium along the view ray, the history is trusted less. @see the GLSL version.
1139
+ let motion = uniforms.volTemporalMotion.x / max(t, 1e-3);
1140
+ let factor = max(uniforms.volTemporalParams.x, motion / (motion + uniforms.volTemporalMotion.y));
1141
+
1142
+ // The transmittance only depends on the length of medium in front of the surface. @see the GLSL version.
1143
+ let transmittanceChange = abs(history.a - current.a) / max(max(history.a, current.a), 1e-3);
1144
+ let historyWeight = (1.0 - factor) * (1.0 - smoothstep(0.02, 0.15, transmittanceChange));
1145
+
1146
+ result = mix(current, clipped, historyWeight);
1085
1147
  }
1086
1148
  }
1087
1149
 
1088
- fragmentOutputs.color = result / totalWeight;
1150
+ fragmentOutputs.color = result;
1151
+ }
1152
+ `;
1153
+ }
1154
+ /**
1155
+ * The separable bilateral blur pass. @see buildVolumetricLightingBlurShader.
1156
+ */
1157
+ export function buildVolumetricLightingBlurShaderWGSL() {
1158
+ return /* wgsl */ `
1159
+ varying vUV: vec2f;
1160
+
1161
+ var textureSampler: texture_2d<f32>;
1162
+ var volLinearDepthSampler: texture_2d<f32>;
1163
+
1164
+ uniform volCameraMinMaxZ: vec2f;
1165
+ uniform volDepthRatio: vec2f;
1166
+ uniform volBlurDirection: vec2f;
1167
+ uniform volBlurParams: vec2f;
1168
+
1169
+ // (1 when the pipeline has nothing to draw this frame, unused, unused, unused)
1170
+ uniform volPassParams: vec4f;
1171
+
1172
+ ${packingHelpers}
1173
+ ${buildLinearDepthHelpers("volLinearDepthSampler")}
1174
+
1175
+ @fragment
1176
+ fn main(input: FragmentInputs) -> FragmentOutputs {
1177
+ // Nothing to draw this frame: the composition doesn't read the scattering buffer.
1178
+ if (uniforms.volPassParams.x > 0.5) {
1179
+ fragmentOutputs.color = vec4f(0.0, 0.0, 0.0, 1.0);
1180
+ } else {
1181
+ // Every tap is an exact texel compared using the depth the raymarching used for it. @see the GLSL version.
1182
+ let size = vec2i(textureDimensions(textureSampler));
1183
+ let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1184
+ let center = vec2i(fragmentInputs.position.xy);
1185
+ let direction = vec2i(uniforms.volBlurDirection);
1186
+
1187
+ let centerDepth = volReadLinearDepth(volScatterToDepthTexel(center, depthSize));
1188
+ let inverseDepthThreshold = 1.0 / max(uniforms.volBlurParams.y * max(centerDepth, uniforms.volCameraMinMaxZ.x), 1e-4);
1189
+ let sigma = max(uniforms.volBlurParams.x, 1e-4);
1190
+ let inverseTwoSigma2 = 1.0 / (2.0 * sigma * sigma);
1191
+
1192
+ var result = textureLoad(textureSampler, center, 0);
1193
+ var totalWeight = 1.0;
1194
+
1195
+ for (var i: i32 = 1; i <= VOL_BLUR_RADIUS; i++) {
1196
+ let spatialWeight = exp(-f32(i * i) * inverseTwoSigma2);
1197
+
1198
+ let positive = center + direction * i;
1199
+ let negative = center - direction * i;
1200
+
1201
+ if (positive.x < size.x && positive.y < size.y) {
1202
+ let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(positive, depthSize)) - centerDepth) * inverseDepthThreshold);
1203
+ result += textureLoad(textureSampler, positive, 0) * weight;
1204
+ totalWeight += weight;
1205
+ }
1206
+
1207
+ if (negative.x >= 0 && negative.y >= 0) {
1208
+ let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(negative, depthSize)) - centerDepth) * inverseDepthThreshold);
1209
+ result += textureLoad(textureSampler, negative, 0) * weight;
1210
+ totalWeight += weight;
1211
+ }
1212
+ }
1213
+
1214
+ fragmentOutputs.color = result / totalWeight;
1215
+ }
1089
1216
  }
1090
1217
  `;
1091
1218
  }
@@ -1105,6 +1232,9 @@ uniform volCameraMinMaxZ: vec2f;
1105
1232
  uniform volDepthRatio: vec2f;
1106
1233
  uniform volComposeParams: vec4f;
1107
1234
 
1235
+ // (1 when the pipeline has nothing to draw this frame, unused, unused, unused)
1236
+ uniform volPassParams: vec4f;
1237
+
1108
1238
  ${packingHelpers}
1109
1239
  ${buildLinearDepthHelpers("volLinearDepthSampler")}
1110
1240
 
@@ -1168,43 +1298,50 @@ fn volUpsample(uv0: vec2f, centerDepth: f32, depthSize: vec2i) -> vec4f {
1168
1298
 
1169
1299
  @fragment
1170
1300
  fn main(input: FragmentInputs) -> FragmentOutputs {
1171
- // The linear depth has the full resolution of the canvas. @see the GLSL version.
1172
- let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1173
- let centerDepth = volReadLinearDepth(min(vec2i(input.vUV * vec2f(depthSize)), depthSize - 1));
1301
+ // Nothing to draw this frame: the color of the scene passes through. @see the GLSL version.
1302
+ if (uniforms.volPassParams.x > 0.5) {
1303
+ let sceneColor = textureSampleLevel(volSceneSampler, volSceneSamplerSampler, input.vUV, 0.0).rgb;
1304
+ fragmentOutputs.color = vec4f(sceneColor + (volBayer8(fragmentInputs.position.xy) - 0.5) * uniforms.volComposeParams.w, 1.0);
1305
+ } else {
1306
+ // The linear depth has the full resolution of the canvas. @see the GLSL version.
1307
+ let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1308
+ let centerDepth = volReadLinearDepth(min(vec2i(input.vUV * vec2f(depthSize)), depthSize - 1));
1174
1309
 
1175
- var volumetric = volUpsample(input.vUV, centerDepth, depthSize);
1310
+ var volumetric = volUpsample(input.vUV, centerDepth, depthSize);
1176
1311
 
1177
- #ifdef VOL_LDR_ENCODE
1178
- volumetric = vec4f(volumetric.rgb / max(vec3f(1e-4), 1.0 - volumetric.rgb), volumetric.a);
1179
- #endif
1312
+ #ifdef VOL_LDR_ENCODE
1313
+ volumetric = vec4f(volumetric.rgb / max(vec3f(1e-4), 1.0 - volumetric.rgb), volumetric.a);
1314
+ #endif
1180
1315
 
1181
- // WGSL has no early return from the fragment entry point, so the debug outputs are branches instead.
1182
- #if VOL_DEBUG == 1 || VOL_DEBUG == 3
1183
- fragmentOutputs.color = vec4f(volumetric.rgb * uniforms.volComposeParams.x, 1.0);
1184
- #elif VOL_DEBUG == 2
1185
- fragmentOutputs.color = vec4f(vec3f(volumetric.a), 1.0);
1186
- #else
1187
- var sceneColor = textureSampleLevel(volSceneSampler, volSceneSamplerSampler, input.vUV, 0.0).rgb;
1316
+ // WGSL has no early return from the fragment entry point, so the debug outputs are branches instead.
1317
+ #if VOL_DEBUG == 1 || VOL_DEBUG == 3
1318
+ fragmentOutputs.color = vec4f(volumetric.rgb * uniforms.volComposeParams.x, 1.0);
1319
+ #elif VOL_DEBUG == 2
1320
+ fragmentOutputs.color = vec4f(vec3f(volumetric.a), 1.0);
1321
+ #else
1322
+ var sceneColor = textureSampleLevel(volSceneSampler, volSceneSamplerSampler, input.vUV, 0.0).rgb;
1188
1323
 
1189
- sceneColor *= mix(1.0, volumetric.a, uniforms.volComposeParams.y);
1324
+ sceneColor *= mix(1.0, volumetric.a, uniforms.volComposeParams.y);
1190
1325
 
1191
- var result = sceneColor + volumetric.rgb * uniforms.volComposeParams.x;
1326
+ var result = sceneColor + volumetric.rgb * uniforms.volComposeParams.x;
1192
1327
 
1193
- // Breaks up the banding an 8 bits output would otherwise show on the smooth gradients of the shafts.
1194
- result += (volBayer8(fragmentInputs.position.xy) - 0.5) * uniforms.volComposeParams.w;
1328
+ // Breaks up the banding an 8 bits output would otherwise show on the smooth gradients of the shafts.
1329
+ result += (volBayer8(fragmentInputs.position.xy) - 0.5) * uniforms.volComposeParams.w;
1195
1330
 
1196
- fragmentOutputs.color = vec4f(result, 1.0);
1197
- #endif
1331
+ fragmentOutputs.color = vec4f(result, 1.0);
1332
+ #endif
1333
+ }
1198
1334
  }
1199
1335
  `;
1200
1336
  }
1201
1337
  /**
1202
- * Returns the four WGSL sources of the pipeline, keyed by the name they are registered under.
1338
+ * Returns the WGSL sources of the passes of the pipeline, keyed by the name they are registered under.
1203
1339
  */
1204
1340
  export function getVolumetricLightingShadersWGSL() {
1205
1341
  return {
1206
1342
  linearDepth: buildVolumetricLightingLinearDepthShaderWGSL(),
1207
1343
  scattering: buildVolumetricLightingScatteringShaderWGSL(maxVolumetricShadowSlots),
1344
+ temporal: buildVolumetricLightingTemporalShaderWGSL(),
1208
1345
  blur: buildVolumetricLightingBlurShaderWGSL(),
1209
1346
  compose: buildVolumetricLightingComposeShaderWGSL(),
1210
1347
  };
@@ -1 +1 @@
1
- {"version":3,"file":"shaders-wgsl.js","sourceRoot":"","sources":["../../../../src/rendering/volumetric/shaders-wgsl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shaders-wgsl.js","sourceRoot":"","sources":["../../../../src/rendering/volumetric/shaders-wgsl.ts"],"names":[],"mappings":"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"}