react-native-wgpu 0.2.10 → 0.3.1

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 (258) hide show
  1. package/README.md +155 -69
  2. package/android/CMakeLists.txt +5 -7
  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/RNFHybridObject.cpp +8 -4
  18. package/cpp/jsi/RNFHybridObject.h +7 -2
  19. package/cpp/jsi/RNFJSIConverter.h +13 -102
  20. package/cpp/jsi/RNFJSIHelper.h +5 -3
  21. package/cpp/jsi/RNFRuntimeState.cpp +18 -0
  22. package/cpp/jsi/RNFRuntimeState.h +106 -0
  23. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
  24. package/cpp/rnwgpu/api/GPU.cpp +51 -26
  25. package/cpp/rnwgpu/api/GPU.h +5 -18
  26. package/cpp/rnwgpu/api/GPUAdapter.cpp +79 -54
  27. package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
  28. package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
  29. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
  30. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
  31. package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
  32. package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
  33. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
  34. package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
  35. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
  36. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
  37. package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
  38. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
  39. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
  40. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
  41. package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
  42. package/cpp/rnwgpu/api/GPUDevice.h +22 -21
  43. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
  44. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
  45. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
  46. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
  47. package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
  48. package/cpp/rnwgpu/api/GPUQueue.h +7 -6
  49. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
  50. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
  51. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
  52. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
  53. package/cpp/rnwgpu/api/GPUSampler.h +1 -3
  54. package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
  55. package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
  56. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
  57. package/cpp/rnwgpu/api/GPUTexture.h +1 -3
  58. package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
  59. package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
  60. package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
  61. package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
  62. package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
  63. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
  64. package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
  65. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
  66. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
  67. package/cpp/webgpu/webgpu.h +5 -4827
  68. package/cpp/webgpu/webgpu_cpp.h +5 -10140
  69. package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
  70. package/lib/commonjs/Canvas.js +6 -66
  71. package/lib/commonjs/Canvas.js.map +1 -1
  72. package/lib/commonjs/hooks.js +6 -42
  73. package/lib/commonjs/hooks.js.map +1 -1
  74. package/lib/module/Canvas.js +7 -67
  75. package/lib/module/Canvas.js.map +1 -1
  76. package/lib/module/hooks.js +5 -40
  77. package/lib/module/hooks.js.map +1 -1
  78. package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
  79. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  80. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  81. package/lib/typescript/lib/module/hooks.d.ts +1 -5
  82. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  83. package/lib/typescript/src/Canvas.d.ts +0 -1
  84. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  85. package/lib/typescript/src/hooks.d.ts +2 -7
  86. package/lib/typescript/src/hooks.d.ts.map +1 -1
  87. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  88. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  89. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  90. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  91. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
  92. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  93. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  94. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  95. package/package.json +4 -3
  96. package/react-native-wgpu.podspec +12 -16
  97. package/src/Canvas.tsx +8 -69
  98. package/src/hooks.tsx +14 -48
  99. package/android/cpp/platform/ThreadUtils.cpp +0 -41
  100. package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
  101. package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
  102. package/apple/WebGPUViewManager.mm +0 -24
  103. package/apple/platform/ThreadUtils.cpp +0 -34
  104. package/cpp/dawn/dawn_proc.h +0 -50
  105. package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
  106. package/cpp/dawn/native/D3D11Backend.h +0 -77
  107. package/cpp/dawn/native/D3D12Backend.h +0 -68
  108. package/cpp/dawn/native/D3DBackend.h +0 -56
  109. package/cpp/dawn/native/MetalBackend.h +0 -56
  110. package/cpp/dawn/platform/DawnPlatform.h +0 -167
  111. package/cpp/dawn/platform/dawn_platform_export.h +0 -49
  112. package/cpp/jsi/RNFRuntimeCache.cpp +0 -57
  113. package/cpp/jsi/RNFRuntimeCache.h +0 -79
  114. package/cpp/jsi/RNFWorkletRuntimeCollector.h +0 -43
  115. package/cpp/jsi/RNFWorkletRuntimeRegistry.cpp +0 -12
  116. package/cpp/jsi/RNFWorkletRuntimeRegistry.h +0 -44
  117. package/cpp/platform/ThreadUtils.h +0 -30
  118. package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
  119. package/cpp/threading/CallInvokerDispatcher.h +0 -37
  120. package/cpp/threading/Dispatcher.cpp +0 -55
  121. package/cpp/threading/Dispatcher.h +0 -93
  122. package/cpp/threading/ThreadPool.cpp +0 -88
  123. package/cpp/threading/ThreadPool.h +0 -53
  124. package/cpp/webgpu/webgpu_glfw.h +0 -88
  125. package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
  126. package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
  127. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
  128. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
  129. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
  130. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
  131. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
  132. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
  133. package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
  134. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
  135. package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
  136. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
  137. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
  138. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
  139. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
  140. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
  141. package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
  142. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
  143. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
  144. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
  145. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
  146. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
  147. package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
  148. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
  149. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
  150. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
  151. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
  152. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
  153. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
  154. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
  155. package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
  156. package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
  157. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
  158. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
  159. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
  160. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
  161. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
  162. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
  163. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
  164. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
  165. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
  166. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
  167. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
  168. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
  169. package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
  170. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
  171. package/lib/typescript/src/__tests__/config.d.ts +0 -3
  172. package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
  173. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
  174. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
  175. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
  176. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
  177. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
  178. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
  179. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
  180. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
  181. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
  182. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
  183. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
  184. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
  185. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
  186. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
  187. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
  188. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
  189. package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
  190. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
  191. package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
  192. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
  193. package/lib/typescript/src/__tests__/setup.d.ts +0 -63
  194. package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
  195. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  196. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  197. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  198. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  199. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  200. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  201. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  202. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  203. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  204. package/libs/dawn.json +0 -4670
  205. package/src/__tests__/Alpha.spec.ts +0 -28
  206. package/src/__tests__/ArrayBuffer.spec.ts +0 -76
  207. package/src/__tests__/Buffer.spec.ts +0 -357
  208. package/src/__tests__/ComputeShader.spec.ts +0 -375
  209. package/src/__tests__/Constants.spec.ts +0 -89
  210. package/src/__tests__/Device.spec.ts +0 -84
  211. package/src/__tests__/ErrorScope.spec.ts +0 -92
  212. package/src/__tests__/ExternalTexture.spec.ts +0 -284
  213. package/src/__tests__/GPU.spec.ts +0 -272
  214. package/src/__tests__/ImageData.spec.ts +0 -26
  215. package/src/__tests__/Shaders.spec.ts +0 -232
  216. package/src/__tests__/Texture.spec.ts +0 -197
  217. package/src/__tests__/assets/Di-3d.png +0 -0
  218. package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
  219. package/src/__tests__/components/Wireframe/models.ts +0 -113
  220. package/src/__tests__/components/Wireframe/utils.ts +0 -22
  221. package/src/__tests__/components/cube.ts +0 -51
  222. package/src/__tests__/components/meshes/mesh.ts +0 -96
  223. package/src/__tests__/components/meshes/sphere.ts +0 -103
  224. package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
  225. package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
  226. package/src/__tests__/components/meshes/teapot.ts +0 -13
  227. package/src/__tests__/components/meshes/utils.ts +0 -235
  228. package/src/__tests__/components/triangle.ts +0 -17
  229. package/src/__tests__/config.ts +0 -2
  230. package/src/__tests__/demos/ABuffer.spec.ts +0 -890
  231. package/src/__tests__/demos/Blur.spec.ts +0 -398
  232. package/src/__tests__/demos/Cube.spec.ts +0 -929
  233. package/src/__tests__/demos/FractalCube.spec.ts +0 -240
  234. package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
  235. package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
  236. package/src/__tests__/demos/Triangle.spec.ts +0 -266
  237. package/src/__tests__/demos/Wireframe.spec.ts +0 -188
  238. package/src/__tests__/globalSetup.ts +0 -45
  239. package/src/__tests__/globalTeardown.ts +0 -11
  240. package/src/__tests__/setup.ts +0 -423
  241. package/src/__tests__/snapshots/abuffer.png +0 -0
  242. package/src/__tests__/snapshots/asteroid.png +0 -0
  243. package/src/__tests__/snapshots/blur.png +0 -0
  244. package/src/__tests__/snapshots/buffer.png +0 -0
  245. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  246. package/src/__tests__/snapshots/cube.png +0 -0
  247. package/src/__tests__/snapshots/f.png +0 -0
  248. package/src/__tests__/snapshots/f2.png +0 -0
  249. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  250. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  251. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  252. package/src/__tests__/snapshots/ref.png +0 -0
  253. package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
  254. package/src/__tests__/snapshots/texture.png +0 -0
  255. package/src/__tests__/snapshots/textured-cube.png +0 -0
  256. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  257. package/src/__tests__/snapshots/triangle.png +0 -0
  258. package/src/__tests__/snapshots/two-cube.png +0 -0
