chorama 0.0.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 (256) hide show
  1. package/.configs/tsconfig.lib.json +43 -0
  2. package/.configs/tsconfig.website.json +34 -0
  3. package/.github/workflows/static.yml +88 -0
  4. package/.vscode/launch.json +29 -0
  5. package/.vscode/tasks.json +19 -0
  6. package/README.md +127 -0
  7. package/assets/images/disappointed.jpg +0 -0
  8. package/assets/images/skybox/grimmnight_back.png +0 -0
  9. package/assets/images/skybox/grimmnight_bottom.png +0 -0
  10. package/assets/images/skybox/grimmnight_front.png +0 -0
  11. package/assets/images/skybox/grimmnight_left.png +0 -0
  12. package/assets/images/skybox/grimmnight_right.png +0 -0
  13. package/assets/images/skybox/grimmnight_top.png +0 -0
  14. package/assets/images/skybox/miramar_back.png +0 -0
  15. package/assets/images/skybox/miramar_bottom.png +0 -0
  16. package/assets/images/skybox/miramar_front.png +0 -0
  17. package/assets/images/skybox/miramar_left.png +0 -0
  18. package/assets/images/skybox/miramar_right.png +0 -0
  19. package/assets/images/skybox/miramar_top.png +0 -0
  20. package/assets/images/uv.jpg +0 -0
  21. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_BaseColor.png +0 -0
  22. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_Normal.png +0 -0
  23. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_OcclusionRoughMetal.png +0 -0
  24. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_BaseColor.png +0 -0
  25. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_Normal.png +0 -0
  26. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_OcclusionRoughMetal.png +0 -0
  27. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_BaseColor.png +0 -0
  28. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_Normal.png +0 -0
  29. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_OcclusionRoughMetal.png +0 -0
  30. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_BaseColor.png +0 -0
  31. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_Normal.png +0 -0
  32. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_OcclusionRoughMetal.png +0 -0
  33. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_BaseColor.png +0 -0
  34. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_Normal.png +0 -0
  35. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_OcclusionRoughMetal.png +0 -0
  36. package/assets/models/gltf/flight_helmet/index.bin +0 -0
  37. package/assets/models/gltf/flight_helmet/index.gltf +705 -0
  38. package/assets/models/gltf/object.gltf +23 -0
  39. package/assets/models/gltf/pirate_girl/index.bin +0 -0
  40. package/assets/models/gltf/pirate_girl/index.gltf +2082 -0
  41. package/assets/models/obj/pirate_girl/pirate_girl.obj +18459 -0
  42. package/assets/models/obj/pirate_girl/pirate_girl.png +0 -0
  43. package/astro.config.mjs +45 -0
  44. package/content/guide/api-map.md +89 -0
  45. package/content/guide/camera-and-controls.md +98 -0
  46. package/content/guide/first-scene.md +176 -0
  47. package/content/guide/index.md +72 -0
  48. package/content/guide/installation.md +179 -0
  49. package/content/guide/materials-and-lighting.md +138 -0
  50. package/content/guide/plugins-and-render-pipeline.md +124 -0
  51. package/content/guide/render-targets-and-views.md +147 -0
  52. package/content/guide/scene-graph-and-transforms.md +113 -0
  53. package/content/guide/textures-and-assets.md +120 -0
  54. package/content/guide/troubleshooting.md +49 -0
  55. package/env.d.ts +19 -0
  56. package/examples/addons/rendergraph_gui.js +580 -0
  57. package/examples/camera/orthographic.js +120 -0
  58. package/examples/camera/perspective.js +138 -0
  59. package/examples/lights/directional.js +397 -0
  60. package/examples/lights/multiple_spot_lights.js +304 -0
  61. package/examples/lights/point.js +337 -0
  62. package/examples/lights/spot.js +366 -0
  63. package/examples/loader/gltf_material.js +111 -0
  64. package/examples/loader/gltfloader.js +78 -0
  65. package/examples/loader/objloader.js +95 -0
  66. package/examples/material/cullface.js +111 -0
  67. package/examples/material/materials.js +126 -0
  68. package/examples/material/standard/basic.js +164 -0
  69. package/examples/mesh/circle.js +117 -0
  70. package/examples/mesh/cuboid.js +151 -0
  71. package/examples/mesh/cylinder.js +139 -0
  72. package/examples/mesh/geometries.js +108 -0
  73. package/examples/mesh/meshTopology.js +103 -0
  74. package/examples/mesh/plane.js +117 -0
  75. package/examples/mesh/skinning.js +136 -0
  76. package/examples/mesh/uvsphere.js +113 -0
  77. package/examples/other/rotatingCube.js +93 -0
  78. package/examples/other/rotatingSphere.js +96 -0
  79. package/examples/rendertarget/basic_canvas.js +130 -0
  80. package/examples/rendertarget/depth_texture.js +130 -0
  81. package/examples/rendertarget/image_target.js +140 -0
  82. package/examples/rendertarget/multiple_views.js +158 -0
  83. package/examples/rendertarget/render_masks.js +173 -0
  84. package/examples/rendertarget/split_screen.js +123 -0
  85. package/examples/rendertarget/split_view.js +137 -0
  86. package/examples/skybox/skybox.js +111 -0
  87. package/examples/texture/arrays.js +156 -0
  88. package/examples/texture/textureWrap.js +118 -0
  89. package/examples/transform/propagation.js +92 -0
  90. package/package.json +55 -0
  91. package/rollup.config.js +66 -0
  92. package/scripts/stage-chorama.mjs +29 -0
  93. package/src/caches/cache.js +420 -0
  94. package/src/caches/index.js +2 -0
  95. package/src/caches/uniformbuffers.js +104 -0
  96. package/src/cameracontrols/index.js +258 -0
  97. package/src/constants/index.js +3 -0
  98. package/src/constants/mesh.js +197 -0
  99. package/src/constants/others.js +218 -0
  100. package/src/constants/texture.js +183 -0
  101. package/src/core/constants.js +14 -0
  102. package/src/core/extensions.js +42 -0
  103. package/src/core/index.js +7 -0
  104. package/src/core/layouts/index.js +4 -0
  105. package/src/core/layouts/meshvertex.js +60 -0
  106. package/src/core/layouts/uniform.js +21 -0
  107. package/src/core/layouts/uniformbuffer.js +15 -0
  108. package/src/core/layouts/vertexbuffer.js +43 -0
  109. package/src/core/limits.js +247 -0
  110. package/src/core/resources/blendparams.js +89 -0
  111. package/src/core/resources/framebuffer.js +127 -0
  112. package/src/core/resources/gpubuffer.js +32 -0
  113. package/src/core/resources/gpumesh.js +43 -0
  114. package/src/core/resources/gputexture.js +73 -0
  115. package/src/core/resources/index.js +5 -0
  116. package/src/core/shader.js +62 -0
  117. package/src/core/webgl/bindgroup.js +89 -0
  118. package/src/core/webgl/descriptors.js +104 -0
  119. package/src/core/webgl/index.js +5 -0
  120. package/src/core/webgl/renderpassencoder.js +96 -0
  121. package/src/core/webgl/renderpipeline.js +54 -0
  122. package/src/core/webgl/utils.js +371 -0
  123. package/src/core/webgl/webglrenderdevice.js +235 -0
  124. package/src/function.js +358 -0
  125. package/src/index.js +15 -0
  126. package/src/loader/gltf.js +2172 -0
  127. package/src/loader/index.js +3 -0
  128. package/src/loader/loader.js +174 -0
  129. package/src/loader/obj.js +188 -0
  130. package/src/loader/texture.js +85 -0
  131. package/src/loader/utils.js +16 -0
  132. package/src/material/basic.js +75 -0
  133. package/src/material/depth.js +73 -0
  134. package/src/material/index.js +8 -0
  135. package/src/material/lambert.js +73 -0
  136. package/src/material/material.js +106 -0
  137. package/src/material/normal.js +30 -0
  138. package/src/material/phong.js +86 -0
  139. package/src/material/raw.js +52 -0
  140. package/src/material/standard.js +221 -0
  141. package/src/math/index.js +3 -0
  142. package/src/math/transform.js +38 -0
  143. package/src/mesh/attribute/attribute.js +79 -0
  144. package/src/mesh/attribute/index.js +1 -0
  145. package/src/mesh/attributedata/index.js +1 -0
  146. package/src/mesh/attributedata/separate.js +180 -0
  147. package/src/mesh/builders/base.js +41 -0
  148. package/src/mesh/builders/circle.js +63 -0
  149. package/src/mesh/builders/cuboid.js +135 -0
  150. package/src/mesh/builders/cylinder.js +131 -0
  151. package/src/mesh/builders/index.js +7 -0
  152. package/src/mesh/builders/plane.js +73 -0
  153. package/src/mesh/builders/utils.js +20 -0
  154. package/src/mesh/builders/uvsphere.js +80 -0
  155. package/src/mesh/builders/wireframe.js +62 -0
  156. package/src/mesh/index.js +4 -0
  157. package/src/mesh/mesh.js +149 -0
  158. package/src/objects/bone.js +17 -0
  159. package/src/objects/camera/camera.js +56 -0
  160. package/src/objects/camera/index.js +2 -0
  161. package/src/objects/camera/projection.js +203 -0
  162. package/src/objects/debug/index.js +1 -0
  163. package/src/objects/debug/skeleton.js +28 -0
  164. package/src/objects/index.js +7 -0
  165. package/src/objects/light/ambient.js +20 -0
  166. package/src/objects/light/directional.js +29 -0
  167. package/src/objects/light/index.js +5 -0
  168. package/src/objects/light/point.js +32 -0
  169. package/src/objects/light/shadow/index.js +1 -0
  170. package/src/objects/light/shadow/shadow.js +67 -0
  171. package/src/objects/light/spot.js +56 -0
  172. package/src/objects/mesh.js +141 -0
  173. package/src/objects/object3d.js +167 -0
  174. package/src/objects/skybox.js +38 -0
  175. package/src/plugins/camera/camera.js +19 -0
  176. package/src/plugins/camera/index.js +2 -0
  177. package/src/plugins/camera/nodes/cameraview.js +46 -0
  178. package/src/plugins/camera/nodes/index.js +2 -0
  179. package/src/plugins/camera/nodes/opaquepass.js +79 -0
  180. package/src/plugins/index.js +6 -0
  181. package/src/plugins/light/index.js +2 -0
  182. package/src/plugins/light/light.js +23 -0
  183. package/src/plugins/light/nodes/index.js +1 -0
  184. package/src/plugins/light/nodes/light.js +127 -0
  185. package/src/plugins/meshmaterial/index.js +3 -0
  186. package/src/plugins/meshmaterial/meshmaterial.js +381 -0
  187. package/src/plugins/meshmaterial/nodes/index.js +1 -0
  188. package/src/plugins/meshmaterial/nodes/meshmaterial.js +50 -0
  189. package/src/plugins/meshmaterial/resources/index.js +1 -0
  190. package/src/plugins/meshmaterial/resources/meshmaterialpipelines.js +50 -0
  191. package/src/plugins/shadow/index.js +3 -0
  192. package/src/plugins/shadow/nodes/index.js +3 -0
  193. package/src/plugins/shadow/nodes/shadow.js +272 -0
  194. package/src/plugins/shadow/nodes/shadowOccluder.js +112 -0
  195. package/src/plugins/shadow/nodes/shadowOpaquePass.js +73 -0
  196. package/src/plugins/shadow/resources/ShadowMap.js +99 -0
  197. package/src/plugins/shadow/resources/index.js +2 -0
  198. package/src/plugins/shadow/resources/shadowpipelines.js +25 -0
  199. package/src/plugins/shadow/shadow.js +31 -0
  200. package/src/plugins/skeletonhelper/index.js +1 -0
  201. package/src/plugins/skeletonhelper/skeletonhelper.js +160 -0
  202. package/src/plugins/skybox/index.js +3 -0
  203. package/src/plugins/skybox/nodes/index.js +1 -0
  204. package/src/plugins/skybox/nodes/skybox.js +143 -0
  205. package/src/plugins/skybox/resources/index.js +2 -0
  206. package/src/plugins/skybox/resources/skyboxmesh.js +14 -0
  207. package/src/plugins/skybox/resources/skyboxpipeline.js +6 -0
  208. package/src/plugins/skybox/skybox.js +137 -0
  209. package/src/renderer/core/index.js +179 -0
  210. package/src/renderer/graph/index.js +3 -0
  211. package/src/renderer/graph/nodes.js +34 -0
  212. package/src/renderer/graph/rendergraph.js +182 -0
  213. package/src/renderer/index.js +5 -0
  214. package/src/renderer/plugin.js +36 -0
  215. package/src/renderer/renderer.js +179 -0
  216. package/src/renderer/views.js +28 -0
  217. package/src/rendertarget/canvastarget.js +30 -0
  218. package/src/rendertarget/image.js +132 -0
  219. package/src/rendertarget/index.js +3 -0
  220. package/src/rendertarget/rendertarget.js +89 -0
  221. package/src/shader/basicFragment.glsl +30 -0
  222. package/src/shader/basicVertex.glsl +87 -0
  223. package/src/shader/common/color.glsl +7 -0
  224. package/src/shader/common/common.glsl +25 -0
  225. package/src/shader/common/index.js +4 -0
  226. package/src/shader/common/light.glsl +437 -0
  227. package/src/shader/common/math.glsl +12 -0
  228. package/src/shader/debug/index.js +2 -0
  229. package/src/shader/debug/skeletonFragment.glsl +8 -0
  230. package/src/shader/debug/skeletonVertex.glsl +27 -0
  231. package/src/shader/depthFragment.glsl +37 -0
  232. package/src/shader/index.js +11 -0
  233. package/src/shader/lambertFragment.glsl +126 -0
  234. package/src/shader/normalFragment.glsl +25 -0
  235. package/src/shader/phongFragment.glsl +140 -0
  236. package/src/shader/skyboxFragment.glsl +16 -0
  237. package/src/shader/skyboxVertex.glsl +20 -0
  238. package/src/shader/standardFragment.glsl +274 -0
  239. package/src/texture/index.js +2 -0
  240. package/src/texture/sampler.js +111 -0
  241. package/src/texture/texture.js +234 -0
  242. package/src/utils/index.js +115 -0
  243. package/tsconfig.json +11 -0
  244. package/website/config/index.ts +1 -0
  245. package/website/config/navigation.ts +53 -0
  246. package/website/content.config.ts +92 -0
  247. package/website/layouts/DocLayout.astro +501 -0
  248. package/website/layouts/Example.astro +91 -0
  249. package/website/pages/examples/[...slug].astro +77 -0
  250. package/website/pages/examples/index.astro +98 -0
  251. package/website/pages/examples/samples/[...slug].astro +17 -0
  252. package/website/pages/guide/[slug].astro +30 -0
  253. package/website/pages/guide/index.astro +21 -0
  254. package/website/pages/index.astro +9 -0
  255. package/website/plugins/remark-link-base.js +23 -0
  256. package/website/utils/url.ts +30 -0
