@zephyr3d/scene 0.9.18 → 0.9.20

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 (124) hide show
  1. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  2. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  3. package/dist/app/scriptregistry.js +124 -6
  4. package/dist/app/scriptregistry.js.map +1 -1
  5. package/dist/asset/assetmanager.js +1 -0
  6. package/dist/asset/assetmanager.js.map +1 -1
  7. package/dist/camera/camera.js +240 -201
  8. package/dist/camera/camera.js.map +1 -1
  9. package/dist/index.d.ts +458 -9
  10. package/dist/index.js +4 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/material/meshmaterial.js +2 -2
  13. package/dist/material/meshmaterial.js.map +1 -1
  14. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +11 -5
  15. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  16. package/dist/material/mixins/lit.js +10 -0
  17. package/dist/material/mixins/lit.js.map +1 -1
  18. package/dist/material/shader/helper.js +138 -10
  19. package/dist/material/shader/helper.js.map +1 -1
  20. package/dist/material/skin.js +4 -6
  21. package/dist/material/skin.js.map +1 -1
  22. package/dist/material/water.js +1 -1
  23. package/dist/material/water.js.map +1 -1
  24. package/dist/posteffect/bloom.js +177 -29
  25. package/dist/posteffect/bloom.js.map +1 -1
  26. package/dist/posteffect/compositor.js +111 -204
  27. package/dist/posteffect/compositor.js.map +1 -1
  28. package/dist/posteffect/motionblur.js +3 -0
  29. package/dist/posteffect/motionblur.js.map +1 -1
  30. package/dist/posteffect/posteffect.js +79 -0
  31. package/dist/posteffect/posteffect.js.map +1 -1
  32. package/dist/posteffect/skinsss.js.map +1 -1
  33. package/dist/posteffect/ssr.js +238 -7
  34. package/dist/posteffect/ssr.js.map +1 -1
  35. package/dist/posteffect/sss.js +16 -15
  36. package/dist/posteffect/sss.js.map +1 -1
  37. package/dist/posteffect/taa.js +121 -19
  38. package/dist/posteffect/taa.js.map +1 -1
  39. package/dist/posteffect/tonemap.js +1 -1
  40. package/dist/posteffect/tonemap.js.map +1 -1
  41. package/dist/render/abuffer_oit.js +7 -1
  42. package/dist/render/abuffer_oit.js.map +1 -1
  43. package/dist/render/cluster_light.js +52 -8
  44. package/dist/render/cluster_light.js.map +1 -1
  45. package/dist/render/dualdepthpeeling_oit.js +331 -0
  46. package/dist/render/dualdepthpeeling_oit.js.map +1 -0
  47. package/dist/render/envlight.js +6 -3
  48. package/dist/render/envlight.js.map +1 -1
  49. package/dist/render/hzb.js +11 -4
  50. package/dist/render/hzb.js.map +1 -1
  51. package/dist/render/lightpass.js +21 -12
  52. package/dist/render/lightpass.js.map +1 -1
  53. package/dist/render/renderer.js +7 -3
  54. package/dist/render/renderer.js.map +1 -1
  55. package/dist/render/rendergraph/blackboard.js +79 -0
  56. package/dist/render/rendergraph/blackboard.js.map +1 -0
  57. package/dist/render/rendergraph/device_pool_allocator.js +10 -1
  58. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  59. package/dist/render/rendergraph/executor.js +41 -11
  60. package/dist/render/rendergraph/executor.js.map +1 -1
  61. package/dist/render/rendergraph/forward_plus_builder.js +551 -201
  62. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  63. package/dist/render/rendergraph/rendergraph.js +29 -0
  64. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  65. package/dist/render/rendergraph/types.js.map +1 -1
  66. package/dist/render/renderpass.js +12 -2
  67. package/dist/render/renderpass.js.map +1 -1
  68. package/dist/render/shadow_mask_pass.js +297 -0
  69. package/dist/render/shadow_mask_pass.js.map +1 -0
  70. package/dist/render/weightedblended_oit.js +5 -0
  71. package/dist/render/weightedblended_oit.js.map +1 -1
  72. package/dist/scene/basesprite.js +1 -0
  73. package/dist/scene/basesprite.js.map +1 -1
  74. package/dist/scene/batchgroup.js +1 -0
  75. package/dist/scene/batchgroup.js.map +1 -1
  76. package/dist/scene/environment.js +1 -0
  77. package/dist/scene/environment.js.map +1 -1
  78. package/dist/scene/msdftext.js +1 -0
  79. package/dist/scene/msdftext.js.map +1 -1
  80. package/dist/scene/msdftextsprite.js +1 -0
  81. package/dist/scene/msdftextsprite.js.map +1 -1
  82. package/dist/scene/particlesys.js +1 -0
  83. package/dist/scene/particlesys.js.map +1 -1
  84. package/dist/scene/scene.js +1 -0
  85. package/dist/scene/scene.js.map +1 -1
  86. package/dist/scene/terrain-cm/grass.js +1 -0
  87. package/dist/scene/terrain-cm/grass.js.map +1 -1
  88. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  89. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  90. package/dist/scene/water.js +1 -0
  91. package/dist/scene/water.js.map +1 -1
  92. package/dist/shaders/ssr.js +52 -21
  93. package/dist/shaders/ssr.js.map +1 -1
  94. package/dist/utility/misc.js +10 -1
  95. package/dist/utility/misc.js.map +1 -1
  96. package/dist/utility/serialization/manager.js +1 -0
  97. package/dist/utility/serialization/manager.js.map +1 -1
  98. package/dist/utility/serialization/scene/animation.js +1 -0
  99. package/dist/utility/serialization/scene/animation.js.map +1 -1
  100. package/dist/utility/serialization/scene/batch.js +1 -0
  101. package/dist/utility/serialization/scene/batch.js.map +1 -1
  102. package/dist/utility/serialization/scene/camera.js +35 -2
  103. package/dist/utility/serialization/scene/camera.js.map +1 -1
  104. package/dist/utility/serialization/scene/light.js +1 -0
  105. package/dist/utility/serialization/scene/light.js.map +1 -1
  106. package/dist/utility/serialization/scene/mesh.js +1 -0
  107. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  108. package/dist/utility/serialization/scene/node.js +1 -0
  109. package/dist/utility/serialization/scene/node.js.map +1 -1
  110. package/dist/utility/serialization/scene/particle.js +1 -0
  111. package/dist/utility/serialization/scene/particle.js.map +1 -1
  112. package/dist/utility/serialization/scene/primitive.js +1 -0
  113. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  114. package/dist/utility/serialization/scene/sprite.js +1 -0
  115. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  116. package/dist/utility/serialization/scene/terrain.js +1 -0
  117. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  118. package/dist/utility/serialization/scene/text.js +1 -0
  119. package/dist/utility/serialization/scene/text.js.map +1 -1
  120. package/dist/utility/serialization/scene/water.js +1 -0
  121. package/dist/utility/serialization/scene/water.js.map +1 -1
  122. package/dist/values.js +11 -1
  123. package/dist/values.js.map +1 -1
  124. package/package.json +2 -2