@@ -1,580 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
- import seedrandom from "seedrandom";
3
-
4
- import { checkImage, client, encodeImage } from "../setup";
5
-
6
- const mesh = /*wgsl*/ `struct Uniforms {
7
- viewProjectionMatrix : mat4x4f
8
- }
9
- @group(0) @binding(0) var<uniform> uniforms : Uniforms;
10
-
11
- @group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
12
-
13
- struct VertexInput {
14
- @location(0) position : vec4f,
15
- @location(1) normal : vec3f,
16
- @location(2) uv : vec2f
17
- }
18
-
19
- struct VertexOutput {
20
- @builtin(position) position : vec4f,
21
- @location(0) normal: vec3f,
22
- @location(1) uv : vec2f,
23
- }
24
-
25
- @vertex
26
- fn vertexMain(input: VertexInput) -> VertexOutput {
27
- var output : VertexOutput;
28
- output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
29
- output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
30
- output.uv = input.uv;
31
- return output;
32
- }
33
-
34
- @group(1) @binding(1) var meshSampler: sampler;
35
- @group(1) @binding(2) var meshTexture: texture_2d<f32>;
36
-
37
- // Static directional lighting
38
- const lightDir = vec3f(1, 1, 1);
39
- const dirColor = vec3(1);
40
- const ambientColor = vec3f(0.05);
41
-
42
- @fragment
43
- fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
44
- let textureColor = textureSample(meshTexture, meshSampler, input.uv);
45
-
46
- // Very simplified lighting algorithm.
47
- let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
48
-
49
- return vec4f(textureColor.rgb * lightColor, textureColor.a);
50
- }
51
- `;
52
-
53
- interface Renderable {
54
- vertices: GPUBuffer;
55
- indices: GPUBuffer;
56
- indexCount: number;
57
- bindGroup?: GPUBindGroup;
58
- }
59
-
60
- const rng = seedrandom("asteroid");
61
- const randomValues: number[] = [];
62
- for (let j = 0; j < 30000; j++) {
63
- randomValues.push(rng());
64
- }
65
-
66
- describe("Render Bundles", () => {
67
- it("Asteroid", async () => {
68
- const result = await client.eval(
69
- ({
70
- device,
71
- gpu,
72
- ctx,
73
- meshWGSL,
74
- mat4,
75
- vec3,
76
- assets: { saturn, moon },
77
- vals,
78
- canvas,
79
- }) => {
80
- interface SphereMesh {
81
- vertices: Float32Array;
82
- indices: Uint16Array;
83
- }
84
-
85
- const SphereLayout = {
86
- vertexStride: 8 * 4,
87
- positionsOffset: 0,
88
- normalOffset: 3 * 4,
89
- uvOffset: 6 * 4,
90
- };
91
-
92
- let k = 0;
93
- const random = () => {
94
- k++;
95
- return vals[k % vals.length];
96
- };
97
-
98
- // Borrowed and simplified from https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js
99
- function createSphereMesh(
100
- radius: number,
101
- widthSegments = 32,
102
- heightSegments = 16,
103
- randomness = 0,
104
- ): SphereMesh {
105
- const vertices = [];
106
- const indices = [];
107
-
108
- widthSegments = Math.max(3, Math.floor(widthSegments));
109
- heightSegments = Math.max(2, Math.floor(heightSegments));
110
-
111
- const firstVertex = vec3.create();
112
- const vertex = vec3.create();
113
- const normal = vec3.create();
114
-
115
- let index = 0;
116
- const grid = [];
117
-
118
- // generate vertices, normals and uvs
119
- for (let iy = 0; iy <= heightSegments; iy++) {
120
- const verticesRow = [];
121
- const v = iy / heightSegments;
122
-
123
- // special case for the poles
124
- let uOffset = 0;
125
- if (iy === 0) {
126
- uOffset = 0.5 / widthSegments;
127
- } else if (iy === heightSegments) {
128
- uOffset = -0.5 / widthSegments;
129
- }
130
-
131
- for (let ix = 0; ix <= widthSegments; ix++) {
132
- const u = ix / widthSegments;
133
-
134
- // Poles should just use the same position all the way around.
135
- if (ix === widthSegments) {
136
- vec3.copy(firstVertex, vertex);
137
- } else if (ix === 0 || (iy !== 0 && iy !== heightSegments)) {
138
- const rr = radius + (random() - 0.5) * 2 * randomness * radius;
139
-
140
- // vertex
141
- vertex[0] =
142
- -rr * Math.cos(u * Math.PI * 2) * Math.sin(v * Math.PI);
143
- vertex[1] = rr * Math.cos(v * Math.PI);
144
- vertex[2] =
145
- rr * Math.sin(u * Math.PI * 2) * Math.sin(v * Math.PI);
146
-
147
- if (ix === 0) {
148
- vec3.copy(vertex, firstVertex);
149
- }
150
- }
151
-
152
- for (const element of vertex) {
153
- vertices.push(element);
154
- }
155
-
156
- // normal
157
- vec3.copy(vertex, normal);
158
- vec3.normalize(normal, normal);
159
- for (const element of normal) {
160
- vertices.push(element);
161
- }
162
-
163
- // uv
164
- vertices.push(u + uOffset, 1 - v);
165
- verticesRow.push(index++);
166
- }
167
-
168
- grid.push(verticesRow);
169
- }
170
-
171
- // indices
172
- for (let iy = 0; iy < heightSegments; iy++) {
173
- for (let ix = 0; ix < widthSegments; ix++) {
174
- const a = grid[iy][ix + 1];
175
- const b = grid[iy][ix];
176
- const c = grid[iy + 1][ix];
177
- const d = grid[iy + 1][ix + 1];
178
-
179
- if (iy !== 0) {
180
- indices.push(a, b, d);
181
- }
182
- if (iy !== heightSegments - 1) {
183
- indices.push(b, c, d);
184
- }
185
- }
186
- }
187
-
188
- return {
189
- vertices: new Float32Array(vertices),
190
- indices: new Uint16Array(indices),
191
- };
192
- }
193
-
194
- const useRenderBundles = true;
195
- const asteroidCount = 5000;
196
- const presentationFormat = gpu.getPreferredCanvasFormat();
197
-
198
- const shaderModule = device.createShaderModule({
199
- code: meshWGSL,
200
- });
201
-
202
- const pipeline = device.createRenderPipeline({
203
- layout: "auto",
204
- vertex: {
205
- module: shaderModule,
206
- buffers: [
207
- {
208
- arrayStride: SphereLayout.vertexStride,
209
- attributes: [
210
- {
211
- // position
212
- shaderLocation: 0,
213
- offset: SphereLayout.positionsOffset,
214
- format: "float32x3",
215
- },
216
- {
217
- // normal
218
- shaderLocation: 1,
219
- offset: SphereLayout.normalOffset,
220
- format: "float32x3",
221
- },
222
- {
223
- // uv
224
- shaderLocation: 2,
225
- offset: SphereLayout.uvOffset,
226
- format: "float32x2",
227
- },
228
- ],
229
- },
230
- ],
231
- },
232
- fragment: {
233
- module: shaderModule,
234
- targets: [
235
- {
236
- format: presentationFormat,
237
- },
238
- ],
239
- },
240
- primitive: {
241
- topology: "triangle-list",
242
-
243
- // Backface culling since the sphere is solid piece of geometry.
244
- // Faces pointing away from the camera will be occluded by faces
245
- // pointing toward the camera.
246
- cullMode: "back",
247
- },
248
-
249
- // Enable depth testing so that the fragment closest to the camera
250
- // is rendered in front.
251
- depthStencil: {
252
- depthWriteEnabled: true,
253
- depthCompare: "less",
254
- format: "depth24plus",
255
- },
256
- });
257
-
258
- const depthTexture = device.createTexture({
259
- size: [ctx.canvas.width, ctx.canvas.height],
260
- format: "depth24plus",
261
- usage: GPUTextureUsage.RENDER_ATTACHMENT,
262
- });
263
-
264
- const uniformBufferSize = 4 * 16; // 4x4 matrix
265
- const uniformBuffer = device.createBuffer({
266
- size: uniformBufferSize,
267
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
268
- });
269
-
270
- // Fetch the images and upload them into a GPUTexture.
271
- let planetTexture: GPUTexture;
272
- {
273
- //const response = await fetch("../../assets/img/saturn.jpg");
274
- const imageBitmap = saturn;
275
-
276
- planetTexture = device.createTexture({
277
- size: [imageBitmap.width, imageBitmap.height, 1],
278
- format: "rgba8unorm",
279
- usage:
280
- GPUTextureUsage.TEXTURE_BINDING |
281
- GPUTextureUsage.COPY_DST |
282
- GPUTextureUsage.RENDER_ATTACHMENT,
283
- });
284
-
285
- device.queue.copyExternalImageToTexture(
286
- { source: imageBitmap },
287
- { texture: planetTexture },
288
- [imageBitmap.width, imageBitmap.height],
289
- );
290
- }
291
-
292
- let moonTexture: GPUTexture;
293
- {
294
- const imageBitmap = moon;
295
-
296
- moonTexture = device.createTexture({
297
- size: [imageBitmap.width, imageBitmap.height, 1],
298
- format: "rgba8unorm",
299
- usage:
300
- GPUTextureUsage.TEXTURE_BINDING |
301
- GPUTextureUsage.COPY_DST |
302
- GPUTextureUsage.RENDER_ATTACHMENT,
303
- });
304
-
305
- device.queue.copyExternalImageToTexture(
306
- { source: imageBitmap },
307
- { texture: moonTexture },
308
- [imageBitmap.width, imageBitmap.height],
309
- );
310
- }
311
-
312
- const sampler = device.createSampler({
313
- magFilter: "linear",
314
- minFilter: "linear",
315
- });
316
-
317
- // Helper functions to create the required meshes and bind groups for each sphere.
318
- function createSphereRenderable(
319
- radius: number,
320
- widthSegments = 32,
321
- heightSegments = 16,
322
- randomness = 0,
323
- ): Renderable {
324
- const sphereMesh = createSphereMesh(
325
- radius,
326
- widthSegments,
327
- heightSegments,
328
- randomness,
329
- );
330
-
331
- // Create a vertex buffer from the sphere data.
332
- const vertices = device.createBuffer({
333
- size: sphereMesh.vertices.byteLength,
334
- usage: GPUBufferUsage.VERTEX,
335
- mappedAtCreation: true,
336
- });
337
- new Float32Array(vertices.getMappedRange()).set(sphereMesh.vertices);
338
- vertices.unmap();
339
-
340
- const indices = device.createBuffer({
341
- size: sphereMesh.indices.byteLength,
342
- usage: GPUBufferUsage.INDEX,
343
- mappedAtCreation: true,
344
- });
345
- new Uint16Array(indices.getMappedRange()).set(sphereMesh.indices);
346
- indices.unmap();
347
-
348
- return {
349
- vertices,
350
- indices,
351
- indexCount: sphereMesh.indices.length,
352
- };
353
- }
354
-
355
- function createSphereBindGroup(
356
- texture: GPUTexture,
357
- transform: Float32Array,
358
- ): GPUBindGroup {
359
- // eslint-disable-next-line @typescript-eslint/no-shadow
360
- const uniformBufferSize = 4 * 16; // 4x4 matrix
361
- // eslint-disable-next-line @typescript-eslint/no-shadow
362
- const uniformBuffer = device.createBuffer({
363
- size: uniformBufferSize,
364
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
365
- mappedAtCreation: true,
366
- });
367
- new Float32Array(uniformBuffer.getMappedRange()).set(transform);
368
- uniformBuffer.unmap();
369
-
370
- const bindGroup = device.createBindGroup({
371
- layout: pipeline.getBindGroupLayout(1),
372
- entries: [
373
- {
374
- binding: 0,
375
- resource: {
376
- buffer: uniformBuffer,
377
- },
378
- },
379
- {
380
- binding: 1,
381
- resource: sampler,
382
- },
383
- {
384
- binding: 2,
385
- resource: texture.createView(),
386
- },
387
- ],
388
- });
389
-
390
- return bindGroup;
391
- }
392
-
393
- const transform = mat4.create();
394
- mat4.identity(transform);
395
-
396
- // Create one large central planet surrounded by a large ring of asteroids
397
- const planet = createSphereRenderable(1.0);
398
- planet.bindGroup = createSphereBindGroup(planetTexture, transform);
399
-
400
- const asteroids = [
401
- createSphereRenderable(0.01, 8, 6, 0.15),
402
- createSphereRenderable(0.013, 8, 6, 0.15),
403
- createSphereRenderable(0.017, 8, 6, 0.15),
404
- createSphereRenderable(0.02, 8, 6, 0.15),
405
- createSphereRenderable(0.03, 16, 8, 0.15),
406
- ];
407
-
408
- const renderables = [planet];
409
-
410
- function ensureEnoughAsteroids() {
411
- for (let i = renderables.length; i <= asteroidCount; ++i) {
412
- // Place copies of the asteroid in a ring.
413
- const radius = random() * 1.7 + 1.25;
414
- const angle = random() * Math.PI * 2;
415
- const x = Math.sin(angle) * radius;
416
- const y = (random() - 0.5) * 0.015;
417
- const z = Math.cos(angle) * radius;
418
-
419
- mat4.identity(transform);
420
- mat4.translate(transform, [x, y, z], transform);
421
- mat4.rotateX(transform, random() * Math.PI, transform);
422
- mat4.rotateY(transform, random() * Math.PI, transform);
423
- renderables.push({
424
- ...asteroids[i % asteroids.length],
425
- bindGroup: createSphereBindGroup(moonTexture, transform),
426
- });
427
- }
428
- }
429
- ensureEnoughAsteroids();
430
-
431
- const renderPassDescriptor: GPURenderPassDescriptor = {
432
- // @ts-expect-error
433
- colorAttachments: [
434
- {
435
- view: undefined, // Assigned later
436
-
437
- clearValue: [0, 0, 0, 1],
438
- loadOp: "clear",
439
- storeOp: "store",
440
- },
441
- ],
442
- depthStencilAttachment: {
443
- view: depthTexture.createView(),
444
-
445
- depthClearValue: 1.0,
446
- depthLoadOp: "clear",
447
- depthStoreOp: "store",
448
- },
449
- };
450
-
451
- const aspect = ctx.canvas.width / ctx.canvas.height;
452
- const projectionMatrix = mat4.perspective(
453
- (2 * Math.PI) / 5,
454
- aspect,
455
- 1,
456
- 100.0,
457
- );
458
- const modelViewProjectionMatrix = mat4.create();
459
-
460
- const frameBindGroup = device.createBindGroup({
461
- layout: pipeline.getBindGroupLayout(0),
462
- entries: [
463
- {
464
- binding: 0,
465
- resource: {
466
- buffer: uniformBuffer,
467
- },
468
- },
469
- ],
470
- });
471
-
472
- function getTransformationMatrix() {
473
- const viewMatrix = mat4.identity();
474
- mat4.translate(viewMatrix, vec3.fromValues(0, 0, -4), viewMatrix);
475
- const now = 1721766068905;
476
- // Tilt the view matrix so the planet looks like it's off-axis.
477
- mat4.rotateZ(viewMatrix, Math.PI * 0.1, viewMatrix);
478
- mat4.rotateX(viewMatrix, Math.PI * 0.1, viewMatrix);
479
- // Rotate the view matrix slowly so the planet appears to spin.
480
- mat4.rotateY(viewMatrix, now * 0.05, viewMatrix);
481
-
482
- mat4.multiply(
483
- projectionMatrix,
484
- viewMatrix,
485
- modelViewProjectionMatrix,
486
- );
487
-
488
- return modelViewProjectionMatrix;
489
- }
490
-
491
- // Render bundles function as partial, limited render passes, so we can use the
492
- // same code both to render the scene normally and to build the render bundle.
493
- function renderScene(
494
- passEncoder: GPURenderPassEncoder | GPURenderBundleEncoder,
495
- ) {
496
- passEncoder.setPipeline(pipeline);
497
- passEncoder.setBindGroup(0, frameBindGroup);
498
-
499
- // Loop through every renderable object and draw them individually.
500
- // (Because many of these meshes are repeated, with only the transforms
501
- // differing, instancing would be highly effective here. This sample
502
- // intentionally avoids using instancing in order to emulate a more complex
503
- // scene, which helps demonstrate the potential time savings a render bundle
504
- // can provide.)
505
- let count = 0;
506
- for (const renderable of renderables) {
507
- passEncoder.setBindGroup(1, renderable.bindGroup!);
508
- passEncoder.setVertexBuffer(0, renderable.vertices);
509
- passEncoder.setIndexBuffer(renderable.indices, "uint16");
510
- passEncoder.drawIndexed(renderable.indexCount);
511
-
512
- if (++count > asteroidCount) {
513
- break;
514
- }
515
- }
516
- }
517
-
518
- // The render bundle can be encoded once and re-used as many times as needed.
519
- // Because it encodes all of the commands needed to render at the GPU level,
520
- // those commands will not need to execute the associated JavaScript code upon
521
- // execution or be re-validated, which can represent a significant time savings.
522
- //
523
- // However, because render bundles are immutable once created, they are only
524
- // appropriate for rendering content where the same commands will be executed
525
- // every time, with the only changes being the contents of the buffers and
526
- // textures used. Cases where the executed commands differ from frame-to-frame,
527
- // such as when using frustrum or occlusion culling, will not benefit from
528
- // using render bundles as much.
529
- let renderBundle: GPURenderBundle;
530
- function updateRenderBundle() {
531
- const renderBundleEncoder = device.createRenderBundleEncoder({
532
- colorFormats: [presentationFormat],
533
- depthStencilFormat: "depth24plus",
534
- });
535
- renderScene(renderBundleEncoder);
536
- renderBundle = renderBundleEncoder.finish();
537
- }
538
- updateRenderBundle();
539
-
540
- function frame() {
541
- const transformationMatrix = getTransformationMatrix();
542
- device.queue.writeBuffer(
543
- uniformBuffer,
544
- 0,
545
- transformationMatrix.buffer,
546
- transformationMatrix.byteOffset,
547
- transformationMatrix.byteLength,
548
- );
549
- // @ts-expect-error
550
- renderPassDescriptor.colorAttachments[0].view = ctx
551
- .getCurrentTexture()
552
- .createView();
553
-
554
- const commandEncoder = device.createCommandEncoder();
555
- const passEncoder =
556
- commandEncoder.beginRenderPass(renderPassDescriptor);
557
-
558
- if (useRenderBundles) {
559
- // Executing a bundle is equivalent to calling all of the commands encoded
560
- // in the render bundle as part of the current render pass.
561
- passEncoder.executeBundles([renderBundle]);
562
- } else {
563
- // Alternatively, the same render commands can be encoded manually, which
564
- // can take longer since each command needs to be interpreted by the
565
- // JavaScript virtual machine and re-validated each time.
566
- renderScene(passEncoder);
567
- }
568
-
569
- passEncoder.end();
570
- device.queue.submit([commandEncoder.finish()]);
571
- }
572
- frame();
573
- return canvas.getImageData();
574
- },
575
- { meshWGSL: mesh, vals: randomValues },
576
- );
577
- const image = encodeImage(result);
578
- checkImage(image, "snapshots/asteroid.png", { maxPixelDiff: 500 });
579
- });
580
- });