@zephyr3d/scene 0.9.26 → 0.9.27

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 (95) hide show
  1. package/dist/animation/animationset.js +92 -30
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  4. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  5. package/dist/animation/skeleton.js +21 -1
  6. package/dist/animation/skeleton.js.map +1 -1
  7. package/dist/asset/model.js +6 -2
  8. package/dist/asset/model.js.map +1 -1
  9. package/dist/camera/camera.js +75 -23
  10. package/dist/camera/camera.js.map +1 -1
  11. package/dist/index.d.ts +4764 -3600
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/material/hairstrand.js +235 -235
  15. package/dist/material/hairstrand.js.map +1 -1
  16. package/dist/material/material.js +296 -296
  17. package/dist/material/material.js.map +1 -1
  18. package/dist/material/mixins/lit.js +33 -1
  19. package/dist/material/mixins/lit.js.map +1 -1
  20. package/dist/material/shader/helper.js +404 -3
  21. package/dist/material/shader/helper.js.map +1 -1
  22. package/dist/material/water.js +2057 -72
  23. package/dist/material/water.js.map +1 -1
  24. package/dist/posteffect/motionblur.js +663 -58
  25. package/dist/posteffect/motionblur.js.map +1 -1
  26. package/dist/posteffect/posteffect.js +12 -1
  27. package/dist/posteffect/posteffect.js.map +1 -1
  28. package/dist/posteffect/sao.js +46 -44
  29. package/dist/posteffect/sao.js.map +1 -1
  30. package/dist/posteffect/sss.js +30 -2
  31. package/dist/posteffect/sss.js.map +1 -1
  32. package/dist/render/abuffer_oit.js +37 -37
  33. package/dist/render/abuffer_oit.js.map +1 -1
  34. package/dist/render/clipmap.js +156 -5
  35. package/dist/render/clipmap.js.map +1 -1
  36. package/dist/render/cull_visitor.js +1 -0
  37. package/dist/render/cull_visitor.js.map +1 -1
  38. package/dist/render/dualdepthpeeling_oit.js +49 -49
  39. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  40. package/dist/render/fbm_wavegenerator.js +3 -3
  41. package/dist/render/fbm_wavegenerator.js.map +1 -1
  42. package/dist/render/fft_wavegenerator.js +57 -15
  43. package/dist/render/fft_wavegenerator.js.map +1 -1
  44. package/dist/render/gerstner_wavegenerator.js +127 -20
  45. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  46. package/dist/render/hzb.js +80 -22
  47. package/dist/render/hzb.js.map +1 -1
  48. package/dist/render/lightpass.js +6 -3
  49. package/dist/render/lightpass.js.map +1 -1
  50. package/dist/render/oit.js +11 -11
  51. package/dist/render/oit.js.map +1 -1
  52. package/dist/render/render_queue.js +36 -0
  53. package/dist/render/render_queue.js.map +1 -1
  54. package/dist/render/renderer.js +4 -0
  55. package/dist/render/renderer.js.map +1 -1
  56. package/dist/render/rendergraph/blackboard.js +1 -0
  57. package/dist/render/rendergraph/blackboard.js.map +1 -1
  58. package/dist/render/rendergraph/forward_plus_builder.js +318 -9
  59. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  60. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  61. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  62. package/dist/render/rendergraph/history_resources.js +8 -1
  63. package/dist/render/rendergraph/history_resources.js.map +1 -1
  64. package/dist/render/underwater.js +624 -0
  65. package/dist/render/underwater.js.map +1 -0
  66. package/dist/render/water_caustics.js +1380 -0
  67. package/dist/render/water_caustics.js.map +1 -0
  68. package/dist/render/weightedblended_oit.js +33 -33
  69. package/dist/render/weightedblended_oit.js.map +1 -1
  70. package/dist/scene/water.js +540 -4
  71. package/dist/scene/water.js.map +1 -1
  72. package/dist/shaders/water.js +22 -19
  73. package/dist/shaders/water.js.map +1 -1
  74. package/dist/shaders/water_medium.js +56 -0
  75. package/dist/shaders/water_medium.js.map +1 -0
  76. package/dist/shadow/shadow_region.js +49 -49
  77. package/dist/shadow/shadow_region.js.map +1 -1
  78. package/dist/utility/serialization/manager.js +3 -1
  79. package/dist/utility/serialization/manager.js.map +1 -1
  80. package/dist/utility/serialization/scene/animation.js +31 -2
  81. package/dist/utility/serialization/scene/animation.js.map +1 -1
  82. package/dist/utility/serialization/scene/camera.js +53 -25
  83. package/dist/utility/serialization/scene/camera.js.map +1 -1
  84. package/dist/utility/serialization/scene/light.js.map +1 -1
  85. package/dist/utility/serialization/scene/water.js +1101 -21
  86. package/dist/utility/serialization/scene/water.js.map +1 -1
  87. package/dist/utility/shprojector.js +87 -87
  88. package/dist/utility/shprojector.js.map +1 -1
  89. package/package.json +1 -1
  90. package/dist/render/rendergraph/frame_graph_context.js +0 -41
  91. package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
  92. package/dist/shaders/ssgi.js +0 -63
  93. package/dist/shaders/ssgi.js.map +0 -1
  94. package/dist/shaders/ssgi_reprojection.js +0 -118
  95. package/dist/shaders/ssgi_reprojection.js.map +0 -1
@@ -24,13 +24,13 @@ import '../material/sprite.js';
24
24
  import '../material/sprite_std.js';
25
25
  import '../utility/blueprint/material/texture.js';
26
26
 
27
- /**
28
- * per-pixel linked list OIT renderer using ABuffer.
29
- *
30
- * @remarks
31
- * The ABuffer OIT renderer only supports WebGPU device.
32
- *
33
- * @public
27
+ /**
28
+ * per-pixel linked list OIT renderer using ABuffer.
29
+ *
30
+ * @remarks
31
+ * The ABuffer OIT renderer only supports WebGPU device.
32
+ *
33
+ * @public
34
34
  */ class ABufferOIT extends OIT {
35
35
  /** Type name of ABufferOIT */ static type = 'ab';
36
36
  static usePremultipliedAlpha = true;
@@ -53,10 +53,10 @@ import '../utility/blueprint/material/texture.js';
53
53
  _currentPass;
54
54
  _savedScissor;
55
55
  _singleColorFramebuffer;
56
- /**
57
- * Creates an instance of ABufferOIT class
58
- *
59
- * @param numLayers - How many transparent layers, default is 16
56
+ /**
57
+ * Creates an instance of ABufferOIT class
58
+ *
59
+ * @param numLayers - How many transparent layers, default is 16
60
60
  */ constructor(numLayers = 16){
61
61
  super();
62
62
  this._nodeBuffer = null;
@@ -76,28 +76,28 @@ import '../utility/blueprint/material/texture.js';
76
76
  this._currentPass = 0;
77
77
  this._singleColorFramebuffer = null;
78
78
  }
79
- /**
80
- * {@inheritDoc OIT.getType}
79
+ /**
80
+ * {@inheritDoc OIT.getType}
81
81
  */ getType() {
82
82
  return ABufferOIT.type;
83
83
  }
84
- /**
85
- * {@inheritDoc OIT.supportDevice}
84
+ /**
85
+ * {@inheritDoc OIT.supportDevice}
86
86
  */ supportDevice(deviceType) {
87
87
  return deviceType === 'webgpu';
88
88
  }
89
- /**
90
- * {@inheritDoc OIT.wantsPremultipliedAlpha}
89
+ /**
90
+ * {@inheritDoc OIT.wantsPremultipliedAlpha}
91
91
  */ wantsPremultipliedAlpha() {
92
92
  return ABufferOIT.usePremultipliedAlpha;
93
93
  }
94
- /**
95
- * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}
94
+ /**
95
+ * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}
96
96
  */ wantsAdditiveLightPassAlpha() {
97
97
  return true;
98
98
  }
99
- /**
100
- * {@inheritDoc OIT.begin}
99
+ /**
100
+ * {@inheritDoc OIT.begin}
101
101
  */ begin(ctx) {
102
102
  const device = ctx.device;
103
103
  this._savedScissor = device.getScissor();
@@ -158,14 +158,14 @@ import '../utility/blueprint/material/texture.js';
158
158
  }
159
159
  return this._scissorSlices;
160
160
  }
161
- /**
162
- * {@inheritDoc OIT.end}
161
+ /**
162
+ * {@inheritDoc OIT.end}
163
163
  */ end(ctx) {
164
164
  // Restore scissor rect
165
165
  ctx.device.setScissor(this._savedScissor);
166
166
  }
167
- /**
168
- * {@inheritDoc OIT.setupFragmentOutput}
167
+ /**
168
+ * {@inheritDoc OIT.setupFragmentOutput}
169
169
  */ setupFragmentOutput(scope) {
170
170
  const pb = scope.$builder;
171
171
  scope.Z_AB_scissorOffset = pb.uint().uniformBuffer(2);
@@ -176,8 +176,8 @@ import '../utility/blueprint/material/texture.js';
176
176
  scope.Z_AB_depthTexture = pb.tex2D().uniform(2).noSampler();
177
177
  scope.$outputs.outColor = pb.vec4();
178
178
  }
179
- /**
180
- * {@inheritDoc OIT.beginPass}
179
+ /**
180
+ * {@inheritDoc OIT.beginPass}
181
181
  */ beginPass(ctx, pass) {
182
182
  this._currentPass = pass;
183
183
  const device = ctx.device;
@@ -222,8 +222,8 @@ import '../utility/blueprint/material/texture.js';
222
222
  }
