react-native-wgpu 0.2.10 → 0.3.0

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 (248) hide show
  1. package/README.md +155 -69
  2. package/android/CMakeLists.txt +4 -5
  3. package/android/build.gradle +7 -18
  4. package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +34 -10
  5. package/apple/MetalView.mm +0 -19
  6. package/apple/WebGPUModule.h +1 -9
  7. package/apple/WebGPUModule.mm +0 -3
  8. package/apple/WebGPUView.h +0 -3
  9. package/apple/WebGPUView.mm +0 -2
  10. package/cpp/WGPULogger.h +10 -0
  11. package/cpp/dawn/dawn_proc_table.h +1 -1
  12. package/cpp/dawn/webgpu.h +4855 -0
  13. package/cpp/dawn/webgpu_cpp.h +10168 -0
  14. package/cpp/dawn/wire/client/webgpu.h +354 -0
  15. package/cpp/dawn/wire/client/webgpu_cpp.h +10343 -0
  16. package/cpp/dawn/wire/client/webgpu_cpp_print.h +2715 -0
  17. package/cpp/jsi/RNFJSIConverter.h +17 -59
  18. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
  19. package/cpp/rnwgpu/api/GPU.cpp +51 -26
  20. package/cpp/rnwgpu/api/GPU.h +5 -18
  21. package/cpp/rnwgpu/api/GPUAdapter.cpp +75 -54
  22. package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
  23. package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
  24. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
  25. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
  26. package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
  27. package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
  28. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
  29. package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
  30. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
  31. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
  32. package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
  33. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
  34. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
  35. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
  36. package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
  37. package/cpp/rnwgpu/api/GPUDevice.h +22 -21
  38. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
  39. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
  40. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
  41. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
  42. package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
  43. package/cpp/rnwgpu/api/GPUQueue.h +7 -6
  44. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
  45. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
  46. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
  47. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
  48. package/cpp/rnwgpu/api/GPUSampler.h +1 -3
  49. package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
  50. package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
  51. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
  52. package/cpp/rnwgpu/api/GPUTexture.h +1 -3
  53. package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
  54. package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
  55. package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
  56. package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
  57. package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
  58. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
  59. package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
  60. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
  61. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
  62. package/cpp/webgpu/webgpu.h +5 -4827
  63. package/cpp/webgpu/webgpu_cpp.h +5 -10140
  64. package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
  65. package/lib/commonjs/Canvas.js +6 -66
  66. package/lib/commonjs/Canvas.js.map +1 -1
  67. package/lib/commonjs/hooks.js +6 -42
  68. package/lib/commonjs/hooks.js.map +1 -1
  69. package/lib/module/Canvas.js +7 -67
  70. package/lib/module/Canvas.js.map +1 -1
  71. package/lib/module/hooks.js +5 -40
  72. package/lib/module/hooks.js.map +1 -1
  73. package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
  74. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  75. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  76. package/lib/typescript/lib/module/hooks.d.ts +1 -5
  77. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  78. package/lib/typescript/src/Canvas.d.ts +0 -1
  79. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  80. package/lib/typescript/src/hooks.d.ts +2 -7
  81. package/lib/typescript/src/hooks.d.ts.map +1 -1
  82. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  83. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  84. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  85. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  86. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
  87. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  88. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  89. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  90. package/package.json +4 -3
  91. package/react-native-wgpu.podspec +12 -16
  92. package/src/Canvas.tsx +8 -69
  93. package/src/hooks.tsx +14 -48
  94. package/android/cpp/platform/ThreadUtils.cpp +0 -41
  95. package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
  96. package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
  97. package/apple/WebGPUViewManager.mm +0 -24
  98. package/apple/platform/ThreadUtils.cpp +0 -34
  99. package/cpp/dawn/dawn_proc.h +0 -50
  100. package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
  101. package/cpp/dawn/native/D3D11Backend.h +0 -77
  102. package/cpp/dawn/native/D3D12Backend.h +0 -68
  103. package/cpp/dawn/native/D3DBackend.h +0 -56
  104. package/cpp/dawn/native/MetalBackend.h +0 -56
  105. package/cpp/dawn/platform/DawnPlatform.h +0 -167
  106. package/cpp/dawn/platform/dawn_platform_export.h +0 -49
  107. package/cpp/platform/ThreadUtils.h +0 -30
  108. package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
  109. package/cpp/threading/CallInvokerDispatcher.h +0 -37
  110. package/cpp/threading/Dispatcher.cpp +0 -55
  111. package/cpp/threading/Dispatcher.h +0 -93
  112. package/cpp/threading/ThreadPool.cpp +0 -88
  113. package/cpp/threading/ThreadPool.h +0 -53
  114. package/cpp/webgpu/webgpu_glfw.h +0 -88
  115. package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
  116. package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
  117. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
  118. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
  119. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
  120. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
  121. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
  122. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
  123. package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
  124. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
  125. package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
  126. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
  127. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
  128. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
  129. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
  130. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
  131. package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
  132. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
  133. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
  134. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
  135. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
  136. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
  137. package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
  138. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
  139. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
  140. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
  141. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
  142. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
  143. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
  144. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
  145. package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
  146. package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
  147. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
  148. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
  149. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
  150. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
  151. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
  152. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
  153. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
  154. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
  155. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
  156. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
  157. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
  158. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
  159. package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
  160. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
  161. package/lib/typescript/src/__tests__/config.d.ts +0 -3
  162. package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
  163. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
  164. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
  165. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
  166. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
  167. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
  168. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
  169. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
  170. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
  171. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
  172. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
  173. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
  174. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
  175. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
  176. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
  177. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
  178. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
  179. package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
  180. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
  181. package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
  182. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
  183. package/lib/typescript/src/__tests__/setup.d.ts +0 -63
  184. package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
  185. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  186. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  187. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  188. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  189. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  190. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  191. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  192. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  193. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  194. package/libs/dawn.json +0 -4670
  195. package/src/__tests__/Alpha.spec.ts +0 -28
  196. package/src/__tests__/ArrayBuffer.spec.ts +0 -76
  197. package/src/__tests__/Buffer.spec.ts +0 -357
  198. package/src/__tests__/ComputeShader.spec.ts +0 -375
  199. package/src/__tests__/Constants.spec.ts +0 -89
  200. package/src/__tests__/Device.spec.ts +0 -84
  201. package/src/__tests__/ErrorScope.spec.ts +0 -92
  202. package/src/__tests__/ExternalTexture.spec.ts +0 -284
  203. package/src/__tests__/GPU.spec.ts +0 -272
  204. package/src/__tests__/ImageData.spec.ts +0 -26
  205. package/src/__tests__/Shaders.spec.ts +0 -232
  206. package/src/__tests__/Texture.spec.ts +0 -197
  207. package/src/__tests__/assets/Di-3d.png +0 -0
  208. package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
  209. package/src/__tests__/components/Wireframe/models.ts +0 -113
  210. package/src/__tests__/components/Wireframe/utils.ts +0 -22
  211. package/src/__tests__/components/cube.ts +0 -51
  212. package/src/__tests__/components/meshes/mesh.ts +0 -96
  213. package/src/__tests__/components/meshes/sphere.ts +0 -103
  214. package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
  215. package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
  216. package/src/__tests__/components/meshes/teapot.ts +0 -13
  217. package/src/__tests__/components/meshes/utils.ts +0 -235
  218. package/src/__tests__/components/triangle.ts +0 -17
  219. package/src/__tests__/config.ts +0 -2
  220. package/src/__tests__/demos/ABuffer.spec.ts +0 -890
  221. package/src/__tests__/demos/Blur.spec.ts +0 -398
  222. package/src/__tests__/demos/Cube.spec.ts +0 -929
  223. package/src/__tests__/demos/FractalCube.spec.ts +0 -240
  224. package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
  225. package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
  226. package/src/__tests__/demos/Triangle.spec.ts +0 -266
  227. package/src/__tests__/demos/Wireframe.spec.ts +0 -188
  228. package/src/__tests__/globalSetup.ts +0 -45
  229. package/src/__tests__/globalTeardown.ts +0 -11
  230. package/src/__tests__/setup.ts +0 -423
  231. package/src/__tests__/snapshots/abuffer.png +0 -0
  232. package/src/__tests__/snapshots/asteroid.png +0 -0
  233. package/src/__tests__/snapshots/blur.png +0 -0
  234. package/src/__tests__/snapshots/buffer.png +0 -0
  235. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  236. package/src/__tests__/snapshots/cube.png +0 -0
  237. package/src/__tests__/snapshots/f.png +0 -0
  238. package/src/__tests__/snapshots/f2.png +0 -0
  239. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  240. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  241. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  242. package/src/__tests__/snapshots/ref.png +0 -0
  243. package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
  244. package/src/__tests__/snapshots/texture.png +0 -0
  245. package/src/__tests__/snapshots/textured-cube.png +0 -0
  246. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  247. package/src/__tests__/snapshots/triangle.png +0 -0
  248. package/src/__tests__/snapshots/two-cube.png +0 -0