@@ -0,0 +1,331 @@
1
+ import { Disposable, Vector4 } from '@zephyr3d/base';
2
+ import { drawFullscreenQuad } from './fullscreenquad.js';
3
+ import { tryGetApp } from '../app/api.js';
4
+
5
+ const DEPTH_FORMAT = 'rg32f';
6
+ const ACCUM_FORMAT = 'rgba16f';
7
+ const COLOR_ATTACHMENT_BYTES_PER_SAMPLE = 4 + 8 + 8;
8
+ /**
9
+ * Dual depth peeling OIT renderer.
10
+ *
11
+ * @remarks
12
+ * This implementation follows the official dual depth peeling pass structure:
13
+ * an initialization pass writes the nearest/farthest transparent depth pair, then
14
+ * each peel pass ping-pongs the depth pair while accumulating front and back colors.
15
+ *
16
+ * It requires MRT, per-target blending, min/max blend equations and blendable
17
+ * floating-point color targets. If those capabilities are missing, supportDevice()
18
+ * returns false and the transparent pass falls back to sorted alpha blending.
19
+ *
20
+ * @public
21
+ */ class DualDepthPeelingOIT extends Disposable {
22
+ /** Type name of DualDepthPeelingOIT */ static type = 'ddp';
23
+ static DEPTH_CLEAR = new Vector4(-1, -1, -1, -1);
24
+ static FRONT_CLEAR = new Vector4(0, 0, 0, 1);
25
+ static BACK_CLEAR = new Vector4(0, 0, 0, 0);
26
+ static _compositeProgram = null;
27
+ static _compositeBindGroup = null;
28
+ static _compositeRenderStates = null;
29
+ _numPeels;
30
+ _currentPass;
31
+ _hash;
32
+ _depthTargets;
33
+ _frontTarget;
34
+ _backTarget;
35
+ _framebuffers;
36
+ _device;
37
+ /**
38
+ * Creates an instance of DualDepthPeelingOIT.
39
+ *
40
+ * @param numPeels - Number of peel iterations after the initialization pass.
41
+ */ constructor(numPeels = 8){
42
+ super();
43
+ this._numPeels = Math.max(1, Math.floor(numPeels || 0));
44
+ this._currentPass = 0;
45
+ this._hash = DualDepthPeelingOIT.type;
46
+ this._depthTargets = [
47
+ null,
48
+ null
49
+ ];
50
+ this._frontTarget = null;
51
+ this._backTarget = null;
52
+ this._framebuffers = [
53
+ null,
54
+ null
55
+ ];
56
+ this._device = null;
57
+ }
58
+ /** Number of front/back peel iterations after the initialization pass. */ get numPeels() {
59
+ return this._numPeels;
60
+ }
61
+ set numPeels(val) {
62
+ this._numPeels = Math.max(1, Math.floor(val || 0));
63
+ }
64
+ /**
65
+ * Checks whether dual depth peeling can run with a capability snapshot.
66
+ *
67
+ * @param deviceType - The device type.
68
+ * @param caps - The device capabilities.
69
+ * @returns True if dual depth peeling is supported.
70
+ */ static supportDeviceCaps(deviceType, caps) {
71
+ const framebufferCaps = caps.framebufferCaps;
72
+ const textureCaps = caps.textureCaps;
73
+ const shaderCaps = caps.shaderCaps;
74
+ const miscCaps = caps.miscCaps;
75
+ const webgl2OrBetter = deviceType !== 'webgl' || shaderCaps.maxUniformBufferSize > 0;
76
+ return webgl2OrBetter && framebufferCaps.maxDrawBuffers >= 3 && framebufferCaps.supportPerTargetBlending && framebufferCaps.maxColorAttachmentBytesPerSample >= COLOR_ATTACHMENT_BYTES_PER_SAMPLE && miscCaps.supportBlendMinMax && textureCaps.supportHalfFloatColorBuffer && textureCaps.supportFloatColorBuffer && textureCaps.supportFloatBlending;
77
+ }
78
+ /**
79
+ * {@inheritDoc OIT.getType}
80
+ */ getType() {
81
+ return DualDepthPeelingOIT.type;
82
+ }
83
+ /**
84
+ * {@inheritDoc OIT.supportDevice}
85
+ */ supportDevice(deviceType) {
86
+ const device = tryGetApp()?.device;
87
+ return !!device && device.type === deviceType && DualDepthPeelingOIT.supportDeviceCaps(deviceType, device.getDeviceCaps());
88
+ }
89
+ /**
90
+ * {@inheritDoc OIT.wantsPremultipliedAlpha}
91
+ */ wantsPremultipliedAlpha() {
92
+ return true;
93
+ }
94
+ /**
95
+ * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}
96
+ */ wantsAdditiveLightPassAlpha() {
97
+ return true;
98
+ }
99
+ /**
100
+ * {@inheritDoc OIT.begin}
101
+ */ begin(ctx) {
102
+ this.releaseFramebuffers();
103
+ if (!ctx.depthTexture) {
104
+ return 0;
105
+ }
106
+ this._device = ctx.device;
107
+ this.createFramebuffers(ctx);
108
+ return this._numPeels + 1;
109
+ }
110
+ /**
111
+ * {@inheritDoc OIT.end}
112
+ */ end(ctx) {
113
+ try {
114
+ if (this._frontTarget && this._backTarget) {
115
+ this.composite(ctx, ctx.device, this._frontTarget, this._backTarget);
116
+ }
117
+ } finally{
118
+ this.releaseFramebuffers();
119
+ this._hash = DualDepthPeelingOIT.type;
120
+ }
121
+ }
122
+ /**
123
+ * {@inheritDoc OIT.beginPass}
124
+ */ beginPass(ctx, pass) {
125
+ this._currentPass = pass;
126
+ const targetIndex = pass & 1;
127
+ const currentDepthTarget = this._depthTargets[targetIndex];
128
+ const previousDepthTarget = this._depthTargets[targetIndex ^ 1];
129
+ const framebuffer = this._framebuffers[targetIndex];
130
+ if (!currentDepthTarget || !framebuffer || pass > 0 && !previousDepthTarget) {
131
+ return false;
132
+ }
133
+ this._hash = pass === 0 ? `${this.getType()}#init#${currentDepthTarget.uid}` : `${this.getType()}#peel#${previousDepthTarget.uid}`;
134
+ ctx.device.pushDeviceStates();
135
+ ctx.device.setFramebuffer(framebuffer);
136
+ ctx.device.clearFrameBuffer(pass === 0 ? [
137
+ DualDepthPeelingOIT.DEPTH_CLEAR,
138
+ DualDepthPeelingOIT.FRONT_CLEAR,
139
+ DualDepthPeelingOIT.BACK_CLEAR
140
+ ] : [
141
+ DualDepthPeelingOIT.DEPTH_CLEAR,
142
+ null,
143
+ null
144
+ ], null, null);
145
+ return true;
146
+ }
147
+ /**
148
+ * {@inheritDoc OIT.endPass}
149
+ */ endPass(ctx, _pass) {
150
+ ctx.device.popDeviceStates();
151
+ }
152
+ /**
153
+ * {@inheritDoc OIT.setupFragmentOutput}
154
+ */ setupFragmentOutput(scope) {
155
+ const pb = scope.$builder;
156
+ scope.$outputs.Z_DDP_depth = pb.vec2();
157
+ scope.$outputs.Z_DDP_frontColor = pb.vec4();
158
+ scope.$outputs.Z_DDP_backColor = pb.vec4();
159
+ if (this._currentPass > 0) {
160
+ scope.Z_DDP_depthTexture = pb.tex2D().uniform(2).noSampler();
161
+ }
162
+ }
163
+ /**
164
+ * {@inheritDoc OIT.outputFragmentColor}
165
+ */ outputFragmentColor(scope, color, ctx) {
166
+ const pb = scope.$builder;
167
+ scope.$outputs.Z_DDP_depth = pb.vec2(-1, -1);
168
+ scope.$outputs.Z_DDP_frontColor = pb.vec4(0, 0, 0, 0);
169
+ scope.$outputs.Z_DDP_backColor = pb.vec4(0, 0, 0, 0);
170
+ if (this._currentPass === 0) {
171
+ scope.$outputs.Z_DDP_depth = pb.vec2(pb.neg(scope.$builtins.fragCoord.z), scope.$builtins.fragCoord.z);
172
+ } else {
173
+ scope.$l.Z_DDP_prevDepth = pb.textureLoad(scope.Z_DDP_depthTexture, pb.ivec2(scope.$builtins.fragCoord.xy), 0).xy;
174
+ scope.$l.Z_DDP_frontDepth = pb.neg(scope.Z_DDP_prevDepth.x);
175
+ scope.$l.Z_DDP_backDepth = scope.Z_DDP_prevDepth.y;
176
+ scope.$l.Z_DDP_curDepth = scope.$builtins.fragCoord.z;
177
+ scope.$l.Z_DDP_outputColor = pb.vec4(color.rgb, ctx.lightBlending ? pb.float(0) : color.a);
178
+ scope.$if(pb.or(pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth), pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)), function() {
179
+ pb.discard();
180
+ }).$elseif(pb.and(pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth), pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)), function() {
181
+ this.$outputs.Z_DDP_depth = pb.vec2(pb.neg(this.$builtins.fragCoord.z), this.$builtins.fragCoord.z);
182
+ }).$elseif(pb.and(pb.lessThan(scope.Z_DDP_curDepth, pb.add(scope.Z_DDP_frontDepth, 0.000001)), pb.greaterThan(scope.Z_DDP_curDepth, pb.sub(scope.Z_DDP_frontDepth, 0.000001))), function() {
183
+ this.$outputs.Z_DDP_frontColor = this.Z_DDP_outputColor;
184
+ }).$else(function() {
185
+ this.$outputs.Z_DDP_backColor = this.Z_DDP_outputColor;
186
+ });
187
+ }
188
+ return true;
189
+ }
190
+ /**
191
+ * {@inheritDoc OIT.applyUniforms}
192
+ */ applyUniforms(_ctx, bindGroup) {
193
+ if (this._currentPass > 0) {
194
+ bindGroup.setTexture('Z_DDP_depthTexture', this._depthTargets[this._currentPass & 1 ^ 1]);
195
+ }
196
+ }
197
+ /**
198
+ * {@inheritDoc OIT.calculateHash}
199
+ */ calculateHash() {
200
+ return this._hash;
201
+ }
202
+ /**
203
+ * {@inheritDoc OIT.setRenderStates}
204
+ */ setRenderStates(rs) {
205
+ rs.useBlendingState().enable(false).enableAlphaToCoverage(false);
206
+ rs.useDepthState().enableTest(true).enableWrite(false);
207
+ rs.useTargetBlendingState(0).enable(true).enableAlphaToCoverage(false).setBlendEquation('max', 'max').setBlendFunc('one', 'one');
208
+ rs.useTargetBlendingState(1).enable(true).enableAlphaToCoverage(false).setBlendEquation('add', 'add').setBlendFuncRGB('dst-alpha', 'one').setBlendFuncAlpha('zero', 'inv-src-alpha');
209
+ rs.useTargetBlendingState(2).enable(true).enableAlphaToCoverage(false).setBlendEquation('add', 'add').setBlendFuncRGB('one', 'inv-src-alpha').setBlendFuncAlpha('one', 'inv-src-alpha');
210
+ }
211
+ /** @internal */ createFramebuffers(ctx) {
212
+ const device = ctx.device;
213
+ const width = ctx.depthTexture.width;
214
+ const height = ctx.depthTexture.height;
215
+ const depthTarget0 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);
216
+ const depthTarget1 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);
217
+ const frontTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);
218
+ const backTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);
219
+ const framebuffer0 = device.pool.createTemporalFramebuffer(false, [
220
+ depthTarget0,
221
+ frontTarget,
222
+ backTarget
223
+ ], ctx.depthTexture);
224
+ const framebuffer1 = device.pool.createTemporalFramebuffer(false, [
225
+ depthTarget1,
226
+ frontTarget,
227
+ backTarget
228
+ ], ctx.depthTexture);
229
+ device.pool.releaseTexture(depthTarget0);
230
+ device.pool.releaseTexture(depthTarget1);
231
+ device.pool.releaseTexture(frontTarget);
232
+ device.pool.releaseTexture(backTarget);
233
+ this._depthTargets = [
234
+ depthTarget0,
235
+ depthTarget1
236
+ ];
237
+ this._frontTarget = frontTarget;
238
+ this._backTarget = backTarget;
239
+ this._framebuffers = [
240
+ framebuffer0,
241
+ framebuffer1
242
+ ];
243
+ }
244
+ /** @internal */ composite(ctx, device, frontTarget, backTarget) {
245
+ const currentFramebuffer = device.getFramebuffer();
246
+ const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;
247
+ const singleColorFramebuffer = currentFramebuffer && currentFramebuffer.getColorAttachments().length > 1 && colorAttachment ? device.pool.fetchTemporalFramebuffer(false, 0, 0, colorAttachment, currentFramebuffer.getDepthAttachment(), false) : null;
248
+ if (singleColorFramebuffer) {
249
+ const viewport = device.getViewport();
250
+ const scissor = device.getScissor();
251
+ device.pushDeviceStates();
252
+ device.setFramebuffer(singleColorFramebuffer);
253
+ device.setViewport(viewport);
254
+ device.setScissor(scissor);
255
+ }
256
+ try {
257
+ device.setProgram(DualDepthPeelingOIT.getCompositeProgram(device));
258
+ DualDepthPeelingOIT._compositeBindGroup.setTexture('frontTex', frontTarget);
259
+ DualDepthPeelingOIT._compositeBindGroup.setTexture('backTex', backTarget);
260
+ device.setBindGroup(0, DualDepthPeelingOIT._compositeBindGroup);
261
+ drawFullscreenQuad(DualDepthPeelingOIT._compositeRenderStates);
262
+ } finally{
263
+ if (singleColorFramebuffer) {
264
+ device.popDeviceStates();
265
+ device.pool.releaseFrameBuffer(singleColorFramebuffer);
266
+ }
267
+ }
268
+ }
269
+ /** @internal */ releaseFramebuffers() {
270
+ if (this._device) {
271
+ if (this._framebuffers[0]) {
272
+ this._device.pool.releaseFrameBuffer(this._framebuffers[0]);
273
+ }
274
+ if (this._framebuffers[1]) {
275
+ this._device.pool.releaseFrameBuffer(this._framebuffers[1]);
276
+ }
277
+ }
278
+ this._depthTargets = [
279
+ null,
280
+ null
281
+ ];
282
+ this._frontTarget = null;
283
+ this._backTarget = null;
284
+ this._framebuffers = [
285
+ null,
286
+ null
287
+ ];
288
+ this._device = null;
289
+ }
290
+ /** @internal */ static getCompositeProgram(device) {
291
+ if (!this._compositeProgram) {
292
+ this._compositeProgram = device.buildRenderProgram({
293
+ vertex (pb) {
294
+ this.$inputs.pos = pb.vec2().attrib('position');
295
+ this.$outputs.uv = pb.vec2();
296
+ pb.main(function() {
297
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
298
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
299
+ if (device.type === 'webgpu') {
300
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
301
+ }
302
+ });
303
+ },
304
+ fragment (pb) {
305
+ this.$outputs.outColor = pb.vec4();
306
+ this.frontTex = pb.tex2D().uniform(0);
307
+ this.backTex = pb.tex2D().uniform(0);
308
+ pb.main(function() {
309
+ this.$l.frontColor = pb.textureSample(this.frontTex, this.$inputs.uv);
310
+ this.$l.backColor = pb.textureSample(this.backTex, this.$inputs.uv);
311
+ this.$l.remainingAlpha = pb.clamp(pb.mul(this.frontColor.a, pb.sub(1, this.backColor.a)), 0, 1);
312
+ this.$outputs.outColor = pb.vec4(pb.add(this.frontColor.rgb, pb.mul(this.frontColor.a, this.backColor.rgb)), this.remainingAlpha);
313
+ });
314
+ }
315
+ });
316
+ this._compositeProgram.name = '@DualDepthPeelingOIT_Composite';
317
+ this._compositeBindGroup = device.createBindGroup(this._compositeProgram.bindGroupLayouts[0]);
318
+ this._compositeRenderStates = device.createRenderStateSet();
319
+ this._compositeRenderStates.useBlendingState().enable(true).setBlendFuncRGB('one', 'src-alpha').setBlendFuncAlpha('zero', 'one');
320
+ this._compositeRenderStates.useDepthState().enableTest(false).enableWrite(false);
321
+ }
322
+ return this._compositeProgram;
323
+ }
324
+ onDispose() {
325
+ super.onDispose();
326
+ this.releaseFramebuffers();
327
+ }
328
+ }
329
+
330
+ export { DualDepthPeelingOIT };
331
+ //# sourceMappingURL=dualdepthpeeling_oit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dualdepthpeeling_oit.js","sources":["../../src/render/dualdepthpeeling_oit.ts"],"sourcesContent":["import type {\r\n AbstractDevice,\r\n BindGroup,\r\n DeviceCaps,\r\n FrameBuffer,\r\n GPUProgram,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n RenderStateSet,\r\n Texture2D,\r\n TextureFormat\r\n} from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { Disposable, Vector4 } from '@zephyr3d/base';\r\nimport type { OIT } from './oit';\r\nimport type { DrawContext } from './drawable';\r\nimport { drawFullscreenQuad } from './fullscreenquad';\r\nimport { tryGetApp } from '../app/api';\r\n\r\nconst DEPTH_FORMAT: TextureFormat = 'rg32f';\r\nconst ACCUM_FORMAT: TextureFormat = 'rgba16f';\r\nconst COLOR_ATTACHMENT_BYTES_PER_SAMPLE = 4 + 8 + 8;\r\n\r\n/**\r\n * Dual depth peeling OIT renderer.\r\n *\r\n * @remarks\r\n * This implementation follows the official dual depth peeling pass structure:\r\n * an initialization pass writes the nearest/farthest transparent depth pair, then\r\n * each peel pass ping-pongs the depth pair while accumulating front and back colors.\r\n *\r\n * It requires MRT, per-target blending, min/max blend equations and blendable\r\n * floating-point color targets. If those capabilities are missing, supportDevice()\r\n * returns false and the transparent pass falls back to sorted alpha blending.\r\n *\r\n * @public\r\n */\r\nexport class DualDepthPeelingOIT extends Disposable implements OIT {\r\n /** Type name of DualDepthPeelingOIT */\r\n public static readonly type = 'ddp';\r\n private static readonly DEPTH_CLEAR = new Vector4(-1, -1, -1, -1);\r\n private static readonly FRONT_CLEAR = new Vector4(0, 0, 0, 1);\r\n private static readonly BACK_CLEAR = new Vector4(0, 0, 0, 0);\r\n private static _compositeProgram: Nullable<GPUProgram> = null;\r\n private static _compositeBindGroup: Nullable<BindGroup> = null;\r\n private static _compositeRenderStates: Nullable<RenderStateSet> = null;\r\n private _numPeels: number;\r\n private _currentPass: number;\r\n private _hash: string;\r\n private _depthTargets: [Nullable<Texture2D>, Nullable<Texture2D>];\r\n private _frontTarget: Nullable<Texture2D>;\r\n private _backTarget: Nullable<Texture2D>;\r\n private _framebuffers: [Nullable<FrameBuffer>, Nullable<FrameBuffer>];\r\n private _device: Nullable<AbstractDevice>;\r\n\r\n /**\r\n * Creates an instance of DualDepthPeelingOIT.\r\n *\r\n * @param numPeels - Number of peel iterations after the initialization pass.\r\n */\r\n constructor(numPeels = 8) {\r\n super();\r\n this._numPeels = Math.max(1, Math.floor(numPeels || 0));\r\n this._currentPass = 0;\r\n this._hash = DualDepthPeelingOIT.type;\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** Number of front/back peel iterations after the initialization pass. */\r\n get numPeels() {\r\n return this._numPeels;\r\n }\r\n set numPeels(val: number) {\r\n this._numPeels = Math.max(1, Math.floor(val || 0));\r\n }\r\n\r\n /**\r\n * Checks whether dual depth peeling can run with a capability snapshot.\r\n *\r\n * @param deviceType - The device type.\r\n * @param caps - The device capabilities.\r\n * @returns True if dual depth peeling is supported.\r\n */\r\n static supportDeviceCaps(deviceType: string, caps: DeviceCaps) {\r\n const framebufferCaps = caps.framebufferCaps;\r\n const textureCaps = caps.textureCaps;\r\n const shaderCaps = caps.shaderCaps;\r\n const miscCaps = caps.miscCaps;\r\n const webgl2OrBetter = deviceType !== 'webgl' || shaderCaps.maxUniformBufferSize > 0;\r\n return (\r\n webgl2OrBetter &&\r\n framebufferCaps.maxDrawBuffers >= 3 &&\r\n framebufferCaps.supportPerTargetBlending &&\r\n framebufferCaps.maxColorAttachmentBytesPerSample >= COLOR_ATTACHMENT_BYTES_PER_SAMPLE &&\r\n miscCaps.supportBlendMinMax &&\r\n textureCaps.supportHalfFloatColorBuffer &&\r\n textureCaps.supportFloatColorBuffer &&\r\n textureCaps.supportFloatBlending\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.getType}\r\n */\r\n getType() {\r\n return DualDepthPeelingOIT.type;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.supportDevice}\r\n */\r\n supportDevice(deviceType: string) {\r\n const device = tryGetApp()?.device;\r\n return (\r\n !!device &&\r\n device.type === deviceType &&\r\n DualDepthPeelingOIT.supportDeviceCaps(deviceType, device.getDeviceCaps())\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsPremultipliedAlpha}\r\n */\r\n wantsPremultipliedAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}\r\n */\r\n wantsAdditiveLightPassAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.begin}\r\n */\r\n begin(ctx: DrawContext) {\r\n this.releaseFramebuffers();\r\n if (!ctx.depthTexture) {\r\n return 0;\r\n }\r\n this._device = ctx.device;\r\n this.createFramebuffers(ctx);\r\n return this._numPeels + 1;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.end}\r\n */\r\n end(ctx: DrawContext) {\r\n try {\r\n if (this._frontTarget && this._backTarget) {\r\n this.composite(ctx, ctx.device, this._frontTarget, this._backTarget);\r\n }\r\n } finally {\r\n this.releaseFramebuffers();\r\n this._hash = DualDepthPeelingOIT.type;\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.beginPass}\r\n */\r\n beginPass(ctx: DrawContext, pass: number) {\r\n this._currentPass = pass;\r\n const targetIndex = pass & 1;\r\n const currentDepthTarget = this._depthTargets[targetIndex];\r\n const previousDepthTarget = this._depthTargets[targetIndex ^ 1];\r\n const framebuffer = this._framebuffers[targetIndex];\r\n if (!currentDepthTarget || !framebuffer || (pass > 0 && !previousDepthTarget)) {\r\n return false;\r\n }\r\n this._hash =\r\n pass === 0\r\n ? `${this.getType()}#init#${currentDepthTarget.uid}`\r\n : `${this.getType()}#peel#${previousDepthTarget!.uid}`;\r\n ctx.device.pushDeviceStates();\r\n ctx.device.setFramebuffer(framebuffer);\r\n ctx.device.clearFrameBuffer(\r\n pass === 0\r\n ? [DualDepthPeelingOIT.DEPTH_CLEAR, DualDepthPeelingOIT.FRONT_CLEAR, DualDepthPeelingOIT.BACK_CLEAR]\r\n : [DualDepthPeelingOIT.DEPTH_CLEAR, null, null],\r\n null,\r\n null\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.endPass}\r\n */\r\n endPass(ctx: DrawContext, _pass: number) {\r\n ctx.device.popDeviceStates();\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setupFragmentOutput}\r\n */\r\n setupFragmentOutput(scope: PBGlobalScope) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2();\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4();\r\n scope.$outputs.Z_DDP_backColor = pb.vec4();\r\n if (this._currentPass > 0) {\r\n scope.Z_DDP_depthTexture = pb.tex2D().uniform(2).noSampler();\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.outputFragmentColor}\r\n */\r\n outputFragmentColor(scope: PBInsideFunctionScope, color: PBShaderExp, ctx: DrawContext) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2(-1, -1);\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4(0, 0, 0, 0);\r\n scope.$outputs.Z_DDP_backColor = pb.vec4(0, 0, 0, 0);\r\n if (this._currentPass === 0) {\r\n scope.$outputs.Z_DDP_depth = pb.vec2(pb.neg(scope.$builtins.fragCoord.z), scope.$builtins.fragCoord.z);\r\n } else {\r\n scope.$l.Z_DDP_prevDepth = pb.textureLoad(\r\n scope.Z_DDP_depthTexture,\r\n pb.ivec2(scope.$builtins.fragCoord.xy),\r\n 0\r\n ).xy;\r\n scope.$l.Z_DDP_frontDepth = pb.neg(scope.Z_DDP_prevDepth.x);\r\n scope.$l.Z_DDP_backDepth = scope.Z_DDP_prevDepth.y;\r\n scope.$l.Z_DDP_curDepth = scope.$builtins.fragCoord.z;\r\n scope.$l.Z_DDP_outputColor = pb.vec4(color.rgb, ctx.lightBlending ? pb.float(0) : color.a);\r\n scope\r\n .$if(\r\n pb.or(\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n pb.discard();\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_depth = pb.vec2(\r\n pb.neg(this.$builtins.fragCoord.z),\r\n this.$builtins.fragCoord.z\r\n );\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.lessThan(scope.Z_DDP_curDepth, pb.add(scope.Z_DDP_frontDepth, 0.000001)),\r\n pb.greaterThan(scope.Z_DDP_curDepth, pb.sub(scope.Z_DDP_frontDepth, 0.000001))\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_frontColor = this.Z_DDP_outputColor;\r\n }\r\n )\r\n .$else(function () {\r\n this.$outputs.Z_DDP_backColor = this.Z_DDP_outputColor;\r\n });\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.applyUniforms}\r\n */\r\n applyUniforms(_ctx: DrawContext, bindGroup: BindGroup) {\r\n if (this._currentPass > 0) {\r\n bindGroup.setTexture('Z_DDP_depthTexture', this._depthTargets[(this._currentPass & 1) ^ 1]!);\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.calculateHash}\r\n */\r\n calculateHash() {\r\n return this._hash;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setRenderStates}\r\n */\r\n setRenderStates(rs: RenderStateSet) {\r\n rs.useBlendingState().enable(false).enableAlphaToCoverage(false);\r\n rs.useDepthState().enableTest(true).enableWrite(false);\r\n\r\n rs.useTargetBlendingState(0)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('max', 'max')\r\n .setBlendFunc('one', 'one');\r\n\r\n rs.useTargetBlendingState(1)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('dst-alpha', 'one')\r\n .setBlendFuncAlpha('zero', 'inv-src-alpha');\r\n\r\n rs.useTargetBlendingState(2)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('one', 'inv-src-alpha');\r\n }\r\n\r\n /** @internal */\r\n private createFramebuffers(ctx: DrawContext) {\r\n const device = ctx.device;\r\n const width = ctx.depthTexture!.width;\r\n const height = ctx.depthTexture!.height;\r\n const depthTarget0 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const depthTarget1 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const frontTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const backTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const framebuffer0 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget0, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n const framebuffer1 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget1, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n device.pool.releaseTexture(depthTarget0);\r\n device.pool.releaseTexture(depthTarget1);\r\n device.pool.releaseTexture(frontTarget);\r\n device.pool.releaseTexture(backTarget);\r\n this._depthTargets = [depthTarget0, depthTarget1];\r\n this._frontTarget = frontTarget;\r\n this._backTarget = backTarget;\r\n this._framebuffers = [framebuffer0, framebuffer1];\r\n }\r\n\r\n /** @internal */\r\n private composite(ctx: DrawContext, device: AbstractDevice, frontTarget: Texture2D, backTarget: Texture2D) {\r\n const currentFramebuffer = device.getFramebuffer();\r\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\r\n const singleColorFramebuffer =\r\n currentFramebuffer && currentFramebuffer.getColorAttachments().length > 1 && colorAttachment\r\n ? device.pool.fetchTemporalFramebuffer(\r\n false,\r\n 0,\r\n 0,\r\n colorAttachment,\r\n currentFramebuffer.getDepthAttachment(),\r\n false\r\n )\r\n : null;\r\n if (singleColorFramebuffer) {\r\n const viewport = device.getViewport();\r\n const scissor = device.getScissor();\r\n device.pushDeviceStates();\r\n device.setFramebuffer(singleColorFramebuffer);\r\n device.setViewport(viewport);\r\n device.setScissor(scissor);\r\n }\r\n try {\r\n device.setProgram(DualDepthPeelingOIT.getCompositeProgram(device));\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('frontTex', frontTarget);\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('backTex', backTarget);\r\n device.setBindGroup(0, DualDepthPeelingOIT._compositeBindGroup!);\r\n drawFullscreenQuad(DualDepthPeelingOIT._compositeRenderStates!);\r\n } finally {\r\n if (singleColorFramebuffer) {\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(singleColorFramebuffer);\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private releaseFramebuffers() {\r\n if (this._device) {\r\n if (this._framebuffers[0]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[0]);\r\n }\r\n if (this._framebuffers[1]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[1]);\r\n }\r\n }\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** @internal */\r\n private static getCompositeProgram(device: AbstractDevice) {\r\n if (!this._compositeProgram) {\r\n this._compositeProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n if (device.type === 'webgpu') {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n }\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.outColor = pb.vec4();\r\n this.frontTex = pb.tex2D().uniform(0);\r\n this.backTex = pb.tex2D().uniform(0);\r\n pb.main(function () {\r\n this.$l.frontColor = pb.textureSample(this.frontTex, this.$inputs.uv);\r\n this.$l.backColor = pb.textureSample(this.backTex, this.$inputs.uv);\r\n this.$l.remainingAlpha = pb.clamp(pb.mul(this.frontColor.a, pb.sub(1, this.backColor.a)), 0, 1);\r\n this.$outputs.outColor = pb.vec4(\r\n pb.add(this.frontColor.rgb, pb.mul(this.frontColor.a, this.backColor.rgb)),\r\n this.remainingAlpha\r\n );\r\n });\r\n }\r\n })!;\r\n this._compositeProgram.name = '@DualDepthPeelingOIT_Composite';\r\n this._compositeBindGroup = device.createBindGroup(this._compositeProgram.bindGroupLayouts[0]);\r\n this._compositeRenderStates = device.createRenderStateSet();\r\n this._compositeRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this._compositeRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n }\r\n return this._compositeProgram;\r\n }\r\n\r\n protected onDispose() {\r\n super.onDispose();\r\n this.releaseFramebuffers();\r\n }\r\n}\r\n"],"names":["DEPTH_FORMAT","ACCUM_FORMAT","COLOR_ATTACHMENT_BYTES_PER_SAMPLE","DualDepthPeelingOIT","Disposable","type","DEPTH_CLEAR","Vector4","FRONT_CLEAR","BACK_CLEAR","_compositeProgram","_compositeBindGroup","_compositeRenderStates","_numPeels","_currentPass","_hash","_depthTargets","_frontTarget","_backTarget","_framebuffers","_device","numPeels","Math","max","floor","val","supportDeviceCaps","deviceType","caps","framebufferCaps","textureCaps","shaderCaps","miscCaps","webgl2OrBetter","maxUniformBufferSize","maxDrawBuffers","supportPerTargetBlending","maxColorAttachmentBytesPerSample","supportBlendMinMax","supportHalfFloatColorBuffer","supportFloatColorBuffer","supportFloatBlending","getType","supportDevice","device","tryGetApp","getDeviceCaps","wantsPremultipliedAlpha","wantsAdditiveLightPassAlpha","begin","ctx","releaseFramebuffers","depthTexture","createFramebuffers","end","composite","beginPass","pass","targetIndex","currentDepthTarget","previousDepthTarget","framebuffer","uid","pushDeviceStates","setFramebuffer","clearFrameBuffer","endPass","_pass","popDeviceStates","setupFragmentOutput","scope","pb","$builder","$outputs","Z_DDP_depth","vec2","Z_DDP_frontColor","vec4","Z_DDP_backColor","Z_DDP_depthTexture","tex2D","uniform","noSampler","outputFragmentColor","color","neg","$builtins","fragCoord","z","$l","Z_DDP_prevDepth","textureLoad","ivec2","xy","Z_DDP_frontDepth","x","Z_DDP_backDepth","y","Z_DDP_curDepth","Z_DDP_outputColor","rgb","lightBlending","float","a","$if","or","lessThan","add","greaterThan","sub","discard","$elseif","and","$else","applyUniforms","_ctx","bindGroup","setTexture","calculateHash","setRenderStates","rs","useBlendingState","enable","enableAlphaToCoverage","useDepthState","enableTest","enableWrite","useTargetBlendingState","setBlendEquation","setBlendFunc","setBlendFuncRGB","setBlendFuncAlpha","width","height","depthTarget0","pool","fetchTemporalTexture2D","depthTarget1","frontTarget","backTarget","framebuffer0","createTemporalFramebuffer","framebuffer1","releaseTexture","currentFramebuffer","getFramebuffer","colorAttachment","getColorAttachments","singleColorFramebuffer","length","fetchTemporalFramebuffer","getDepthAttachment","viewport","getViewport","scissor","getScissor","setViewport","setScissor","setProgram","getCompositeProgram","setBindGroup","drawFullscreenQuad","releaseFrameBuffer","buildRenderProgram","vertex","$inputs","pos","attrib","uv","main","position","mul","fragment","outColor","frontTex","backTex","frontColor","textureSample","backColor","remainingAlpha","clamp","name","createBindGroup","bindGroupLayouts","createRenderStateSet","onDispose"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Disposable, DRef, Vector3, Vector4 } from '@zephyr3d/base';
2
- import { fetchSampler } from '../utility/misc.js';
2
+ import { getSamplerOptions, fetchSampler } from '../utility/misc.js';
3
3
  import { getDevice } from '../app/api.js';