223
223
  return true;
224
224
  }
225
- /**
226
- * {@inheritDoc OIT.endPass}
225
+ /**
226
+ * {@inheritDoc OIT.endPass}
227
227
  */ endPass(ctx, pass) {
228
228
  const device = ctx.device;
229
229
  ABufferOIT.getCompositeProgram(device);
@@ -262,13 +262,13 @@ import '../utility/blueprint/material/texture.js';
262
262
  }
263
263
  }
264
264
  }
265
- /**
266
- * {@inheritDoc OIT.calculateHash}
265
+ /**
266
+ * {@inheritDoc OIT.calculateHash}
267
267
  */ calculateHash() {
268
268
  return this._hash;
269
269
  }
270
- /**
271
- * {@inheritDoc OIT.applyUniforms}
270
+ /**
271
+ * {@inheritDoc OIT.applyUniforms}
272
272
  */ applyUniforms(ctx, bindGroup) {
273
273
  bindGroup.setBuffer('Z_AB_nodeBuffer', this._nodeBuffer);
274
274
  bindGroup.setBuffer('Z_AB_scissorOffset', this._scissorOffsetBuffer, 0, this._currentPass * ABufferOIT._ubAlignment, ABufferOIT._ubAlignment);
@@ -276,8 +276,8 @@ import '../utility/blueprint/material/texture.js';
276
276
  bindGroup.setValue('Z_AB_screenSize', this._screenSize[0]);
277
277
  bindGroup.setTexture('Z_AB_depthTexture', ctx.linearDepthTexture);
278
278
  }
279
- /**
280
- * {@inheritDoc OIT.outputFragmentColor}
279
+ /**
280
+ * {@inheritDoc OIT.outputFragmentColor}
281
281
  */ outputFragmentColor(scope, color) {
282
282
  const pb = scope.$builder;
283
283
  // linear depth of current fragment
@@ -301,8 +301,8 @@ import '../utility/blueprint/material/texture.js';
301
301
  });
302
302
  return true;
303
303
  }