@@ -1,890 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
- import { checkImage, client, encodeImage } from "../setup";
3
- import { mesh as teapotMesh } from "../components/meshes/teapot";
4
-
5
- const opaque = /*wgsl*/ `struct Uniforms {
6
- modelViewProjectionMatrix: mat4x4f,
7
- };
8
-
9
- @binding(0) @group(0) var<uniform> uniforms: Uniforms;
10
-
11
- struct VertexOutput {
12
- @builtin(position) position: vec4f,
13
- @location(0) @interpolate(flat) instance: u32
14
- };
15
-
16
- @vertex
17
- fn main_vs(@location(0) position: vec4f, @builtin(instance_index) instance: u32) -> VertexOutput {
18
- var output: VertexOutput;
19
-
20
- // distribute instances into a staggered 4x4 grid
21
- const gridWidth = 125.0;
22
- const cellSize = gridWidth / 4.0;
23
- let row = instance / 2u;
24
- let col = instance % 2u;
25
-
26
- let xOffset = -gridWidth / 2.0 + cellSize / 2.0 + 2.0 * cellSize * f32(col) + f32(row % 2u != 0u) * cellSize;
27
- let zOffset = -gridWidth / 2.0 + cellSize / 2.0 + 2.0 + f32(row) * cellSize;
28
-
29
- let offsetPos = vec4(position.x + xOffset, position.y, position.z + zOffset, position.w);
30
-
31
- output.position = uniforms.modelViewProjectionMatrix * offsetPos;
32
- output.instance = instance;
33
- return output;
34
- }
35
-
36
- @fragment
37
- fn main_fs(@location(0) @interpolate(flat) instance: u32) -> @location(0) vec4f {
38
- const colors = array<vec3f,6>(
39
- vec3(1.0, 0.0, 0.0),
40
- vec3(0.0, 1.0, 0.0),
41
- vec3(0.0, 0.0, 1.0),
42
- vec3(1.0, 0.0, 1.0),
43
- vec3(1.0, 1.0, 0.0),
44
- vec3(0.0, 1.0, 1.0),
45
- );
46
-
47
- return vec4(colors[instance % 6u], 1.0);
48
- }
49
- `;
50
-
51
- const translucent = /*wgsl*/ `struct Uniforms {
52
- modelViewProjectionMatrix: mat4x4f,
53
- maxStorableFragments: u32,
54
- targetWidth: u32,
55
- };
56
-
57
- struct SliceInfo {
58
- sliceStartY: i32
59
- };
60
-
61
- struct Heads {
62
- numFragments: atomic<u32>,
63
- data: array<atomic<u32>>
64
- };
65
-
66
- struct LinkedListElement {
67
- color: vec4f,
68
- depth: f32,
69
- next: u32
70
- };
71
-
72
- struct LinkedList {
73
- data: array<LinkedListElement>
74
- };
75
-
76
- @binding(0) @group(0) var<uniform> uniforms: Uniforms;
77
- @binding(1) @group(0) var<storage, read_write> heads: Heads;
78
- @binding(2) @group(0) var<storage, read_write> linkedList: LinkedList;
79
- @binding(3) @group(0) var opaqueDepthTexture: texture_depth_2d;
80
- @binding(4) @group(0) var<uniform> sliceInfo: SliceInfo;
81
-
82
- struct VertexOutput {
83
- @builtin(position) position: vec4f,
84
- @location(0) @interpolate(flat) instance: u32
85
- };
86
-
87
- @vertex
88
- fn main_vs(@location(0) position: vec4f, @builtin(instance_index) instance: u32) -> VertexOutput {
89
- var output: VertexOutput;
90
-
91
- // distribute instances into a staggered 4x4 grid
92
- const gridWidth = 125.0;
93
- const cellSize = gridWidth / 4.0;
94
- let row = instance / 2u;
95
- let col = instance % 2u;
96
-
97
- let xOffset = -gridWidth / 2.0 + cellSize / 2.0 + 2.0 * cellSize * f32(col) + f32(row % 2u == 0u) * cellSize;
98
- let zOffset = -gridWidth / 2.0 + cellSize / 2.0 + 2.0 + f32(row) * cellSize;
99
-
100
- let offsetPos = vec4(position.x + xOffset, position.y, position.z + zOffset, position.w);
101
-
102
- output.position = uniforms.modelViewProjectionMatrix * offsetPos;
103
- output.instance = instance;
104
-
105
- return output;
106
- }
107
-
108
- @fragment
109
- fn main_fs(@builtin(position) position: vec4f, @location(0) @interpolate(flat) instance: u32) {
110
- const colors = array<vec3f,6>(
111
- vec3(1.0, 0.0, 0.0),
112
- vec3(0.0, 1.0, 0.0),
113
- vec3(0.0, 0.0, 1.0),
114
- vec3(1.0, 0.0, 1.0),
115
- vec3(1.0, 1.0, 0.0),
116
- vec3(0.0, 1.0, 1.0),
117
- );
118
-
119
- let fragCoords = vec2i(position.xy);
120
- let opaqueDepth = textureLoad(opaqueDepthTexture, fragCoords, 0);
121
-
122
- // reject fragments behind opaque objects
123
- if position.z >= opaqueDepth {
124
- discard;
125
- }
126
-
127
- // The index in the heads buffer corresponding to the head data for the fragment at
128
- // the current location.
129
- let headsIndex = u32(fragCoords.y - sliceInfo.sliceStartY) * uniforms.targetWidth + u32(fragCoords.x);
130
-
131
- // The index in the linkedList buffer at which to store the new fragment
132
- let fragIndex = atomicAdd(&heads.numFragments, 1u);
133
-
134
- // If we run out of space to store the fragments, we just lose them
135
- if fragIndex < uniforms.maxStorableFragments {
136
- let lastHead = atomicExchange(&heads.data[headsIndex], fragIndex);
137
- linkedList.data[fragIndex].depth = position.z;
138
- linkedList.data[fragIndex].next = lastHead;
139
- linkedList.data[fragIndex].color = vec4(colors[(instance + 3u) % 6u], 0.3);
140
- }
141
- }
142
- `;
143
-
144
- const composite = /*wgsl*/ `struct Uniforms {
145
- modelViewProjectionMatrix: mat4x4f,
146
- maxStorableFragments: u32,
147
- targetWidth: u32,
148
- };
149
-
150
- struct SliceInfo {
151
- sliceStartY: i32
152
- };
153
-
154
- struct Heads {
155
- numFragments: u32,
156
- data: array<u32>
157
- };
158
-
159
- struct LinkedListElement {
160
- color: vec4f,
161
- depth: f32,
162
- next: u32
163
- };
164
-
165
- struct LinkedList {
166
- data: array<LinkedListElement>
167
- };
168
-
169
- @binding(0) @group(0) var<uniform> uniforms: Uniforms;
170
- @binding(1) @group(0) var<storage, read_write> heads: Heads;
171
- @binding(2) @group(0) var<storage, read_write> linkedList: LinkedList;
172
- @binding(3) @group(0) var<uniform> sliceInfo: SliceInfo;
173
-
174
- // Output a full screen quad
175
- @vertex
176
- fn main_vs(@builtin(vertex_index) vertIndex: u32) -> @builtin(position) vec4f {
177
- const position = array<vec2f, 6>(
178
- vec2(-1.0, -1.0),
179
- vec2(1.0, -1.0),
180
- vec2(1.0, 1.0),
181
- vec2(-1.0, -1.0),
182
- vec2(1.0, 1.0),
183
- vec2(-1.0, 1.0),
184
- );
185
-
186
- return vec4(position[vertIndex], 0.0, 1.0);
187
- }
188
-
189
- @fragment
190
- fn main_fs(@builtin(position) position: vec4f) -> @location(0) vec4f {
191
- let fragCoords = vec2i(position.xy);
192
- let headsIndex = u32(fragCoords.y - sliceInfo.sliceStartY) * uniforms.targetWidth + u32(fragCoords.x);
193
-
194
- // The maximum layers we can process for any pixel
195
- const maxLayers = 12u;
196
-
197
- var layers: array<LinkedListElement, maxLayers>;
198
-
199
- var numLayers = 0u;
200
- var elementIndex = heads.data[headsIndex];
201
-
202
- // copy the list elements into an array up to the maximum amount of layers
203
- while elementIndex != 0xFFFFFFFFu && numLayers < maxLayers {
204
- layers[numLayers] = linkedList.data[elementIndex];
205
- numLayers++;
206
- elementIndex = linkedList.data[elementIndex].next;
207
- }
208
-
209
- if numLayers == 0u {
210
- discard;
211
- }
212
-
213
- // sort the fragments by depth
214
- for (var i = 1u; i < numLayers; i++) {
215
- let toInsert = layers[i];
216
- var j = i;
217
-
218
- while j > 0u && toInsert.depth > layers[j - 1u].depth {
219
- layers[j] = layers[j - 1u];
220
- j--;
221
- }
222
-
223
- layers[j] = toInsert;
224
- }
225
-
226
- // pre-multiply alpha for the first layer
227
- var color = vec4(layers[0].color.a * layers[0].color.rgb, layers[0].color.a);
228
-
229
- // blend the remaining layers
230
- for (var i = 1u; i < numLayers; i++) {
231
- let mixed = mix(color.rgb, layers[i].color.rgb, layers[i].color.aaa);
232
- color = vec4(mixed, color.a);
233
- }
234
-
235
- return color;
236
- }`;
237
-
238
- describe("A Buffer", () => {
239
- it("draw scene", async () => {
240
- const result = await client.eval(
241
- ({
242
- ctx,
243
- device,
244
- gpu,
245
- mesh,
246
- opaqueWGSL,
247
- compositeWGSL,
248
- translucentWGSL,
249
- mat4,
250
- vec3,
251
- canvas,
252
- }) => {
253
- const presentationFormat = gpu.getPreferredCanvasFormat();
254
- const settings = {
255
- memoryStrategy: "multipass",
256
- };
257
-
258
- function roundUp(n: number, k: number): number {
259
- return Math.ceil(n / k) * k;
260
- }
261
-
262
- // Create the model vertex buffer
263
- const vertexBuffer = device.createBuffer({
264
- size: 3 * mesh.positions.length * Float32Array.BYTES_PER_ELEMENT,
265
- usage: GPUBufferUsage.VERTEX,
266
- mappedAtCreation: true,
267
- label: "vertexBuffer",
268
- });
269
- {
270
- const mapping = new Float32Array(vertexBuffer.getMappedRange());
271
- for (let i = 0; i < mesh.positions.length; ++i) {
272
- mapping.set(mesh.positions[i], 3 * i);
273
- }
274
- vertexBuffer.unmap();
275
- }
276
-
277
- // Create the model index buffer
278
- const indexCount = mesh.triangles.length * 3;
279
- const indexBuffer = device.createBuffer({
280
- size: indexCount * Uint16Array.BYTES_PER_ELEMENT,
281
- usage: GPUBufferUsage.INDEX,
282
- mappedAtCreation: true,
283
- label: "indexBuffer",
284
- });
285
- {
286
- const mapping = new Uint16Array(indexBuffer.getMappedRange());
287
- for (let i = 0; i < mesh.triangles.length; ++i) {
288
- mapping.set(mesh.triangles[i], 3 * i);
289
- }
290
- indexBuffer.unmap();
291
- }
292
-
293
- // Uniforms contains:
294
- // * modelViewProjectionMatrix: mat4x4f
295
- // * maxStorableFragments: u32
296
- // * targetWidth: u32
297
- const uniformsSize = roundUp(
298
- 16 * Float32Array.BYTES_PER_ELEMENT +
299
- 2 * Uint32Array.BYTES_PER_ELEMENT,
300
- 16,
301
- );
302
-
303
- const uniformBuffer = device.createBuffer({
304
- size: uniformsSize,
305
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
306
- label: "uniformBuffer",
307
- });
308
-
309
- const opaqueModule = device.createShaderModule({
310
- code: opaqueWGSL,
311
- label: "opaqueModule",
312
- });
313
-
314
- const opaquePipeline = device.createRenderPipeline({
315
- layout: "auto",
316
- vertex: {
317
- module: opaqueModule,
318
- buffers: [
319
- {
320
- arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,
321
- attributes: [
322
- {
323
- // position
324
- format: "float32x3",
325
- offset: 0,
326
- shaderLocation: 0,
327
- },
328
- ],
329
- },
330
- ],
331
- },
332
- fragment: {
333
- module: opaqueModule,
334
- targets: [
335
- {
336
- format: presentationFormat,
337
- },
338
- ],
339
- },
340
- primitive: {
341
- topology: "triangle-list",
342
- },
343
- depthStencil: {
344
- depthWriteEnabled: true,
345
- depthCompare: "less",
346
- format: "depth24plus",
347
- },
348
- label: "opaquePipeline",
349
- });
350
-
351
- const opaquePassDescriptor: GPURenderPassDescriptor = {
352
- // @ts-expect-error
353
- colorAttachments: [
354
- {
355
- view: undefined,
356
- clearValue: [0, 0, 0, 1.0],
357
- loadOp: "clear",
358
- storeOp: "store",
359
- },
360
- ],
361
- depthStencilAttachment: {
362
- // @ts-expect-error
363
- view: undefined,
364
- depthClearValue: 1.0,
365
- depthLoadOp: "clear",
366
- depthStoreOp: "store",
367
- },
368
- label: "opaquePassDescriptor",
369
- };
370
-
371
- const opaqueBindGroup = device.createBindGroup({
372
- layout: opaquePipeline.getBindGroupLayout(0),
373
- entries: [
374
- {
375
- binding: 0,
376
- resource: {
377
- buffer: uniformBuffer,
378
- size: 16 * Float32Array.BYTES_PER_ELEMENT,
379
- label: "modelViewProjection",
380
- },
381
- },
382
- ],
383
- label: "opaquePipeline",
384
- });
385
-
386
- const translucentModule = device.createShaderModule({
387
- code: translucentWGSL,
388
- label: "translucentModule",
389
- });
390
-
391
- const translucentBindGroupLayout = device.createBindGroupLayout({
392
- label: "translucentBindGroupLayout",
393
- entries: [
394
- {
395
- binding: 0,
396
- visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
397
- buffer: {
398
- type: "uniform",
399
- },
400
- },
401
- {
402
- binding: 1,
403
- visibility: GPUShaderStage.FRAGMENT,
404
- buffer: {
405
- type: "storage",
406
- },
407
- },
408
- {
409
- binding: 2,
410
- visibility: GPUShaderStage.FRAGMENT,
411
- buffer: {
412
- type: "storage",
413
- },
414
- },
415
- {
416
- binding: 3,
417
- visibility: GPUShaderStage.FRAGMENT,
418
- texture: { sampleType: "depth" },
419
- },
420
- {
421
- binding: 4,
422
- visibility: GPUShaderStage.FRAGMENT,
423
- buffer: {
424
- type: "uniform",
425
- hasDynamicOffset: true,
426
- },
427
- },
428
- ],
429
- });
430
-
431
- const translucentPipeline = device.createRenderPipeline({
432
- layout: device.createPipelineLayout({
433
- bindGroupLayouts: [translucentBindGroupLayout],
434
- label: "translucentPipelineLayout",
435
- }),
436
- vertex: {
437
- module: translucentModule,
438
- buffers: [
439
- {
440
- arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,
441
- attributes: [
442
- {
443
- format: "float32x3",
444
- offset: 0,
445
- shaderLocation: 0,
446
- },
447
- ],
448
- },
449
- ],
450
- },
451
- fragment: {
452
- module: translucentModule,
453
- targets: [
454
- {
455
- format: presentationFormat,
456
- writeMask: 0x0,
457
- },
458
- ],
459
- },
460
- primitive: {
461
- topology: "triangle-list",
462
- },
463
- label: "translucentPipeline",
464
- });
465
-
466
- const translucentPassDescriptor: GPURenderPassDescriptor = {
467
- // @ts-expect-error
468
- colorAttachments: [
469
- {
470
- loadOp: "load",
471
- storeOp: "store",
472
- view: undefined,
473
- },
474
- ],
475
- label: "translucentPassDescriptor",
476
- };
477
-
478
- const compositeModule = device.createShaderModule({
479
- code: compositeWGSL,
480
- label: "compositeModule",
481
- });
482
-
483
- const compositeBindGroupLayout = device.createBindGroupLayout({
484
- label: "compositeBindGroupLayout",
485
- entries: [
486
- {
487
- binding: 0,
488
- visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
489
- buffer: {
490
- type: "uniform",
491
- },
492
- },
493
- {
494
- binding: 1,
495
- visibility: GPUShaderStage.FRAGMENT,
496
- buffer: {
497
- type: "storage",
498
- },
499
- },
500
- {
501
- binding: 2,
502
- visibility: GPUShaderStage.FRAGMENT,
503
- buffer: {
504
- type: "storage",
505
- },
506
- },
507
- {
508
- binding: 3,
509
- visibility: GPUShaderStage.FRAGMENT,
510
- buffer: {
511
- type: "uniform",
512
- hasDynamicOffset: true,
513
- },
514
- },
515
- ],
516
- });
517
-
518
- const compositePipeline = device.createRenderPipeline({
519
- layout: device.createPipelineLayout({
520
- bindGroupLayouts: [compositeBindGroupLayout],
521
- label: "compositePipelineLayout",
522
- }),
523
- vertex: {
524
- module: compositeModule,
525
- },
526
- fragment: {
527
- module: compositeModule,
528
- targets: [
529
- {
530
- format: presentationFormat,
531
- blend: {
532
- color: {
533
- srcFactor: "one",
534
- operation: "add",
535
- dstFactor: "one-minus-src-alpha",
536
- },
537
- alpha: {},
538
- },
539
- },
540
- ],
541
- },
542
- primitive: {
543
- topology: "triangle-list",
544
- },
545
- label: "compositePipeline",
546
- });
547
-
548
- const compositePassDescriptor: GPURenderPassDescriptor = {
549
- // @ts-expect-error
550
- colorAttachments: [
551
- {
552
- view: undefined,
553
- loadOp: "load",
554
- storeOp: "store",
555
- },
556
- ],
557
- label: "compositePassDescriptor",
558
- };
559
-
560
- const configure = () => {
561
- // The default maximum storage buffer binding size is 128Mib. The amount
562
- // of memory we need to store transparent fragments depends on the size
563
- // of the canvas and the average number of layers per fragment we want to
564
- // support. When the devicePixelRatio is 1, we know that 128Mib is enough
565
- // to store 4 layers per pixel at 600x600. However, when the device pixel
566
- // ratio is high enough we will exceed this limit.
567
- //
568
- // We provide 2 choices of mitigations to this issue:
569
- // 1) Clamp the device pixel ratio to a value which we know will not break
570
- // the limit. The tradeoff here is that the canvas resolution will not
571
- // match the native resolution and therefore may have a reduction in
572
- // quality.
573
- // 2) Break the frame into a series of horizontal slices using the scissor
574
- // functionality and process a single slice at a time. This limits memory
575
- // usage because we only need enough memory to process the dimensions
576
- // of the slice. The tradeoff is the performance reduction due to multiple
577
- // passes.
578
- if (settings.memoryStrategy === "clamp-pixel-ratio") {
579
- devicePixelRatio = 1;
580
- }
581
-
582
- const depthTexture = device.createTexture({
583
- size: [ctx.canvas.width, ctx.canvas.height],
584
- format: "depth24plus",
585
- usage:
586
- GPUTextureUsage.RENDER_ATTACHMENT |
587
- GPUTextureUsage.TEXTURE_BINDING,
588
- label: "depthTexture",
589
- });
590
-
591
- const depthTextureView = depthTexture.createView({
592
- label: "depthTextureView",
593
- });
594
-
595
- // Determines how much memory is allocated to store linked-list elements
596
- const averageLayersPerFragment = 4;
597
-
598
- // Each element stores
599
- // * color : vec4f
600
- // * depth : f32
601
- // * index of next element in the list : u32
602
- const linkedListElementSize =
603
- 5 * Float32Array.BYTES_PER_ELEMENT +
604
- 1 * Uint32Array.BYTES_PER_ELEMENT;
605
-
606
- // We want to keep the linked-list buffer size under the maxStorageBufferBindingSize.
607
- // Split the frame into enough slices to meet that constraint.
608
- const bytesPerline =
609
- ctx.canvas.width * averageLayersPerFragment * linkedListElementSize;
610
- const maxLinesSupported = Math.floor(
611
- device.limits.maxStorageBufferBindingSize / bytesPerline,
612
- );
613
- const numSlices = Math.ceil(ctx.canvas.height / maxLinesSupported);
614
- const sliceHeight = Math.ceil(ctx.canvas.height / numSlices);
615
- const linkedListBufferSize = sliceHeight * bytesPerline;
616
-
617
- const linkedListBuffer = device.createBuffer({
618
- size: linkedListBufferSize,
619
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
620
- label: "linkedListBuffer",
621
- });
622
-
623
- // To slice up the frame we need to pass the starting fragment y position of the slice.
624
- // We do this using a uniform buffer with a dynamic offset.
625
- const sliceInfoBuffer = device.createBuffer({
626
- size: numSlices * device.limits.minUniformBufferOffsetAlignment,
627
- usage: GPUBufferUsage.UNIFORM,
628
- mappedAtCreation: true,
629
- label: "sliceInfoBuffer",
630
- });
631
- {
632
- const mapping = new Int32Array(sliceInfoBuffer.getMappedRange());
633
-
634
- // This assumes minUniformBufferOffsetAlignment is a multiple of 4
635
- const stride =
636
- device.limits.minUniformBufferOffsetAlignment /
637
- Int32Array.BYTES_PER_ELEMENT;
638
- for (let i = 0; i < numSlices; ++i) {
639
- mapping[i * stride] = i * sliceHeight;
640
- }
641
- sliceInfoBuffer.unmap();
642
- }
643
-
644
- // `Heads` struct contains the start index of the linked-list of translucent fragments
645
- // for a given pixel.
646
- // * numFragments : u32
647
- // * data : array<u32>
648
- const headsBuffer = device.createBuffer({
649
- size:
650
- (1 + ctx.canvas.width * sliceHeight) *
651
- Uint32Array.BYTES_PER_ELEMENT,
652
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
653
- label: "headsBuffer",
654
- });
655
-
656
- const headsInitBuffer = device.createBuffer({
657
- size:
658
- (1 + ctx.canvas.width * sliceHeight) *
659
- Uint32Array.BYTES_PER_ELEMENT,
660
- usage: GPUBufferUsage.COPY_SRC,
661
- mappedAtCreation: true,
662
- label: "headsInitBuffer",
663
- });
664
- {
665
- const buffer = new Uint32Array(headsInitBuffer.getMappedRange());
666
-
667
- for (let i = 0; i < buffer.length; ++i) {
668
- buffer[i] = 0xffffffff;
669
- }
670
-
671
- headsInitBuffer.unmap();
672
- }
673
-
674
- const translucentBindGroup = device.createBindGroup({
675
- layout: translucentBindGroupLayout,
676
- entries: [
677
- {
678
- binding: 0,
679
- resource: {
680
- buffer: uniformBuffer,
681
- label: "uniforms",
682
- },
683
- },
684
- {
685
- binding: 1,
686
- resource: {
687
- buffer: headsBuffer,
688
- label: "headsBuffer",
689
- },
690
- },
691
- {
692
- binding: 2,
693
- resource: {
694
- buffer: linkedListBuffer,
695
- label: "linkedListBuffer",
696
- },
697
- },
698
- {
699
- binding: 3,
700
- resource: depthTextureView,
701
- },
702
- {
703
- binding: 4,
704
- resource: {
705
- buffer: sliceInfoBuffer,
706
- size: device.limits.minUniformBufferOffsetAlignment,
707
- label: "sliceInfoBuffer",
708
- },
709
- },
710
- ],
711
- label: "translucentBindGroup",
712
- });
713
-
714
- const compositeBindGroup = device.createBindGroup({
715
- layout: compositePipeline.getBindGroupLayout(0),
716
- entries: [
717
- {
718
- binding: 0,
719
- resource: {
720
- buffer: uniformBuffer,
721
- label: "uniforms",
722
- },
723
- },
724
- {
725
- binding: 1,
726
- resource: {
727
- buffer: headsBuffer,
728
- label: "headsBuffer",
729
- },
730
- },
731
- {
732
- binding: 2,
733
- resource: {
734
- buffer: linkedListBuffer,
735
- label: "linkedListBuffer",
736
- },
737
- },
738
- {
739
- binding: 3,
740
- resource: {
741
- buffer: sliceInfoBuffer,
742
- size: device.limits.minUniformBufferOffsetAlignment,
743
- label: "sliceInfoBuffer",
744
- },
745
- },
746
- ],
747
- });
748
- // @ts-expect-error
749
- opaquePassDescriptor.depthStencilAttachment.view = depthTextureView;
750
-
751
- // Rotates the camera around the origin based on time.
752
- function getCameraViewProjMatrix() {
753
- const aspect = ctx.canvas.width / ctx.canvas.height;
754
-
755
- const projectionMatrix = mat4.perspective(
756
- (2 * Math.PI) / 5,
757
- aspect,
758
- 1,
759
- 2000.0,
760
- );
761
-
762
- const upVector = vec3.fromValues(0, 1, 0);
763
- const origin = vec3.fromValues(0, 0, 0);
764
- const eyePosition = vec3.fromValues(0, 5, -100);
765
-
766
- const now = 1721824271091;
767
- const rad = Math.PI * (now / 5000);
768
- const rotation = mat4.rotateY(mat4.translation(origin), rad);
769
- vec3.transformMat4(eyePosition, rotation, eyePosition);
770
-
771
- const viewMatrix = mat4.lookAt(eyePosition, origin, upVector);
772
-
773
- const viewProjMatrix = mat4.multiply(projectionMatrix, viewMatrix);
774
- return viewProjMatrix;
775
- }
776
-
777
- return function doDraw() {
778
- // update the uniform buffer
779
- {
780
- const buffer = new ArrayBuffer(uniformBuffer.size);
781
-
782
- new Float32Array(buffer).set(getCameraViewProjMatrix());
783
- new Uint32Array(buffer, 16 * Float32Array.BYTES_PER_ELEMENT).set([
784
- averageLayersPerFragment * ctx.canvas.width * sliceHeight,
785
- ctx.canvas.width,
786
- ]);
787
-
788
- device.queue.writeBuffer(uniformBuffer, 0, buffer);
789
- }
790
-
791
- const commandEncoder = device.createCommandEncoder();
792
- const textureView = ctx.getCurrentTexture().createView();
793
-
794
- // Draw the opaque objects
795
- // @ts-expect-error
796
- opaquePassDescriptor.colorAttachments[0].view = textureView;
797
- const opaquePassEncoder =
798
- commandEncoder.beginRenderPass(opaquePassDescriptor);
799
- opaquePassEncoder.setPipeline(opaquePipeline);
800
- opaquePassEncoder.setBindGroup(0, opaqueBindGroup);
801
- opaquePassEncoder.setVertexBuffer(0, vertexBuffer);
802
- opaquePassEncoder.setIndexBuffer(indexBuffer, "uint16");
803
- opaquePassEncoder.drawIndexed(mesh.triangles.length * 3, 8);
804
- opaquePassEncoder.end();
805
-
806
- for (let slice = 0; slice < numSlices; ++slice) {
807
- // initialize the heads buffer
808
- commandEncoder.copyBufferToBuffer(
809
- headsInitBuffer,
810
- 0,
811
- headsBuffer,
812
- 0,
813
- headsInitBuffer.size,
814
- );
815
-
816
- const scissorX = 0;
817
- const scissorY = slice * sliceHeight;
818
- const scissorWidth = ctx.canvas.width;
819
- const scissorHeight =
820
- Math.min((slice + 1) * sliceHeight, ctx.canvas.height) -
821
- slice * sliceHeight;
822
-
823
- // Draw the translucent objects
824
- // @ts-expect-error
825
- translucentPassDescriptor.colorAttachments[0].view = textureView;
826
- const translucentPassEncoder = commandEncoder.beginRenderPass(
827
- translucentPassDescriptor,
828
- );
829
-
830
- // Set the scissor to only process a horizontal slice of the frame
831
- translucentPassEncoder.setScissorRect(
832
- scissorX,
833
- scissorY,
834
- scissorWidth,
835
- scissorHeight,
836
- );
837
-
838
- translucentPassEncoder.setPipeline(translucentPipeline);
839
- translucentPassEncoder.setBindGroup(0, translucentBindGroup, [
840
- slice * device.limits.minUniformBufferOffsetAlignment,
841
- ]);
842
- translucentPassEncoder.setVertexBuffer(0, vertexBuffer);
843
- translucentPassEncoder.setIndexBuffer(indexBuffer, "uint16");
844
- translucentPassEncoder.drawIndexed(mesh.triangles.length * 3, 8);
845
- translucentPassEncoder.end();
846
-
847
- // Composite the opaque and translucent objects
848
- // @ts-expect-error
849
- compositePassDescriptor.colorAttachments[0].view = textureView;
850
- const compositePassEncoder = commandEncoder.beginRenderPass(
851
- compositePassDescriptor,
852
- );
853
-
854
- // Set the scissor to only process a horizontal slice of the frame
855
- compositePassEncoder.setScissorRect(
856
- scissorX,
857
- scissorY,
858
- scissorWidth,
859
- scissorHeight,
860
- );
861
-
862
- compositePassEncoder.setPipeline(compositePipeline);
863
- compositePassEncoder.setBindGroup(0, compositeBindGroup, [
864
- slice * device.limits.minUniformBufferOffsetAlignment,
865
- ]);
866
- compositePassEncoder.draw(6);
867
- compositePassEncoder.end();
868
- }
869
-
870
- device.queue.submit([commandEncoder.finish()]);
871
- };
872
- };
873
-
874
- const doDraw = configure();
875
-
876
- doDraw();
877
-
878
- return canvas.getImageData();
879
- },
880
- {
881
- mesh: teapotMesh,
882
- opaqueWGSL: opaque,
883
- translucentWGSL: translucent,
884
- compositeWGSL: composite,
885
- },
886
- );
887
- const image = encodeImage(result);
888
- checkImage(image, "snapshots/abuffer.png");
889
- });
890
- });