4
4
 
5
5
  /**
@@ -75,11 +75,12 @@ import { getDevice } from '../app/api.js';
75
75
  */ initShaderBindings(pb) {
76
76
  if (pb.shaderKind === 'fragment') {
77
77
  if (this.radianceMap) {
78
- pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_RADIANCE_MAP] = pb.texCube().uniform(0);
78
+ // Prefiltered radiance cube: mipmap chain indexed by roughness
79
+ pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_RADIANCE_MAP] = pb.texCube().uniform(0).withSampler(getSamplerOptions('clamp_linear'));
79
80
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_RADIANCE_MAP_MAX_LOD] = pb.float().uniform(0);
80
81
  }
81
82
  if (this.sheenRadianceMap) {
82
- pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_SHEEN_RADIANCE_MAP] = pb.texCube().uniform(0);
83
+ pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_SHEEN_RADIANCE_MAP] = pb.texCube().uniform(0).withSampler(getSamplerOptions('clamp_linear'));
83
84
  }
84
85
  if (this.irradianceSHFB) {
85
86
  const tex = pb.tex2D();
@@ -87,6 +88,8 @@ import { getDevice } from '../app/api.js';
87
88
  if (formatInfo && !formatInfo.filterable) {
88
89
  tex.sampleType('unfilterable-float');
89
90
  }
91
+ // SH coefficients are read at texel centers; nearest sampling is exact
92
+ tex.withSampler(getSamplerOptions('clamp_nearest_nomip'));
90
93
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_SH] = tex.uniform(0);
91
94
  pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_WINDOW] = pb.vec3().uniform(0);
92
95
  } else if (this.irradianceSH) {