304
- /**
305
- * {@inheritDoc OIT.setRenderStates}
304
+ /**
305
+ * {@inheritDoc OIT.setRenderStates}
306
306
  */ setRenderStates(rs) {
307
307
  const stencilStates = rs.useStencilState();
308
308
  stencilStates.enable(true);
@@ -1 +1 @@
1
- {"version":3,"file":"abuffer_oit.js","sources":["../../src/render/abuffer_oit.ts"],"sourcesContent":["import type {\n AbstractDevice,\n BindGroup,\n DeviceViewport,\n FrameBuffer,\n GPUDataBuffer,\n GPUProgram,\n PBGlobalScope,\n PBInsideFunctionScope,\n PBShaderExp,\n RenderStateSet\n} from '@zephyr3d/device';\nimport { OIT } from './oit';\nimport type { DrawContext } from './drawable';\nimport { drawFullscreenQuad } from './fullscreenquad';\nimport { ShaderHelper } from '../material';\nimport type { Nullable } from '@zephyr3d/base';\nimport { DEPTH_FARTHEST } from '@zephyr3d/base';\n\n/**\n * per-pixel linked list OIT renderer using ABuffer.\n *\n * @remarks\n * The ABuffer OIT renderer only supports WebGPU device.\n *\n * @public\n */\nexport class ABufferOIT extends OIT {\n /** Type name of ABufferOIT */\n public static readonly type = 'ab';\n public static readonly usePremultipliedAlpha = true;\n private static readonly MAX_FRAGMENT_LAYERS = 75;\n private static _compositeProgram: Nullable<GPUProgram> = null;\n private static _compositeBindGroup: Nullable<BindGroup> = null;\n private static _compositeRenderStates: Nullable<RenderStateSet> = null;\n private static _compositeAdditiveRenderStates: Nullable<RenderStateSet> = null;\n private static _ubAlignment = 0;\n private _nodeBuffer: Nullable<GPUDataBuffer>;\n private _headStagingBuffer: Nullable<GPUDataBuffer>;\n private _headBuffer: Nullable<GPUDataBuffer>;\n private _scissorOffsetBuffer: Nullable<GPUDataBuffer>;\n private readonly _numLayers: number;\n private _screenSize: Uint32Array<ArrayBuffer>;\n private _hash: Nullable<string>;\n private readonly _debug: boolean;\n private _scissorSlices: number;\n private _scissorHeight: number;\n private _currentPass: number;\n private _savedScissor: Nullable<DeviceViewport>;\n private _singleColorFramebuffer: Nullable<FrameBuffer>;\n /**\n * Creates an instance of ABufferOIT class\n *\n * @param numLayers - How many transparent layers, default is 16\n */\n constructor(numLayers = 16) {\n super();\n this._nodeBuffer = null;\n this._headStagingBuffer = null;\n this._headBuffer = null;\n this._scissorOffsetBuffer = null;\n this._numLayers = numLayers;\n this._screenSize = new Uint32Array([0xffffffff, 0xffffffff]);\n this._hash = null;\n this._debug = false;\n this._scissorSlices = 0;\n this._scissorHeight = 0;\n this._savedScissor = null;\n this._currentPass = 0;\n this._singleColorFramebuffer = null;\n }\n /**\n * {@inheritDoc OIT.getType}\n */\n getType() {\n return ABufferOIT.type;\n }\n /**\n * {@inheritDoc OIT.supportDevice}\n */\n supportDevice(deviceType: string) {\n return deviceType === 'webgpu';\n }\n /**\n * {@inheritDoc OIT.wantsPremultipliedAlpha}\n */\n wantsPremultipliedAlpha() {\n return ABufferOIT.usePremultipliedAlpha;\n }\n /**\n * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}\n */\n wantsAdditiveLightPassAlpha() {\n return true;\n }\n /**\n * {@inheritDoc OIT.begin}\n */\n begin(ctx: DrawContext) {\n const device = ctx.device;\n this._savedScissor = device.getScissor();\n const ubAlignment = (ABufferOIT._ubAlignment =\n device.getDeviceCaps().shaderCaps.uniformBufferOffsetAlignment);\n const viewport = device.getViewport();\n const screenWidth = device.screenXToDevice(viewport.width);\n const screenHeight = device.screenYToDevice(Math.max(viewport.height, 1));\n if (screenWidth !== this._screenSize[0] || screenHeight !== this._screenSize[1]) {\n // Mark uniform changed\n this.uniformChanged();\n // Resize buffers if viewport was changed\n this._screenSize[0] = screenWidth;\n this._screenSize[1] = screenHeight;\n // compute scissor slices\n const maxBufferSize = device.getDeviceCaps().shaderCaps.maxStorageBufferSize;\n const bytesPerLine = screenWidth * 4 * 4 * this._numLayers;\n this._scissorHeight = (maxBufferSize / bytesPerLine) >> 0;\n this._scissorSlices = Math.ceil(screenHeight / this._scissorHeight);\n const offsetBufferSize = ubAlignment * this._scissorSlices;\n const offsetBuffer = new Uint32Array(offsetBufferSize >> 2);\n for (let i = 0; i < this._scissorSlices; i++) {\n offsetBuffer[i * (ubAlignment >> 2)] = i * this._scissorHeight;\n }\n if (!this._scissorOffsetBuffer || this._scissorOffsetBuffer.byteLength < offsetBuffer.byteLength) {\n this._scissorOffsetBuffer?.dispose();\n this._scissorOffsetBuffer = device.createBuffer(offsetBuffer.byteLength, { usage: 'uniform' });\n }\n this._scissorOffsetBuffer.bufferSubData(0, offsetBuffer);\n // resize node buffer\n const size = screenWidth * this._scissorHeight * 4;\n const nodeBufferSize = size * 4 * this._numLayers;\n if (!this._nodeBuffer || nodeBufferSize > this._nodeBuffer.byteLength) {\n this._nodeBuffer?.dispose();\n this._nodeBuffer = device.createBuffer(nodeBufferSize, { storage: true, usage: 'uniform' });\n }\n // resize head buffer\n const headBufferSize = size + 4;\n if (!this._headBuffer || headBufferSize > this._headBuffer.byteLength) {\n this._headBuffer?.dispose();\n this._headBuffer = device.createBuffer(headBufferSize, { storage: true, usage: 'uniform' });\n this._headStagingBuffer?.dispose();\n this._headStagingBuffer = device.createBuffer(headBufferSize, { storage: true, usage: 'uniform' });\n const tmpArray = new Uint32Array(headBufferSize >> 2);\n tmpArray.fill(0xffffffff);\n this._headStagingBuffer.bufferSubData(0, tmpArray);\n }\n }\n return this._scissorSlices;\n }\n /**\n * {@inheritDoc OIT.end}\n */\n end(ctx: DrawContext) {\n // Restore scissor rect\n ctx.device.setScissor(this._savedScissor);\n }\n /**\n * {@inheritDoc OIT.setupFragmentOutput}\n */\n setupFragmentOutput(scope: PBGlobalScope) {\n const pb = scope.$builder;\n scope.Z_AB_scissorOffset = pb.uint().uniformBuffer(2);\n scope.Z_AB_nodeBuffer = pb.uvec4[0]().storageBuffer(2);\n scope.Z_AB_headImage = pb.atomic_uint[0]().storageBuffer(2);\n scope.Z_AB_screenSize = pb.uint().uniform(2);\n // Read with textureLoad only\n scope.Z_AB_depthTexture = pb.tex2D().uniform(2).noSampler();\n scope.$outputs.outColor = pb.vec4();\n }\n /**\n * {@inheritDoc OIT.beginPass}\n */\n beginPass(ctx: DrawContext, pass: number) {\n this._currentPass = pass;\n const device = ctx.device;\n const currentFramebuffer = device.getFramebuffer();\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\n this._singleColorFramebuffer =\n currentFramebuffer && currentFramebuffer.getColorAttachments().length > 1 && colorAttachment\n ? device.pool.fetchTemporalFramebuffer(\n false,\n 0,\n 0,\n colorAttachment,\n currentFramebuffer.getDepthAttachment(),\n false\n )\n : null;\n if (this._singleColorFramebuffer) {\n const viewport = device.getViewport();\n const scissor = device.getScissor();\n device.pushDeviceStates();\n device.setFramebuffer(this._singleColorFramebuffer);\n device.setViewport(viewport);\n device.setScissor(scissor);\n }\n const scissorY = pass * this._scissorHeight;\n const scissorH =\n Math.min((pass + 1) * this._scissorHeight, this._screenSize[1]) - pass * this._scissorHeight;\n device.setScissor([\n 0,\n device.deviceYToScreen(this._screenSize[1] - scissorY - scissorH),\n device.deviceXToScreen(this._screenSize[0]),\n device.deviceYToScreen(scissorH)\n ]);\n device.copyBuffer(this._headStagingBuffer!, this._headBuffer!, 0, 0, this._headStagingBuffer!.byteLength);\n // Update render hash\n this._hash = `${this.getType()}#${this._nodeBuffer!.uid}#${this._headBuffer!.uid}#${\n this._scissorOffsetBuffer!.uid\n }#${pass}`;\n if (this._debug) {\n const data = new Uint8Array(this._headBuffer!.byteLength);\n const readBuffer = device.createBuffer(this._headBuffer!.byteLength, { usage: 'read' });\n device.copyBuffer(this._headBuffer!, readBuffer, 0, 0, this._headBuffer!.byteLength);\n readBuffer.getBufferSubData(data).then(() => {\n const uint = new Uint32Array(data.buffer);\n for (let i = 0; i < uint.length; i++) {\n if (uint[i] !== 0xffffffff) {\n console.error('Clear head buffer failed');\n break;\n }\n }\n readBuffer.dispose();\n });\n }\n return true;\n }\n /**\n * {@inheritDoc OIT.endPass}\n */\n endPass(ctx: DrawContext, pass: number) {\n const device = ctx.device;\n ABufferOIT.getCompositeProgram(device);\n const lastBindGroup = device.getBindGroup(0);\n const currentFramebuffer = device.getFramebuffer();\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\n const singleColorFramebuffer =\n !this._singleColorFramebuffer &&\n currentFramebuffer &&\n currentFramebuffer.getColorAttachments().length > 1 &&\n colorAttachment\n ? device.pool.fetchTemporalFramebuffer(\n false,\n 0,\n 0,\n colorAttachment,\n currentFramebuffer.getDepthAttachment(),\n false\n )\n : null;\n if (singleColorFramebuffer) {\n const viewport = device.getViewport();\n const scissor = device.getScissor();\n device.pushDeviceStates();\n device.setFramebuffer(singleColorFramebuffer);\n device.setViewport(viewport);\n device.setScissor(scissor);\n }\n try {\n device.setProgram(ABufferOIT.getCompositeProgram(device));\n const bindGroup = ABufferOIT._compositeBindGroup!;\n bindGroup.setBuffer(\n 'scissorOffset',\n this._scissorOffsetBuffer!,\n 0,\n pass * ABufferOIT._ubAlignment,\n ABufferOIT._ubAlignment\n );\n bindGroup.setBuffer('headBuffer', this._headBuffer!);\n bindGroup.setBuffer('nodeBuffer', this._nodeBuffer!);\n bindGroup.setValue('screenWidth', this._screenSize[0]);\n bindGroup.setValue('additiveOnly', ctx.lightBlending ? 1 : 0);\n device.setBindGroup(0, bindGroup);\n drawFullscreenQuad(\n ctx.lightBlending ? ABufferOIT._compositeAdditiveRenderStates! : ABufferOIT._compositeRenderStates!\n );\n } finally {\n if (singleColorFramebuffer) {\n device.popDeviceStates();\n device.pool.releaseFrameBuffer(singleColorFramebuffer);\n } else if (this._singleColorFramebuffer) {\n device.popDeviceStates();\n device.pool.releaseFrameBuffer(this._singleColorFramebuffer);\n this._singleColorFramebuffer = null;\n } else {\n device.setBindGroup(0, lastBindGroup[0], lastBindGroup[1]);\n }\n }\n }\n /**\n * {@inheritDoc OIT.calculateHash}\n */\n calculateHash() {\n return this._hash!;\n }\n /**\n * {@inheritDoc OIT.applyUniforms}\n */\n applyUniforms(ctx: DrawContext, bindGroup: BindGroup) {\n bindGroup.setBuffer('Z_AB_nodeBuffer', this._nodeBuffer!);\n bindGroup.setBuffer(\n 'Z_AB_scissorOffset',\n this._scissorOffsetBuffer!,\n 0,\n this._currentPass * ABufferOIT._ubAlignment,\n ABufferOIT._ubAlignment\n );\n bindGroup.setBuffer('Z_AB_headImage', this._headBuffer!);\n bindGroup.setValue('Z_AB_screenSize', this._screenSize[0]);\n bindGroup.setTexture('Z_AB_depthTexture', ctx.linearDepthTexture!);\n }\n /**\n * {@inheritDoc OIT.outputFragmentColor}\n */\n outputFragmentColor(scope: PBInsideFunctionScope, color: PBShaderExp) {\n const pb = scope.$builder;\n // linear depth of current fragment\n scope.$l.fragDepth = ShaderHelper.nonLinearDepthToLinearNormalized(scope, scope.$builtins.fragCoord.z);\n // linear depth in depth texture\n scope.$l.linearDepth = pb.textureLoad(\n scope.Z_AB_depthTexture,\n pb.ivec2(scope.$builtins.fragCoord.xy),\n 0\n ).r;\n // saved to buffer only if nothing is infront\n scope.$if(pb.lessThan(scope.fragDepth, scope.linearDepth), function () {\n this.$l.Z_AB_pixelCount = pb.atomicAdd(this.Z_AB_headImage.at(0), 1);\n this.$l.Z_AB_nodeOffset = this.Z_AB_pixelCount;\n // save if index not exceeded\n this.$if(pb.lessThan(this.Z_AB_nodeOffset, pb.arrayLength(this.Z_AB_nodeBuffer)), function () {\n this.$l.Z_AB_headOffset = pb.add(\n pb.mul(this.Z_AB_screenSize, pb.sub(pb.uint(this.$builtins.fragCoord.y), this.Z_AB_scissorOffset)),\n pb.uint(this.$builtins.fragCoord.x)\n );\n this.$l.Z_AB_oldHead = pb.atomicExchange(\n this.Z_AB_headImage.at(pb.add(this.Z_AB_headOffset, 1)),\n this.Z_AB_nodeOffset\n );\n this.$l.Z_AB_colorScale = pb.floatBitsToUint(pb.length(color.rgb));\n this.$l.Z_AB_color = pb.pack4x8unorm(pb.vec4(pb.normalize(color.rgb), pb.clamp(color.a, 0, 1)));\n this.$l.Z_AB_depth = pb.floatBitsToUint(this.fragDepth);\n this.Z_AB_nodeBuffer.setAt(\n this.Z_AB_nodeOffset,\n pb.uvec4(this.Z_AB_color, this.Z_AB_colorScale, this.Z_AB_depth, this.Z_AB_oldHead)\n );\n pb.discard();\n });\n });\n return true;\n }\n /**\n * {@inheritDoc OIT.setRenderStates}\n */\n setRenderStates(rs: RenderStateSet) {\n const stencilStates = rs.useStencilState();\n stencilStates.enable(true);\n stencilStates.setFrontCompareFunc('always');\n stencilStates.setBackCompareFunc('always');\n stencilStates.setFrontOp('keep', 'keep', 'replace');\n stencilStates.setBackOp('keep', 'keep', 'replace');\n stencilStates.setReference(1);\n stencilStates.setReadMask(0xff);\n }\n /** @internal */\n private static getCompositeProgram(device: AbstractDevice) {\n if (!this._compositeProgram) {\n this._compositeProgram = device.buildRenderProgram({\n vertex(pb) {\n this.$inputs.pos = pb.vec2().attrib('position');\n this.$outputs.uv = pb.vec2();\n pb.main(function () {\n this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\n if (device.type === 'webgpu') {\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\n }\n });\n },\n fragment(pb) {\n this.$outputs.outColor = pb.vec4();\n this.scissorOffset = pb.uint().uniformBuffer(0);\n this.headBuffer = pb.uint[0]().storageBuffer(0);\n this.nodeBuffer = pb.uvec4[0]().storageBuffer(0);\n this.screenWidth = pb.uint().uniform(0);\n this.additiveOnly = pb.int().uniform(0);\n pb.func('unpackColor', [pb.uvec4('x')], function () {\n this.$l.colorNorm = pb.unpack4x8unorm(this.x.x);\n this.$l.colorScale = pb.uintBitsToFloat(this.x.y);\n this.$return(pb.vec4(pb.mul(this.colorNorm.rgb, this.colorScale), this.colorNorm.a));\n });\n pb.main(function () {\n this.$l.fragmentArray = pb.uvec4[ABufferOIT.MAX_FRAGMENT_LAYERS]();\n this.$l.fragmentArrayLen = pb.uint(0);\n this.$l.offset = pb.add(\n pb.mul(this.screenWidth, pb.sub(pb.uint(this.$builtins.fragCoord.y), this.scissorOffset)),\n pb.uint(this.$builtins.fragCoord.x)\n );\n //this.$l.head = this.headBuffer.at(this.offset);\n this.$l.head = this.headBuffer.at(pb.add(this.offset, 1));\n this.$while(\n pb.and(\n pb.lessThan(this.fragmentArrayLen, ABufferOIT.MAX_FRAGMENT_LAYERS),\n pb.notEqual(this.head, 0xffffffff)\n ),\n function () {\n this.fragmentArray.setAt(this.fragmentArrayLen, this.nodeBuffer.at(this.head));\n this.head = this.fragmentArray.at(this.fragmentArrayLen).w;\n this.fragmentArrayLen = pb.add(this.fragmentArrayLen, 1);\n }\n );\n this.$if(pb.equal(this.fragmentArrayLen, 0), function () {\n this.$outputs.outColor = pb.vec4(0, 0, 0, 1);\n }).$else(function () {\n // bubble sort\n this.$for(pb.uint('i'), 0, pb.sub(this.fragmentArrayLen, 1), function () {\n this.$for(pb.uint('j'), 0, pb.sub(pb.sub(this.fragmentArrayLen, 1), this.i), function () {\n this.$l.a = this.fragmentArray.at(this.j);\n this.$l.b = this.fragmentArray.at(pb.add(this.j, 1));\n this.$if(pb.greaterThan(this.a.z, this.b.z), function () {\n this.fragmentArray.setAt(this.j, this.b);\n this.fragmentArray.setAt(pb.add(this.j, 1), this.a);\n });\n });\n });\n // under operator blending\n this.$l.c0 = this.unpackColor(this.fragmentArray[0]);\n this.$l.c_dst = ABufferOIT.usePremultipliedAlpha ? this.c0.rgb : pb.mul(this.c0.rgb, this.c0.a);\n this.$l.a_dst = pb.sub(1, this.c0.a);\n this.$for(pb.uint('i'), 1, this.fragmentArrayLen, function () {\n this.$l.c = this.unpackColor(this.fragmentArray.at(this.i));\n if (ABufferOIT.usePremultipliedAlpha) {\n this.c_dst = pb.add(this.c_dst, pb.mul(this.c.rgb, this.a_dst));\n } else {\n this.c_dst = pb.add(this.c_dst, pb.mul(this.c.rgb, this.c.a, this.a_dst));\n }\n this.a_dst = pb.mul(this.a_dst, pb.sub(1, this.c.a));\n });\n this.$outputs.outColor = pb.vec4(\n this.c_dst,\n pb.equal(this.additiveOnly, 0) ? this.a_dst : pb.float(0)\n );\n });\n });\n }\n })!;\n this._compositeProgram.name = '@ABufferOIT_Composite';\n this._compositeBindGroup = device.createBindGroup(this._compositeProgram.bindGroupLayouts[0]);\n this._compositeRenderStates = device.createRenderStateSet();\n this._compositeRenderStates\n .useBlendingState()\n .enable(true)\n .setBlendFuncRGB('one', 'src-alpha')\n .setBlendFuncAlpha('zero', 'one');\n this._compositeRenderStates.useDepthState().enableTest(false).enableWrite(false);\n this._compositeAdditiveRenderStates = device.createRenderStateSet();\n this._compositeAdditiveRenderStates\n .useBlendingState()\n .enable(true)\n .setBlendFuncRGB('one', 'one')\n .setBlendFuncAlpha('zero', 'one');\n this._compositeAdditiveRenderStates.useDepthState().enableTest(false).enableWrite(false);\n const stencilStates = this._compositeRenderStates.useStencilState();\n stencilStates.enable(false);\n stencilStates.setFrontCompareFunc('always');\n stencilStates.setBackCompareFunc('always');\n stencilStates.setFrontOp('keep', 'keep', 'replace');\n stencilStates.setBackOp('keep', 'keep', 'replace');\n stencilStates.setReference(0);\n stencilStates.setReadMask(0xff);\n const additiveStencilStates = this._compositeAdditiveRenderStates.useStencilState();\n additiveStencilStates.enable(false);\n additiveStencilStates.setFrontCompareFunc('always');\n additiveStencilStates.setBackCompareFunc('always');\n additiveStencilStates.setFrontOp('keep', 'keep', 'replace');\n additiveStencilStates.setBackOp('keep', 'keep', 'replace');\n additiveStencilStates.setReference(0);\n additiveStencilStates.setReadMask(0xff);\n }\n return this._compositeProgram;\n }\n protected onDispose() {\n super.onDispose();\n this._nodeBuffer?.dispose();\n this._nodeBuffer = null;\n this._headStagingBuffer?.dispose();\n this._headStagingBuffer = null;\n this._headBuffer?.dispose();\n this._headBuffer = null;\n this._scissorOffsetBuffer?.dispose();\n this._scissorOffsetBuffer = null;\n this._hash = null;\n this._savedScissor = null;\n }\n}\n"],"names":["ABufferOIT","OIT","type","usePremultipliedAlpha","MAX_FRAGMENT_LAYERS","_compositeProgram","_compositeBindGroup","_compositeRenderStates","_compositeAdditiveRenderStates","_ubAlignment","_nodeBuffer","_headStagingBuffer","_headBuffer","_scissorOffsetBuffer","_numLayers","_screenSize","_hash","_debug","_scissorSlices","_scissorHeight","_currentPass","_savedScissor","_singleColorFramebuffer","numLayers","Uint32Array","getType","supportDevice","deviceType","wantsPremultipliedAlpha","wantsAdditiveLightPassAlpha","begin","ctx","device","getScissor","ubAlignment","getDeviceCaps","shaderCaps","uniformBufferOffsetAlignment","viewport","getViewport","screenWidth","screenXToDevice","width","screenHeight","screenYToDevice","Math","max","height","uniformChanged","maxBufferSize","maxStorageBufferSize","bytesPerLine","ceil","offsetBufferSize","offsetBuffer","i","byteLength","dispose","createBuffer","usage","bufferSubData","size","nodeBufferSize","storage","headBufferSize","tmpArray","fill","end","setScissor","setupFragmentOutput","scope","pb","$builder","Z_AB_scissorOffset","uint","uniformBuffer","Z_AB_nodeBuffer","uvec4","storageBuffer","Z_AB_headImage","atomic_uint","Z_AB_screenSize","uniform","Z_AB_depthTexture","tex2D","noSampler","$outputs","outColor","vec4","beginPass","pass","currentFramebuffer","getFramebuffer","colorAttachment","getColorAttachments","length","pool","fetchTemporalFramebuffer","getDepthAttachment","scissor","pushDeviceStates","setFramebuffer","setViewport","scissorY","scissorH","min","deviceYToScreen","deviceXToScreen","copyBuffer","uid","data","Uint8Array","readBuffer","getBufferSubData","then","buffer","console","error","endPass","getCompositeProgram","lastBindGroup","getBindGroup","singleColorFramebuffer","setProgram","bindGroup","setBuffer","setValue","lightBlending","setBindGroup","drawFullscreenQuad","popDeviceStates","releaseFrameBuffer","calculateHash","applyUniforms","setTexture","linearDepthTexture","outputFragmentColor","color","$l","fragDepth","ShaderHelper","nonLinearDepthToLinearNormalized","$builtins","fragCoord","z","linearDepth","textureLoad","ivec2","xy","r","$if","lessThan","Z_AB_pixelCount","atomicAdd","at","Z_AB_nodeOffset","arrayLength","Z_AB_headOffset","add","mul","sub","y","x","Z_AB_oldHead","atomicExchange","Z_AB_colorScale","floatBitsToUint","rgb","Z_AB_color","pack4x8unorm","normalize","clamp","a","Z_AB_depth","setAt","discard","setRenderStates","rs","stencilStates","useStencilState","enable","setFrontCompareFunc","setBackCompareFunc","setFrontOp","setBackOp","setReference","setReadMask","buildRenderProgram","vertex","$inputs","pos","vec2","attrib","uv","main","position","DEPTH_FARTHEST","neg","fragment","scissorOffset","headBuffer","nodeBuffer","additiveOnly","int","func","colorNorm","unpack4x8unorm","colorScale","uintBitsToFloat","$return","fragmentArray","fragmentArrayLen","offset","head","$while","and","notEqual","w","equal","$else","$for","j","b","greaterThan","c0","unpackColor","c_dst","a_dst","c","float","name","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","additiveStencilStates","onDispose"],"mappings":"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"}
1
+ {"version":3,"file":"abuffer_oit.js","sources":["../../src/render/abuffer_oit.ts"],"sourcesContent":["import type {\r\n AbstractDevice,\r\n BindGroup,\r\n DeviceViewport,\r\n FrameBuffer,\r\n GPUDataBuffer,\r\n GPUProgram,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n RenderStateSet\r\n} from '@zephyr3d/device';\r\nimport { OIT } from './oit';\r\nimport type { DrawContext } from './drawable';\r\nimport { drawFullscreenQuad } from './fullscreenquad';\r\nimport { ShaderHelper } from '../material';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { DEPTH_FARTHEST } from '@zephyr3d/base';\r\n\r\n/**\r\n * per-pixel linked list OIT renderer using ABuffer.\r\n *\r\n * @remarks\r\n * The ABuffer OIT renderer only supports WebGPU device.\r\n *\r\n * @public\r\n */\r\nexport class ABufferOIT extends OIT {\r\n /** Type name of ABufferOIT */\r\n public static readonly type = 'ab';\r\n public static readonly usePremultipliedAlpha = true;\r\n private static readonly MAX_FRAGMENT_LAYERS = 75;\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 static _compositeAdditiveRenderStates: Nullable<RenderStateSet> = null;\r\n private static _ubAlignment = 0;\r\n private _nodeBuffer: Nullable<GPUDataBuffer>;\r\n private _headStagingBuffer: Nullable<GPUDataBuffer>;\r\n private _headBuffer: Nullable<GPUDataBuffer>;\r\n private _scissorOffsetBuffer: Nullable<GPUDataBuffer>;\r\n private readonly _numLayers: number;\r\n private _screenSize: Uint32Array<ArrayBuffer>;\r\n private _hash: Nullable<string>;\r\n private readonly _debug: boolean;\r\n private _scissorSlices: number;\r\n private _scissorHeight: number;\r\n private _currentPass: number;\r\n private _savedScissor: Nullable<DeviceViewport>;\r\n private _singleColorFramebuffer: Nullable<FrameBuffer>;\r\n /**\r\n * Creates an instance of ABufferOIT class\r\n *\r\n * @param numLayers - How many transparent layers, default is 16\r\n */\r\n constructor(numLayers = 16) {\r\n super();\r\n this._nodeBuffer = null;\r\n this._headStagingBuffer = null;\r\n this._headBuffer = null;\r\n this._scissorOffsetBuffer = null;\r\n this._numLayers = numLayers;\r\n this._screenSize = new Uint32Array([0xffffffff, 0xffffffff]);\r\n this._hash = null;\r\n this._debug = false;\r\n this._scissorSlices = 0;\r\n this._scissorHeight = 0;\r\n this._savedScissor = null;\r\n this._currentPass = 0;\r\n this._singleColorFramebuffer = null;\r\n }\r\n /**\r\n * {@inheritDoc OIT.getType}\r\n */\r\n getType() {\r\n return ABufferOIT.type;\r\n }\r\n /**\r\n * {@inheritDoc OIT.supportDevice}\r\n */\r\n supportDevice(deviceType: string) {\r\n return deviceType === 'webgpu';\r\n }\r\n /**\r\n * {@inheritDoc OIT.wantsPremultipliedAlpha}\r\n */\r\n wantsPremultipliedAlpha() {\r\n return ABufferOIT.usePremultipliedAlpha;\r\n }\r\n /**\r\n * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}\r\n */\r\n wantsAdditiveLightPassAlpha() {\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc OIT.begin}\r\n */\r\n begin(ctx: DrawContext) {\r\n const device = ctx.device;\r\n this._savedScissor = device.getScissor();\r\n const ubAlignment = (ABufferOIT._ubAlignment =\r\n device.getDeviceCaps().shaderCaps.uniformBufferOffsetAlignment);\r\n const viewport = device.getViewport();\r\n const screenWidth = device.screenXToDevice(viewport.width);\r\n const screenHeight = device.screenYToDevice(Math.max(viewport.height, 1));\r\n if (screenWidth !== this._screenSize[0] || screenHeight !== this._screenSize[1]) {\r\n // Mark uniform changed\r\n this.uniformChanged();\r\n // Resize buffers if viewport was changed\r\n this._screenSize[0] = screenWidth;\r\n this._screenSize[1] = screenHeight;\r\n // compute scissor slices\r\n const maxBufferSize = device.getDeviceCaps().shaderCaps.maxStorageBufferSize;\r\n const bytesPerLine = screenWidth * 4 * 4 * this._numLayers;\r\n this._scissorHeight = (maxBufferSize / bytesPerLine) >> 0;\r\n this._scissorSlices = Math.ceil(screenHeight / this._scissorHeight);\r\n const offsetBufferSize = ubAlignment * this._scissorSlices;\r\n const offsetBuffer = new Uint32Array(offsetBufferSize >> 2);\r\n for (let i = 0; i < this._scissorSlices; i++) {\r\n offsetBuffer[i * (ubAlignment >> 2)] = i * this._scissorHeight;\r\n }\r\n if (!this._scissorOffsetBuffer || this._scissorOffsetBuffer.byteLength < offsetBuffer.byteLength) {\r\n this._scissorOffsetBuffer?.dispose();\r\n this._scissorOffsetBuffer = device.createBuffer(offsetBuffer.byteLength, { usage: 'uniform' });\r\n }\r\n this._scissorOffsetBuffer.bufferSubData(0, offsetBuffer);\r\n // resize node buffer\r\n const size = screenWidth * this._scissorHeight * 4;\r\n const nodeBufferSize = size * 4 * this._numLayers;\r\n if (!this._nodeBuffer || nodeBufferSize > this._nodeBuffer.byteLength) {\r\n this._nodeBuffer?.dispose();\r\n this._nodeBuffer = device.createBuffer(nodeBufferSize, { storage: true, usage: 'uniform' });\r\n }\r\n // resize head buffer\r\n const headBufferSize = size + 4;\r\n if (!this._headBuffer || headBufferSize > this._headBuffer.byteLength) {\r\n this._headBuffer?.dispose();\r\n this._headBuffer = device.createBuffer(headBufferSize, { storage: true, usage: 'uniform' });\r\n this._headStagingBuffer?.dispose();\r\n this._headStagingBuffer = device.createBuffer(headBufferSize, { storage: true, usage: 'uniform' });\r\n const tmpArray = new Uint32Array(headBufferSize >> 2);\r\n tmpArray.fill(0xffffffff);\r\n this._headStagingBuffer.bufferSubData(0, tmpArray);\r\n }\r\n }\r\n return this._scissorSlices;\r\n }\r\n /**\r\n * {@inheritDoc OIT.end}\r\n */\r\n end(ctx: DrawContext) {\r\n // Restore scissor rect\r\n ctx.device.setScissor(this._savedScissor);\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.Z_AB_scissorOffset = pb.uint().uniformBuffer(2);\r\n scope.Z_AB_nodeBuffer = pb.uvec4[0]().storageBuffer(2);\r\n scope.Z_AB_headImage = pb.atomic_uint[0]().storageBuffer(2);\r\n scope.Z_AB_screenSize = pb.uint().uniform(2);\r\n // Read with textureLoad only\r\n scope.Z_AB_depthTexture = pb.tex2D().uniform(2).noSampler();\r\n scope.$outputs.outColor = pb.vec4();\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 device = ctx.device;\r\n const currentFramebuffer = device.getFramebuffer();\r\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\r\n this._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 (this._singleColorFramebuffer) {\r\n const viewport = device.getViewport();\r\n const scissor = device.getScissor();\r\n device.pushDeviceStates();\r\n device.setFramebuffer(this._singleColorFramebuffer);\r\n device.setViewport(viewport);\r\n device.setScissor(scissor);\r\n }\r\n const scissorY = pass * this._scissorHeight;\r\n const scissorH =\r\n Math.min((pass + 1) * this._scissorHeight, this._screenSize[1]) - pass * this._scissorHeight;\r\n device.setScissor([\r\n 0,\r\n device.deviceYToScreen(this._screenSize[1] - scissorY - scissorH),\r\n device.deviceXToScreen(this._screenSize[0]),\r\n device.deviceYToScreen(scissorH)\r\n ]);\r\n device.copyBuffer(this._headStagingBuffer!, this._headBuffer!, 0, 0, this._headStagingBuffer!.byteLength);\r\n // Update render hash\r\n this._hash = `${this.getType()}#${this._nodeBuffer!.uid}#${this._headBuffer!.uid}#${\r\n this._scissorOffsetBuffer!.uid\r\n }#${pass}`;\r\n if (this._debug) {\r\n const data = new Uint8Array(this._headBuffer!.byteLength);\r\n const readBuffer = device.createBuffer(this._headBuffer!.byteLength, { usage: 'read' });\r\n device.copyBuffer(this._headBuffer!, readBuffer, 0, 0, this._headBuffer!.byteLength);\r\n readBuffer.getBufferSubData(data).then(() => {\r\n const uint = new Uint32Array(data.buffer);\r\n for (let i = 0; i < uint.length; i++) {\r\n if (uint[i] !== 0xffffffff) {\r\n console.error('Clear head buffer failed');\r\n break;\r\n }\r\n }\r\n readBuffer.dispose();\r\n });\r\n }\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc OIT.endPass}\r\n */\r\n endPass(ctx: DrawContext, pass: number) {\r\n const device = ctx.device;\r\n ABufferOIT.getCompositeProgram(device);\r\n const lastBindGroup = device.getBindGroup(0);\r\n const currentFramebuffer = device.getFramebuffer();\r\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\r\n const singleColorFramebuffer =\r\n !this._singleColorFramebuffer &&\r\n currentFramebuffer &&\r\n currentFramebuffer.getColorAttachments().length > 1 &&\r\n 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(ABufferOIT.getCompositeProgram(device));\r\n const bindGroup = ABufferOIT._compositeBindGroup!;\r\n bindGroup.setBuffer(\r\n 'scissorOffset',\r\n this._scissorOffsetBuffer!,\r\n 0,\r\n pass * ABufferOIT._ubAlignment,\r\n ABufferOIT._ubAlignment\r\n );\r\n bindGroup.setBuffer('headBuffer', this._headBuffer!);\r\n bindGroup.setBuffer('nodeBuffer', this._nodeBuffer!);\r\n bindGroup.setValue('screenWidth', this._screenSize[0]);\r\n bindGroup.setValue('additiveOnly', ctx.lightBlending ? 1 : 0);\r\n device.setBindGroup(0, bindGroup);\r\n drawFullscreenQuad(\r\n ctx.lightBlending ? ABufferOIT._compositeAdditiveRenderStates! : ABufferOIT._compositeRenderStates!\r\n );\r\n } finally {\r\n if (singleColorFramebuffer) {\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(singleColorFramebuffer);\r\n } else if (this._singleColorFramebuffer) {\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(this._singleColorFramebuffer);\r\n this._singleColorFramebuffer = null;\r\n } else {\r\n device.setBindGroup(0, lastBindGroup[0], lastBindGroup[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 * {@inheritDoc OIT.applyUniforms}\r\n */\r\n applyUniforms(ctx: DrawContext, bindGroup: BindGroup) {\r\n bindGroup.setBuffer('Z_AB_nodeBuffer', this._nodeBuffer!);\r\n bindGroup.setBuffer(\r\n 'Z_AB_scissorOffset',\r\n this._scissorOffsetBuffer!,\r\n 0,\r\n this._currentPass * ABufferOIT._ubAlignment,\r\n ABufferOIT._ubAlignment\r\n );\r\n bindGroup.setBuffer('Z_AB_headImage', this._headBuffer!);\r\n bindGroup.setValue('Z_AB_screenSize', this._screenSize[0]);\r\n bindGroup.setTexture('Z_AB_depthTexture', ctx.linearDepthTexture!);\r\n }\r\n /**\r\n * {@inheritDoc OIT.outputFragmentColor}\r\n */\r\n outputFragmentColor(scope: PBInsideFunctionScope, color: PBShaderExp) {\r\n const pb = scope.$builder;\r\n // linear depth of current fragment\r\n scope.$l.fragDepth = ShaderHelper.nonLinearDepthToLinearNormalized(scope, scope.$builtins.fragCoord.z);\r\n // linear depth in depth texture\r\n scope.$l.linearDepth = pb.textureLoad(\r\n scope.Z_AB_depthTexture,\r\n pb.ivec2(scope.$builtins.fragCoord.xy),\r\n 0\r\n ).r;\r\n // saved to buffer only if nothing is infront\r\n scope.$if(pb.lessThan(scope.fragDepth, scope.linearDepth), function () {\r\n this.$l.Z_AB_pixelCount = pb.atomicAdd(this.Z_AB_headImage.at(0), 1);\r\n this.$l.Z_AB_nodeOffset = this.Z_AB_pixelCount;\r\n // save if index not exceeded\r\n this.$if(pb.lessThan(this.Z_AB_nodeOffset, pb.arrayLength(this.Z_AB_nodeBuffer)), function () {\r\n this.$l.Z_AB_headOffset = pb.add(\r\n pb.mul(this.Z_AB_screenSize, pb.sub(pb.uint(this.$builtins.fragCoord.y), this.Z_AB_scissorOffset)),\r\n pb.uint(this.$builtins.fragCoord.x)\r\n );\r\n this.$l.Z_AB_oldHead = pb.atomicExchange(\r\n this.Z_AB_headImage.at(pb.add(this.Z_AB_headOffset, 1)),\r\n this.Z_AB_nodeOffset\r\n );\r\n this.$l.Z_AB_colorScale = pb.floatBitsToUint(pb.length(color.rgb));\r\n this.$l.Z_AB_color = pb.pack4x8unorm(pb.vec4(pb.normalize(color.rgb), pb.clamp(color.a, 0, 1)));\r\n this.$l.Z_AB_depth = pb.floatBitsToUint(this.fragDepth);\r\n this.Z_AB_nodeBuffer.setAt(\r\n this.Z_AB_nodeOffset,\r\n pb.uvec4(this.Z_AB_color, this.Z_AB_colorScale, this.Z_AB_depth, this.Z_AB_oldHead)\r\n );\r\n pb.discard();\r\n });\r\n });\r\n return true;\r\n }\r\n /**\r\n * {@inheritDoc OIT.setRenderStates}\r\n */\r\n setRenderStates(rs: RenderStateSet) {\r\n const stencilStates = rs.useStencilState();\r\n stencilStates.enable(true);\r\n stencilStates.setFrontCompareFunc('always');\r\n stencilStates.setBackCompareFunc('always');\r\n stencilStates.setFrontOp('keep', 'keep', 'replace');\r\n stencilStates.setBackOp('keep', 'keep', 'replace');\r\n stencilStates.setReference(1);\r\n stencilStates.setReadMask(0xff);\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, DEPTH_FARTHEST, 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.scissorOffset = pb.uint().uniformBuffer(0);\r\n this.headBuffer = pb.uint[0]().storageBuffer(0);\r\n this.nodeBuffer = pb.uvec4[0]().storageBuffer(0);\r\n this.screenWidth = pb.uint().uniform(0);\r\n this.additiveOnly = pb.int().uniform(0);\r\n pb.func('unpackColor', [pb.uvec4('x')], function () {\r\n this.$l.colorNorm = pb.unpack4x8unorm(this.x.x);\r\n this.$l.colorScale = pb.uintBitsToFloat(this.x.y);\r\n this.$return(pb.vec4(pb.mul(this.colorNorm.rgb, this.colorScale), this.colorNorm.a));\r\n });\r\n pb.main(function () {\r\n this.$l.fragmentArray = pb.uvec4[ABufferOIT.MAX_FRAGMENT_LAYERS]();\r\n this.$l.fragmentArrayLen = pb.uint(0);\r\n this.$l.offset = pb.add(\r\n pb.mul(this.screenWidth, pb.sub(pb.uint(this.$builtins.fragCoord.y), this.scissorOffset)),\r\n pb.uint(this.$builtins.fragCoord.x)\r\n );\r\n //this.$l.head = this.headBuffer.at(this.offset);\r\n this.$l.head = this.headBuffer.at(pb.add(this.offset, 1));\r\n this.$while(\r\n pb.and(\r\n pb.lessThan(this.fragmentArrayLen, ABufferOIT.MAX_FRAGMENT_LAYERS),\r\n pb.notEqual(this.head, 0xffffffff)\r\n ),\r\n function () {\r\n this.fragmentArray.setAt(this.fragmentArrayLen, this.nodeBuffer.at(this.head));\r\n this.head = this.fragmentArray.at(this.fragmentArrayLen).w;\r\n this.fragmentArrayLen = pb.add(this.fragmentArrayLen, 1);\r\n }\r\n );\r\n this.$if(pb.equal(this.fragmentArrayLen, 0), function () {\r\n this.$outputs.outColor = pb.vec4(0, 0, 0, 1);\r\n }).$else(function () {\r\n // bubble sort\r\n this.$for(pb.uint('i'), 0, pb.sub(this.fragmentArrayLen, 1), function () {\r\n this.$for(pb.uint('j'), 0, pb.sub(pb.sub(this.fragmentArrayLen, 1), this.i), function () {\r\n this.$l.a = this.fragmentArray.at(this.j);\r\n this.$l.b = this.fragmentArray.at(pb.add(this.j, 1));\r\n this.$if(pb.greaterThan(this.a.z, this.b.z), function () {\r\n this.fragmentArray.setAt(this.j, this.b);\r\n this.fragmentArray.setAt(pb.add(this.j, 1), this.a);\r\n });\r\n });\r\n });\r\n // under operator blending\r\n this.$l.c0 = this.unpackColor(this.fragmentArray[0]);\r\n this.$l.c_dst = ABufferOIT.usePremultipliedAlpha ? this.c0.rgb : pb.mul(this.c0.rgb, this.c0.a);\r\n this.$l.a_dst = pb.sub(1, this.c0.a);\r\n this.$for(pb.uint('i'), 1, this.fragmentArrayLen, function () {\r\n this.$l.c = this.unpackColor(this.fragmentArray.at(this.i));\r\n if (ABufferOIT.usePremultipliedAlpha) {\r\n this.c_dst = pb.add(this.c_dst, pb.mul(this.c.rgb, this.a_dst));\r\n } else {\r\n this.c_dst = pb.add(this.c_dst, pb.mul(this.c.rgb, this.c.a, this.a_dst));\r\n }\r\n this.a_dst = pb.mul(this.a_dst, pb.sub(1, this.c.a));\r\n });\r\n this.$outputs.outColor = pb.vec4(\r\n this.c_dst,\r\n pb.equal(this.additiveOnly, 0) ? this.a_dst : pb.float(0)\r\n );\r\n });\r\n });\r\n }\r\n })!;\r\n this._compositeProgram.name = '@ABufferOIT_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 this._compositeAdditiveRenderStates = device.createRenderStateSet();\r\n this._compositeAdditiveRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'one')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this._compositeAdditiveRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n const stencilStates = this._compositeRenderStates.useStencilState();\r\n stencilStates.enable(false);\r\n stencilStates.setFrontCompareFunc('always');\r\n stencilStates.setBackCompareFunc('always');\r\n stencilStates.setFrontOp('keep', 'keep', 'replace');\r\n stencilStates.setBackOp('keep', 'keep', 'replace');\r\n stencilStates.setReference(0);\r\n stencilStates.setReadMask(0xff);\r\n const additiveStencilStates = this._compositeAdditiveRenderStates.useStencilState();\r\n additiveStencilStates.enable(false);\r\n additiveStencilStates.setFrontCompareFunc('always');\r\n additiveStencilStates.setBackCompareFunc('always');\r\n additiveStencilStates.setFrontOp('keep', 'keep', 'replace');\r\n additiveStencilStates.setBackOp('keep', 'keep', 'replace');\r\n additiveStencilStates.setReference(0);\r\n additiveStencilStates.setReadMask(0xff);\r\n }\r\n return this._compositeProgram;\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this._nodeBuffer?.dispose();\r\n this._nodeBuffer = null;\r\n this._headStagingBuffer?.dispose();\r\n this._headStagingBuffer = null;\r\n this._headBuffer?.dispose();\r\n this._headBuffer = null;\r\n this._scissorOffsetBuffer?.dispose();\r\n this._scissorOffsetBuffer = null;\r\n this._hash = null;\r\n this._savedScissor = null;\r\n }\r\n}\r\n"],"names":["ABufferOIT","OIT","type","usePremultipliedAlpha","MAX_FRAGMENT_LAYERS","_compositeProgram","_compositeBindGroup","_compositeRenderStates","_compositeAdditiveRenderStates","_ubAlignment","_nodeBuffer","_headStagingBuffer","_headBuffer","_scissorOffsetBuffer","_numLayers","_screenSize","_hash","_debug","_scissorSlices","_scissorHeight","_currentPass","_savedScissor","_singleColorFramebuffer","numLayers","Uint32Array","getType","supportDevice","deviceType","wantsPremultipliedAlpha","wantsAdditiveLightPassAlpha","begin","ctx","device","getScissor","ubAlignment","getDeviceCaps","shaderCaps","uniformBufferOffsetAlignment","viewport","getViewport","screenWidth","screenXToDevice","width","screenHeight","screenYToDevice","Math","max","height","uniformChanged","maxBufferSize","maxStorageBufferSize","bytesPerLine","ceil","offsetBufferSize","offsetBuffer","i","byteLength","dispose","createBuffer","usage","bufferSubData","size","nodeBufferSize","storage","headBufferSize","tmpArray","fill","end","setScissor","setupFragmentOutput","scope","pb","$builder","Z_AB_scissorOffset","uint","uniformBuffer","Z_AB_nodeBuffer","uvec4","storageBuffer","Z_AB_headImage","atomic_uint","Z_AB_screenSize","uniform","Z_AB_depthTexture","tex2D","noSampler","$outputs","outColor","vec4","beginPass","pass","currentFramebuffer","getFramebuffer","colorAttachment","getColorAttachments","length","pool","fetchTemporalFramebuffer","getDepthAttachment","scissor","pushDeviceStates","setFramebuffer","setViewport","scissorY","scissorH","min","deviceYToScreen","deviceXToScreen","copyBuffer","uid","data","Uint8Array","readBuffer","getBufferSubData","then","buffer","console","error","endPass","getCompositeProgram","lastBindGroup","getBindGroup","singleColorFramebuffer","setProgram","bindGroup","setBuffer","setValue","lightBlending","setBindGroup","drawFullscreenQuad","popDeviceStates","releaseFrameBuffer","calculateHash","applyUniforms","setTexture","linearDepthTexture","outputFragmentColor","color","$l","fragDepth","ShaderHelper","nonLinearDepthToLinearNormalized","$builtins","fragCoord","z","linearDepth","textureLoad","ivec2","xy","r","$if","lessThan","Z_AB_pixelCount","atomicAdd","at","Z_AB_nodeOffset","arrayLength","Z_AB_headOffset","add","mul","sub","y","x","Z_AB_oldHead","atomicExchange","Z_AB_colorScale","floatBitsToUint","rgb","Z_AB_color","pack4x8unorm","normalize","clamp","a","Z_AB_depth","setAt","discard","setRenderStates","rs","stencilStates","useStencilState","enable","setFrontCompareFunc","setBackCompareFunc","setFrontOp","setBackOp","setReference","setReadMask","buildRenderProgram","vertex","$inputs","pos","vec2","attrib","uv","main","position","DEPTH_FARTHEST","neg","fragment","scissorOffset","headBuffer","nodeBuffer","additiveOnly","int","func","colorNorm","unpack4x8unorm","colorScale","uintBitsToFloat","$return","fragmentArray","fragmentArrayLen","offset","head","$while","and","notEqual","w","equal","$else","$for","j","b","greaterThan","c0","unpackColor","c_dst","a_dst","c","float","name","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","additiveStencilStates","onDispose"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AABB, Vector3, Disposable, Matrix4x4, ClipState, Vector2 } from '@zephyr3d/base';
1
+ import { AABB, Vector3, BoxSide, Disposable, Matrix4x4, ClipState, Vector2 } from '@zephyr3d/base';
2
2
  import { Primitive } from './primitive.js';
3
3
  import { getVertexAttributeIndex, VERTEX_ATTRIB_POSITION, VERTEX_ATTRIB_TEXCOORD0, getVertexAttributeFormat } from '@zephyr3d/device';
4
4
 
@@ -10,6 +10,10 @@ const rotationValues = [
10
10
  Math.PI * 0.5,
11
11
  Math.PI
12
12
  ];
13
+ /**
14
+ * Frustum plane mask covering everything but the far plane, for a clipmap that
15
+ * reaches past it. @internal
16
+ */ const ALL_PLANES_EXCEPT_FAR = 0b111111 & ~(1 << BoxSide.BACK);
13
17
  /** @internal */ class Clipmap extends Disposable {
14
18
  _instanceDataPool;
15
19
  _instanceDataPoolSize;
@@ -37,6 +41,8 @@ const rotationValues = [
37
41
  _seamMesh;
38
42
  _seamMeshLines;
39
43
  _seamMeshAABB;
44
+ _skirtMesh;
45
+ _skirtMeshLines;
40
46
  _wireframe;
41
47
  constructor(resolution, extraInstanceBuffers, maxMipLevels = 64){
42
48
  super();
@@ -60,6 +66,7 @@ const rotationValues = [
60
66
  this.generateSeamMesh();
61
67
  this.generateTileMesh();
62
68
  this.generateTrimMesh();
69
+ this.generateSkirtMesh();
63
70
  }
64
71
  get wireframe() {
65
72
  return this._wireframe;
@@ -78,6 +85,7 @@ const rotationValues = [
78
85
  this.generateSeamMesh();
79
86
  this.generateTileMesh();
80
87
  this.generateTrimMesh();
88
+ this.generateSkirtMesh();
81
89
  }
82
90
  }
83
91
  allocInstanceBuffer() {
@@ -533,6 +541,112 @@ const rotationValues = [
533
541
  this._seamMeshLines.indexCount = indicesLines.length;
534
542
  this._seamMeshLines.primitiveType = 'line-list';
535
543
  }
544
+ /**
545
+ * Ring of quads welded to the outer boundary of the outermost level, whose
546
+ * outer edge the vertex shader is expected to push towards the horizon.
547
+ *
548
+ * The inner edge has to land on exactly the vertices the outermost tiles end
549
+ * on, or a displaced surface tears along the join: both sides evaluate the
550
+ * same wave function, so identical world positions are what keeps them
551
+ * identical. That boundary runs from `-2 * tileResolution` to
552
+ * `2 * tileResolution + 1` in the level's local units - the asymmetry is the
553
+ * `fillX`/`fillY` shift `gather` applies to the far tiles - which is
554
+ * `clipmapVertResolution` vertices a side, the same density the seam mesh
555
+ * uses.
556
+ *
557
+ * Outer vertices are flagged with `position.z = 1`. Every other clipmap mesh
558
+ * leaves z at 0 and the shader's clipmap matrix only reads xy, so the
559
+ * component is free to carry the flag without a second vertex stream.
560
+ */ generateSkirtMesh() {
561
+ const clipmapVertResolution = this._tileResolution * 4 + 2;
562
+ const lo = -2 * this._tileResolution;
563
+ const hi = 2 * this._tileResolution + 1;
564
+ // Unique positions around the perimeter: each side contributes all but its
565
+ // last vertex, which is the next side's first, so the loop closes without
566
+ // doubling the corners.
567
+ const perSide = clipmapVertResolution - 1;
568
+ const ringCount = perSide * 4;
569
+ const vertices = new Float32Array(ringCount * 2 * 3);
570
+ // Placeholder extent for the outer ring. The vertex shader relocates these
571
+ // vertices, so this only has to be outside the inner ring and finite.
572
+ const outerFactor = 8;
573
+ const centre = (lo + hi) * 0.5;
574
+ let n = 0;
575
+ const putRing = (index, x, y, outer)=>{
576
+ const px = outer ? centre + (x - centre) * outerFactor : x;
577
+ const py = outer ? centre + (y - centre) * outerFactor : y;
578
+ const base = (index + (outer ? ringCount : 0)) * 3;
579
+ vertices[base + 0] = px;
580
+ vertices[base + 1] = py;
581
+ vertices[base + 2] = outer ? 1 : 0;
582
+ };
583
+ for(let i = 0; i < perSide; i++){
584
+ putRing(n, lo + i, lo, false);
585
+ putRing(n, lo + i, lo, true);
586
+ n++;
587
+ }
588
+ for(let i = 0; i < perSide; i++){
589
+ putRing(n, hi, lo + i, false);
590
+ putRing(n, hi, lo + i, true);
591
+ n++;
592
+ }
593
+ for(let i = 0; i < perSide; i++){
594
+ putRing(n, hi - i, hi, false);
595
+ putRing(n, hi - i, hi, true);
596
+ n++;
597
+ }
598
+ for(let i = 0; i < perSide; i++){
599
+ putRing(n, lo, hi - i, false);
600
+ putRing(n, lo, hi - i, true);
601
+ n++;
602
+ }
603
+ const indices = new Uint16Array(ringCount * 6);
604
+ n = 0;
605
+ for(let k = 0; k < ringCount; k++){
606
+ const j = (k + 1) % ringCount;
607
+ indices[n++] = k;
608
+ indices[n++] = j;
609
+ indices[n++] = ringCount + j;
610
+ indices[n++] = k;
611
+ indices[n++] = ringCount + j;
612
+ indices[n++] = ringCount + k;
613
+ }
614
+ this._skirtMesh?.dispose();
615
+ this._skirtMesh = new Primitive();
616
+ this._skirtMesh.createAndSetVertexBuffer('position_f32x3', vertices);
617
+ this._skirtMesh.createAndSetVertexBuffer('tex0_f32x4', this.allocNonInstanceBuffer(0, 0, 0, 0), 'instance');
618
+ this._nonInstanceDataPoolSize++;
619
+ for (const fmt of this._extraInstanceBuffers){
620
+ this._skirtMesh.createAndSetVertexBuffer(fmt, this.allocNonInstanceBuffer(0, 0, 0, 0), 'instance');
621
+ this._nonInstanceDataPoolSize++;
622
+ }
623
+ this._skirtMesh.createAndSetIndexBuffer(indices);
624
+ this._skirtMesh.indexStart = 0;
625
+ this._skirtMesh.indexCount = indices.length;
626
+ this._skirtMesh.primitiveType = 'triangle-list';
627
+ const indicesLines = new Uint16Array(indices.length * 2);
628
+ for(let i = 0; i < indices.length / 3; i++){
629
+ indicesLines[i * 6 + 0] = indices[i * 3 + 0];
630
+ indicesLines[i * 6 + 1] = indices[i * 3 + 1];
631
+ indicesLines[i * 6 + 2] = indices[i * 3 + 1];
632
+ indicesLines[i * 6 + 3] = indices[i * 3 + 2];
633
+ indicesLines[i * 6 + 4] = indices[i * 3 + 2];
634
+ indicesLines[i * 6 + 5] = indices[i * 3 + 0];
635
+ }
636
+ this._skirtMeshLines?.dispose();
637
+ this._skirtMeshLines = new Primitive();
638
+ this._skirtMeshLines.setVertexBuffer(this._skirtMesh.getVertexBuffer('position'));
639
+ this._skirtMeshLines.createAndSetVertexBuffer('tex0_f32x4', this.allocNonInstanceBuffer(0, 0, 0, 0), 'instance');
640
+ this._nonInstanceDataPoolSize++;
641
+ for (const fmt of this._extraInstanceBuffers){
642
+ this._skirtMeshLines.createAndSetVertexBuffer(fmt, this.allocNonInstanceBuffer(0, 0, 0, 0), 'instance');
643
+ this._nonInstanceDataPoolSize++;
644
+ }
645
+ this._skirtMeshLines.createAndSetIndexBuffer(indicesLines);
646
+ this._skirtMeshLines.indexStart = 0;
647
+ this._skirtMeshLines.indexCount = indicesLines.length;
648
+ this._skirtMeshLines.primitiveType = 'line-list';
649
+ }
536
650
  intervalsOverlap(a0, a1, b0, b1) {
537
651
  return a0 <= b1 && b0 <= a1;
538
652
  }
@@ -572,6 +686,14 @@ const rotationValues = [
572
686
  const minZ = (tmpAABB.minPoint.y * scale + offset.y) * gridScale;
573
687
  const maxZ = (tmpAABB.maxPoint.y * scale + offset.y) * gridScale;
574
688
  ctx.calcAABB(ctx.userData, minX, maxX, minZ, maxZ, tmpAABB, level);
689
+ if (ctx.skirt) {
690
+ // Every plane except the far one. A skirted clipmap deliberately reaches
691
+ // past the far plane and pins the depth of whatever lands beyond it, so
692
+ // culling against that plane here would throw away exactly the tiles the
693
+ // skirt is there to lead up to - leaving a gap between the last surviving
694
+ // tile and the ring, with the sky showing through it.
695
+ return tmpAABB.getClipStateWithFrustumMask(camera.frustum, ALL_PLANES_EXCEPT_FAR) !== ClipState.NOT_CLIPPED;
696
+ }
575
697
  return tmpAABB.getClipStateWithFrustum(camera.frustum) !== ClipState.NOT_CLIPPED;
576
698
  }
577
699
  calcLevelAABB(camera, minMaxWorldPos, gridScale) {
@@ -627,11 +749,16 @@ const rotationValues = [
627
749
  }
628
750
  return outAABB;
629
751
  }
630
- calcMipLevels(camera, minMaxWorldPos, gridScale) {
752
+ calcMipLevels(camera, minMaxWorldPos, gridScale, viewDistance) {
631
753
  camera.getWorldPosition(tmpV3);
632
754
  const distX = Math.max(Math.abs(tmpV3.x - minMaxWorldPos.x), Math.abs(tmpV3.x - minMaxWorldPos.z));
633
755
  const distY = Math.max(Math.abs(tmpV3.z - minMaxWorldPos.y), Math.abs(tmpV3.z - minMaxWorldPos.w));
634
- const maxDist = Math.min(Math.max(distX, distY), camera.getFarPlane());
756
+ // The reach is the caller's when it supplies one; the far plane is only the
757
+ // default. An infinite water surface draws its horizon ring beyond the far
758
+ // plane and clamps the depth in the vertex shader, so capping the levels
759
+ // here would starve it of the very tiles it needs.
760
+ const maxReach = viewDistance && viewDistance > 0 ? viewDistance : camera.getFarPlane();
761
+ const maxDist = Math.min(Math.max(distX, distY), maxReach);
635
762
  return Math.min(Math.max(Math.ceil(Math.log2(maxDist / (this._tileResolution * gridScale))), 0) + 1, this._maxMipLevels);
636
763
  }
637
764
  addInstance(info, rotation, offsetX, offsetY, scale, mipLevel) {
@@ -649,7 +776,7 @@ const rotationValues = [
649
776
  this._nonInstanceDataPoolSize = this._nonInstanceDataPool.length;
650
777
  this._nonInstanceMipLevelDataPoolSize = this._nonInstanceMipLevelDataPool.length;
651
778
  const renderData = [];
652
- const mipLevels = this.calcMipLevels(context.camera, context.minMaxWorldPos, context.gridScale);
779
+ const mipLevels = this.calcMipLevels(context.camera, context.minMaxWorldPos, context.gridScale, context.viewDistance);
653
780
  context.camera.getWorldPosition(tmpV3);
654
781
  const snappedPos = new Vector2();
655
782
  const tileSize = new Vector2();
@@ -711,7 +838,13 @@ const rotationValues = [
711
838
  const fillX = x >= 2 ? scale : 0;
712
839
  const fillY = y >= 2 ? scale : 0;
713
840
  offset.setXY(base.x + x * tileSize.x + fillX, base.y + y * tileSize.y + fillY);
714
- if (this.intervalsOverlap(offset.x * context.gridScale, (offset.x + tileSize.x) * context.gridScale, context.minMaxWorldPos.x, context.minMaxWorldPos.z) && this.intervalsOverlap(offset.y * context.gridScale, (offset.y + tileSize.y) * context.gridScale, context.minMaxWorldPos.y, context.minMaxWorldPos.w)) {
841
+ if (// An unbounded surface has no rectangle to keep tiles inside of.
842
+ // Passing a very large one instead does not work: the clipmap's
843
+ // outermost level reaches 2 * tileResolution << (levels - 1), which
844
+ // at a raised camera is tens of kilometres and outgrows any sentinel
845
+ // rectangle - dropping the outer tiles and opening a band of sky
846
+ // between the last one drawn and the horizon skirt.
847
+ context.skirt || this.intervalsOverlap(offset.x * context.gridScale, (offset.x + tileSize.x) * context.gridScale, context.minMaxWorldPos.x, context.minMaxWorldPos.z) && this.intervalsOverlap(offset.y * context.gridScale, (offset.y + tileSize.y) * context.gridScale, context.minMaxWorldPos.y, context.minMaxWorldPos.w)) {
715
848
  if (!context.frustumCulling || this.visible(context, this._tileMeshBBox, context.camera, null, offset, scale, context.gridScale, l)) {
716
849
  this.addInstance(tilePrimitives, rotationValues[0], offset.x, offset.y, scale, l);
717
850
  }
@@ -753,6 +886,22 @@ const rotationValues = [
753
886
  if (seamPrimitives.numInstances > 0) {
754
887
  renderData.push(seamPrimitives);
755
888
  }
889
+ if (context.skirt) {
890
+ // Welded to the outer boundary of the outermost level, so it carries that
891
+ // level's scale and snapped origin. Never frustum-culled: the ring spans
892
+ // the whole horizon, and its outer edge is relocated by the vertex shader,
893
+ // so the AABB tested here would not describe where it actually lands.
894
+ const outerLevel = mipLevels - 1;
895
+ const outerScale = 1 << outerLevel;
896
+ snappedPos.setXY(Math.floor(posX / outerScale) * outerScale, Math.floor(posY / outerScale) * outerScale);
897
+ renderData.push({
898
+ primitive: this._wireframe ? this._skirtMeshLines : this._skirtMesh,
899
+ numInstances: 1,
900
+ instanceDatas: this.allocNonInstanceBuffer(rotationValues[0], outerScale, snappedPos.x, snappedPos.y),
901
+ mipLevels: this.allocNonInstanceMipLevelBuffer(outerLevel),
902
+ maxMiplevel: outerLevel
903
+ });
904
+ }
756
905
  for (const info of renderData){
757
906
  info.primitive.getVertexBuffer('texCoord0').bufferSubData(0, info.instanceDatas, 0, info.numInstances * 4);
758
907
  }
@@ -770,6 +919,8 @@ const rotationValues = [
770
919
  this._trimMeshLines.dispose();
771
920
  this._tileMesh.dispose();
772
921
  this._tileMeshLines.dispose();
922
+ this._skirtMesh.dispose();
923
+ this._skirtMeshLines.dispose();
773
924
  }
774
925
  }
775
926