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,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
- });