@@ -0,0 +1,96 @@
1
+ /** @import { GPUMesh } from "../resources/index.js" */
2
+ import { assert } from "../../utils/index.js"
3
+
4
+ export class WebGLRenderPassEncoder {
5
+ /**
6
+ * @private
7
+ * @type {WebGL2RenderingContext}
8
+ */
9
+ context
10
+ /**
11
+ * @private
12
+ * @type {import("./renderpipeline.js").WebGLRenderPipeline | undefined}
13
+ */
14
+ pipeline
15
+ /**
16
+ * @private
17
+ * @type {Map<number, any>}
18
+ */
19
+ bindGroups = new Map()
20
+
21
+ /**
22
+ * @param {WebGL2RenderingContext} context
23
+ */
24
+ constructor(context) {
25
+ this.context = context
26
+ }
27
+
28
+ /**
29
+ * WebGPU-like API: selects the active render pipeline.
30
+ * @param {import("./renderpipeline.js").WebGLRenderPipeline} pipeline
31
+ */
32
+ setPipeline(pipeline) {
33
+ this.pipeline = pipeline
34
+ this.context.useProgram(pipeline.program)
35
+
36
+ // culling
37
+ if (pipeline.cullMode) {
38
+ this.context.enable(this.context.CULL_FACE)
39
+ this.context.cullFace(pipeline.cullMode)
40
+ } else {
41
+ this.context.disable(this.context.CULL_FACE)
42
+ }
43
+
44
+ // depth
45
+ this.context.depthFunc(pipeline.depthCompare)
46
+ this.context.depthMask(pipeline.depthWrite)
47
+
48
+ // blending
49
+ // NOTE: webgl does not have ability to blend differently on
50
+ // different render targets since state is global.
51
+ const target = pipeline.targets[0]
52
+ if (target && target.blend) {
53
+ const { color, alpha } = target.blend
54
+
55
+ this.context.enable(this.context.BLEND)
56
+ this.context.blendEquationSeparate(color.operation, alpha.operation)
57
+ this.context.blendFuncSeparate(
58
+ color.source,
59
+ color.destination,
60
+ alpha.source,
61
+ alpha.destination
62
+ )
63
+ } else {
64
+ this.context.disable(this.context.BLEND)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Makeshift bind-group entry point for future expansion.
70
+ * @param {number} index
71
+ * @param {any} bindGroup
72
+ */
73
+ setBindGroup(index, bindGroup) {
74
+ this.bindGroups.set(index, bindGroup)
75
+ }
76
+
77
+ /**
78
+ * @param {GPUMesh} mesh
79
+ */
80
+ draw(mesh) {
81
+ assert(this.pipeline, "No active pipeline set on render pass encoder")
82
+
83
+ this.context.bindVertexArray(mesh.inner)
84
+ if (mesh.indexType !== undefined) {
85
+ this.context.drawElements(this.pipeline.topology, mesh.count, mesh.indexType, 0)
86
+ return
87
+ }
88
+ this.context.drawArrays(this.pipeline.topology, 0, mesh.count)
89
+ }
90
+
91
+ end() {
92
+ this.pipeline = undefined
93
+ this.bindGroups.clear()
94
+ this.context.bindVertexArray(null)
95
+ }
96
+ }
@@ -0,0 +1,54 @@
1
+ /**@import { RenderTargetDescriptor } from './descriptors.js' */
2
+ import { CullFace, FrontFaceDirection, PrimitiveTopology } from "../../constants/index.js";
3
+ import { CompareFunction } from "../constants.js";
4
+ import { MeshVertexLayout, UniformBufferLayout, Uniform } from "../layouts/index.js";
5
+
6
+ export class WebGLRenderPipeline {
7
+ /**
8
+ * @param {WebGLRenderPipelineOptions} descriptor
9
+ */
10
+ constructor({
11
+ program,
12
+ targets,
13
+ uniforms,
14
+ uniformBlocks,
15
+ topology,
16
+ vertexLayout,
17
+ depthCompare,
18
+ depthWrite,
19
+ cullFace,
20
+ frontFace
21
+ }) {
22
+ this.program = program
23
+ this.uniforms = uniforms
24
+ this.uniformBlocks = uniformBlocks
25
+ this.vertexLayout = vertexLayout
26
+ this.topology = topology
27
+ this.cullMode = cullFace
28
+ this.depthCompare = depthCompare
29
+ this.depthWrite = depthWrite
30
+ this.frontFace = frontFace
31
+ this.targets = targets
32
+ }
33
+
34
+ /**
35
+ * @param {WebGL2RenderingContext} gl
36
+ */
37
+ dispose(gl) {
38
+ gl.deleteProgram(this.program)
39
+ }
40
+ }
41
+
42
+ /**
43
+ * @typedef WebGLRenderPipelineOptions
44
+ * @property {WebGLProgram} program
45
+ * @property {Map<string, Uniform>} uniforms
46
+ * @property {Map<string, UniformBufferLayout>} uniformBlocks
47
+ * @property {RenderTargetDescriptor[]} targets
48
+ * @property {MeshVertexLayout} vertexLayout
49
+ * @property {PrimitiveTopology} topology
50
+ * @property {CullFace} cullFace
51
+ * @property {boolean} depthWrite
52
+ * @property {CompareFunction} depthCompare
53
+ * @property {FrontFaceDirection} frontFace
54
+ */
@@ -0,0 +1,371 @@
1
+ /**@import { WebGLTextureDescriptor, WebGLWriteTextureDescriptor } from './descriptors.js'*/
2
+ import { UniformType } from "../../constants/index.js"
3
+ import { WebGLTextureFormat, convertBufferToTypedArray } from "../../function.js"
4
+ import { Vector3 } from "../../math/index.js"
5
+ import { assert } from "../../utils/index.js"
6
+ import { MeshVertexLayout, Uniform, UniformBufferLayout } from "../layouts/index.js"
7
+
8
+ /**
9
+ * @param {WebGL2RenderingContext} context
10
+ * @param {WebGLTextureDescriptor} descriptor
11
+ * @param {WebGLTextureFormat} format
12
+ */
13
+ export function allocateTexture2DArray(context, descriptor, format) {
14
+ context.texStorage3D(
15
+ WebGL2RenderingContext.TEXTURE_2D_ARRAY,
16
+ 1,
17
+ format.internalFormat,
18
+ descriptor.width,
19
+ descriptor.height,
20
+ descriptor.depth || 1
21
+ )
22
+ }
23
+
24
+ /**
25
+ * @param {WebGL2RenderingContext} context
26
+ * @param {WebGLTextureDescriptor} descriptor
27
+ * @param {WebGLTextureFormat} format
28
+ */
29
+ export function allocateTexture2D(context, descriptor, format) {
30
+ context.texImage2D(
31
+ WebGL2RenderingContext.TEXTURE_2D,
32
+ 0,
33
+ format.internalFormat,
34
+ descriptor.width,
35
+ descriptor.height,
36
+ 0,
37
+ format.format,
38
+ format.dataType,
39
+ null
40
+ )
41
+ context.texParameteri(
42
+ WebGL2RenderingContext.TEXTURE_2D,
43
+ WebGL2RenderingContext.TEXTURE_MIN_FILTER,
44
+ WebGL2RenderingContext.NEAREST
45
+ )
46
+ context.texParameteri(
47
+ WebGL2RenderingContext.TEXTURE_2D,
48
+ WebGL2RenderingContext.TEXTURE_MAG_FILTER,
49
+ WebGL2RenderingContext.NEAREST
50
+ )
51
+ }
52
+
53
+ /**
54
+ * @param {WebGL2RenderingContext} context
55
+ * @param {WebGLTextureDescriptor} descriptor
56
+ * @param {WebGLTextureFormat} format
57
+ */
58
+ export function allocateCubemap(context, descriptor, format) {
59
+ for (let offset = 0; offset < 6; offset++) {
60
+ context.texImage2D(
61
+ WebGL2RenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X + offset,
62
+ 0,
63
+ format.internalFormat,
64
+ descriptor.width,
65
+ descriptor.height,
66
+ 0,
67
+ format.format,
68
+ format.dataType,
69
+ null
70
+ )
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @param {WebGL2RenderingContext} context
76
+ * @param {WebGLWriteTextureDescriptor} descriptor
77
+ */
78
+ export function updateTexture2D(context, descriptor) {
79
+ const {
80
+ texture,
81
+ data,
82
+ mipmapLevel = 0,
83
+ offset = new Vector3(0, 0, 0),
84
+ size = new Vector3(texture.width, texture.height, texture.depth)
85
+ } = descriptor
86
+ const { format, dataType } = texture.format
87
+
88
+ context.texSubImage2D(
89
+ WebGL2RenderingContext.TEXTURE_2D,
90
+ mipmapLevel,
91
+ offset.x,
92
+ offset.y,
93
+ size.x,
94
+ size.y,
95
+ format,
96
+ dataType,
97
+ convertBufferToTypedArray(data, dataType)
98
+ )
99
+ }
100
+
101
+ /**
102
+ * @param {WebGL2RenderingContext} context
103
+ * @param {WebGLWriteTextureDescriptor} descriptor
104
+ */
105
+ export function updateTexture2DArray(context, descriptor) {
106
+ const {
107
+ texture,
108
+ data,
109
+ mipmapLevel = 0,
110
+ offset = new Vector3(0, 0, 0),
111
+ size = new Vector3(texture.width, texture.height, texture.depth)
112
+ } = descriptor
113
+ const { format, dataType } = texture.format
114
+
115
+ context.texSubImage3D(
116
+ WebGL2RenderingContext.TEXTURE_2D_ARRAY,
117
+ mipmapLevel,
118
+ offset.x,
119
+ offset.y,
120
+ offset.z,
121
+ size.x,
122
+ size.y,
123
+ size.z,
124
+ format,
125
+ dataType,
126
+ convertBufferToTypedArray(data, dataType)
127
+ )
128
+ }
129
+
130
+ /**
131
+ * @param {WebGL2RenderingContext} gl
132
+ * @param {WebGLWriteTextureDescriptor} descriptor
133
+ */
134
+ export function updateCubeMap(gl, descriptor) {
135
+ const {
136
+ texture,
137
+ data,
138
+ mipmapLevel = 0,
139
+ offset = new Vector3(0, 0, 0),
140
+ size = new Vector3(texture.width, texture.height, texture.depth)
141
+ } = descriptor
142
+ const { format, dataType } = texture.format
143
+ const { width, height, pixelSize } = texture
144
+ const sliceSize = pixelSize * width * height
145
+ const src = convertBufferToTypedArray(data, dataType)
146
+
147
+ for (let i = 0; i < 6; i++) {
148
+ gl.texSubImage2D(
149
+ WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X + i,
150
+ mipmapLevel,
151
+ offset.x,
152
+ offset.y,
153
+ size.x,
154
+ size.y,
155
+ format,
156
+ dataType,
157
+ src,
158
+ sliceSize * i
159
+ )
160
+ }
161
+ }
162
+
163
+ /**
164
+ * @param {WebGL2RenderingContext} gl
165
+ * @param {string} vshader
166
+ * @param {string} fshader
167
+ * @param {MeshVertexLayout} vertexLayout
168
+ */
169
+ export function createProgramFromSrc(gl, vshader, fshader, vertexLayout) {
170
+ let v = createshader(gl, vshader, gl.VERTEX_SHADER)
171
+ let f = createshader(gl, fshader, gl.FRAGMENT_SHADER)
172
+ if (f == null || v == null) {
173
+ gl.deleteShader(v)
174
+ gl.deleteShader(f)
175
+ return null
176
+ }
177
+ let program = createProgram(gl, v, f, vertexLayout)
178
+
179
+ return program
180
+ }
181
+
182
+ /**
183
+ * @param {WebGL2RenderingContext} gl
184
+ * @param {WebGLShader} vshader
185
+ * @param {WebGLShader} fshader
186
+ * @param {MeshVertexLayout} vertexLayout
187
+ *
188
+ */
189
+ function createProgram(gl, vshader, fshader, vertexLayout) {
190
+ let program = gl.createProgram()
191
+ gl.attachShader(program, vshader)
192
+ gl.attachShader(program, fshader)
193
+
194
+ for (const layout of vertexLayout.layouts) {
195
+ for (const attribute of layout.attributes) {
196
+ gl.bindAttribLocation(program, attribute.id, attribute.name)
197
+ }
198
+ }
199
+ gl.linkProgram(program)
200
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
201
+ console.log(`Program could not be linked:
202
+ ========================================
203
+ ${gl.getProgramInfoLog(program)}
204
+ `);
205
+ gl.deleteProgram(program)
206
+ return null
207
+ }
208
+ gl.validateProgram(program)
209
+ const info = gl.getProgramInfoLog(program)?.trim()
210
+ if (info) {
211
+ console.log(`Program could not be validated:
212
+ ========================================
213
+ ${info}
214
+ `);
215
+ }
216
+
217
+ gl.useProgram(program)
218
+ gl.detachShader(program, vshader)
219
+ gl.detachShader(program, fshader)
220
+ gl.deleteShader(vshader)
221
+ gl.deleteShader(fshader)
222
+ return {
223
+ program,
224
+ uniforms: getActiveUniforms(gl, program),
225
+ uniformBlocks: getActiveUniformBlocks(gl, program)
226
+ }
227
+ }
228
+
229
+ /**
230
+ * @param {WebGL2RenderingContext} gl
231
+ * @param {WebGLProgram} program
232
+ * @returns {Map<string,Uniform>}
233
+ */
234
+ function getActiveUniforms(gl, program) {
235
+ let textureUnit = 0
236
+ const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
237
+ const map = new Map()
238
+ for (let i = 0; i < numUniforms; i++) {
239
+ const info = gl.getActiveUniform(program, i)
240
+
241
+ if (!info) continue
242
+
243
+ const location = gl.getUniformLocation(program, info.name)
244
+ const [blockIndex] = gl.getActiveUniforms(
245
+ program,
246
+ [i],
247
+ gl.UNIFORM_BLOCK_INDEX
248
+ )
249
+ if (blockIndex !== -1 || !location) continue
250
+ const uniform = new Uniform(
251
+ location,
252
+ info.type,
253
+ info.size
254
+ )
255
+
256
+ switch (info.type) {
257
+ case UniformType.Sampler2D:
258
+ case UniformType.ISampler2D:
259
+ case UniformType.USampler2D:
260
+ case UniformType.Sampler2DShadow:
261
+ case UniformType.Sampler2DArray:
262
+ case UniformType.ISampler2DArray:
263
+ case UniformType.USampler2DArray:
264
+ case UniformType.Sampler2DArrayShadow:
265
+ case UniformType.SamplerCube:
266
+ case UniformType.ISamplerCube:
267
+ case UniformType.USamplerCube:
268
+ case UniformType.SamplerCubeShadow:
269
+ case UniformType.Sampler3D:
270
+ case UniformType.ISampler3D:
271
+ case UniformType.USampler3D:
272
+ uniform.texture_unit = textureUnit
273
+ textureUnit += 1
274
+ gl.uniform1i(location, uniform.texture_unit)
275
+ break
276
+ }
277
+ map.set(info.name, uniform)
278
+ }
279
+ return map
280
+ }
281
+
282
+ /**
283
+ * @param {WebGL2RenderingContext} gl
284
+ * @param {WebGLProgram} program
285
+ * @returns {Map<string,UniformBufferLayout>}
286
+ */
287
+ function getActiveUniformBlocks(gl, program) {
288
+ const results = new Map()
289
+ const numBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS);
290
+
291
+ for (let i = 0; i < numBlocks; i++) {
292
+ const name = gl.getActiveUniformBlockName(program, i);
293
+ results.set(name, getUniformBufferLayout(gl, program, i))
294
+ }
295
+ return results
296
+ }
297
+
298
+ /**
299
+ * @param {WebGL2RenderingContext} gl
300
+ * @param {WebGLProgram} program
301
+ * @param {number} index
302
+ */
303
+ function getUniformBufferLayout(gl, program, index) {
304
+ const size = gl.getActiveUniformBlockParameter(
305
+ program,
306
+ index,
307
+ gl.UNIFORM_BLOCK_DATA_SIZE
308
+ )
309
+ const uniformIndices = gl.getActiveUniformBlockParameter(
310
+ program,
311
+ index,
312
+ gl.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
313
+ )
314
+ const offsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
315
+ const strides = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_ARRAY_STRIDE);
316
+ const fields = new Map()
317
+
318
+ uniformIndices.forEach((/** @type {number} */ index, /** @type {string | number} */ i) => {
319
+ const info = gl.getActiveUniform(program, index)
320
+
321
+ if (!info) {
322
+ return
323
+ }
324
+ return fields.set(info.name, {
325
+ type: info.type,
326
+ size: info.size,
327
+ offset: offsets[i],
328
+ stride: strides[i]
329
+ })
330
+ });
331
+ return new UniformBufferLayout("", size, fields)
332
+ }
333
+
334
+ /**
335
+ * @param {WebGL2RenderingContext} gl
336
+ * @param {string} src
337
+ * @param {number} type
338
+ */
339
+ function createshader(gl, src, type) {
340
+ let shader = gl.createShader(type)
341
+
342
+ assert(shader, "No shader created")
343
+
344
+ gl.shaderSource(shader, src)
345
+ gl.compileShader(shader)
346
+
347
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
348
+ console.log(`Shader could not compile:
349
+ ${formatGlsl(src)}
350
+ ========================================
351
+ ${gl.getShaderInfoLog(shader)}
352
+ `);
353
+ gl.deleteShader(shader)
354
+ return null
355
+ }
356
+ return shader
357
+ }
358
+
359
+ /**
360
+ * @param {string} code
361
+ */
362
+ function formatGlsl(code) {
363
+ const normalized = code.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
364
+ const lines = normalized.split("\n")
365
+
366
+ return lines.map((ln, idx) => {
367
+ const num = (idx + 1).toString()
368
+ return `${num}: ${ln}`;
369
+ })
370
+ .join("\n");
371
+ }