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,160 @@
1
+ /**@import { WebGLRenderPipelineDescriptor } from '../../core/index.js' */
2
+ import { CompareFunction, MeshVertexLayout, Shader, WebGLRenderDevice } from "../../core/index.js";
3
+ import { Affine3 } from "../../math/index.js";
4
+ import { PrimitiveTopology, TextureFormat } from "../../constants/index.js";
5
+ import { Bone3D, Object3D, SkeletonHelper } from "../../objects/index.js";
6
+ import { Plugin, WebGLRenderer } from "../../renderer/index.js";
7
+ import { skeletonFragment, skeletonVertex } from "../../shader/index.js";
8
+ import { Texture } from "../../texture/index.js";
9
+
10
+ export class SkeletonHelperPlugin extends Plugin {
11
+
12
+ /**
13
+ * @override
14
+ */
15
+ preprocess() { }
16
+
17
+ /**
18
+ * @type {number | undefined}
19
+ */
20
+ pipelineId
21
+ /**
22
+ * @param {Object3D} object
23
+ * @param {WebGLRenderDevice} device
24
+ * @param {WebGLRenderer} renderer
25
+ */
26
+ renderObject3D(object, device, renderer) {
27
+ if (!(object instanceof SkeletonHelper) || !object.skinnedMesh.skin) {
28
+ return
29
+ }
30
+ const { caches } = renderer
31
+ const { bones, boneTexture } = object.skinnedMesh.skin
32
+ const pipeline = this.getRenderPipeline(device, renderer)
33
+ const transformsInfo = pipeline.uniforms.get("transforms")
34
+ const modelInfo = pipeline.uniforms.get("model")
35
+ const parentInfo = pipeline.uniforms.get("parent_index")
36
+ const childInfo = pipeline.uniforms.get("child_index")
37
+ const pass = device.beginRenderPass()
38
+ pass.setPipeline(pipeline)
39
+
40
+ if (
41
+ !transformsInfo || transformsInfo.texture_unit === undefined ||
42
+ !modelInfo || !parentInfo || !childInfo) {
43
+ console.warn("uniforms are not set up correctly in shader")
44
+ return
45
+ }
46
+
47
+ updateDataTexture(boneTexture, bones.map((bone) => bone.transform.world))
48
+
49
+ const transformsTexture = caches.getTexture(device, boneTexture)
50
+
51
+
52
+ device.context.activeTexture(WebGL2RenderingContext.TEXTURE0 + transformsInfo.texture_unit)
53
+ device.context.bindTexture(boneTexture.type, transformsTexture.inner)
54
+
55
+ device.context.uniformMatrix4fv(modelInfo.location, false, [...Affine3.toMatrix4(object.skinnedMesh.transform.world)])
56
+ device.context.bindVertexArray(null)
57
+
58
+ object.rootBone.traverseBFS((parent) => {
59
+ if (parent instanceof Bone3D) {
60
+ for (let i = 0; i < parent.children.length; i++) {
61
+ const child = parent.children[i]
62
+ if (child instanceof Bone3D) {
63
+ const childIndex = child.index
64
+ const parentIndex = parent.index
65
+ device.context.uniform1ui(parentInfo.location, parentIndex)
66
+ device.context.uniform1ui(childInfo.location, childIndex)
67
+ device.context.drawArrays(PrimitiveTopology.Lines, 0, 2)
68
+ }
69
+ }
70
+ }
71
+ return true
72
+ })
73
+ pass.end()
74
+ }
75
+
76
+ /**
77
+ * @param {WebGLRenderDevice} device
78
+ * @param {WebGLRenderer} renderer
79
+ */
80
+ getRenderPipeline(device, renderer) {
81
+ const { caches, includes, defines: globalDefines } = renderer
82
+ if (this.pipelineId) {
83
+ const pipeline = caches.getRenderPipeline(this.pipelineId)
84
+
85
+ if (pipeline) {
86
+ return pipeline
87
+ }
88
+ }
89
+
90
+ /**
91
+ * @type {WebGLRenderPipelineDescriptor}
92
+ */
93
+ const descriptor = {
94
+ depthWrite: false,
95
+ depthCompare: CompareFunction.Always,
96
+ topology: PrimitiveTopology.Lines,
97
+ vertexLayout: new MeshVertexLayout([]),
98
+ vertex: new Shader({
99
+ source: skeletonVertex
100
+ }),
101
+ fragment: {
102
+ source: new Shader({
103
+ source: skeletonFragment
104
+ }),
105
+ targets: [{
106
+ format: TextureFormat.RGBA8Unorm
107
+ }]
108
+ }
109
+ }
110
+
111
+ for (const [name, value] of globalDefines) {
112
+ descriptor.vertex.defines.set(name, value)
113
+ descriptor.fragment?.source?.defines?.set(name, value)
114
+ }
115
+ for (const [name, value] of includes) {
116
+ descriptor.vertex.includes.set(name, value)
117
+ descriptor.fragment?.source?.includes?.set(name, value)
118
+ }
119
+ const [newRenderPipeline, newId] = caches.createRenderPipeline(device, descriptor)
120
+
121
+ this.pipelineId = newId
122
+ return newRenderPipeline
123
+ }
124
+ }
125
+
126
+ // NOTE: This could be expanded to pack numbers, vectors, matrices and affines
127
+ /**
128
+ * @param {Texture} texture
129
+ * @param {Affine3[]} items
130
+ */
131
+ function updateDataTexture(texture, items) {
132
+ const data = new Float32Array(items.length * 16)
133
+
134
+ for (let i = 0; i < items.length; i++) {
135
+ const offset = i * 16
136
+ const world = /**@type {Affine3} */(items[i])
137
+
138
+ data[offset + 0] = world.a
139
+ data[offset + 1] = world.b
140
+ data[offset + 2] = world.c
141
+ data[offset + 3] = 0
142
+ data[offset + 4] = world.d
143
+ data[offset + 5] = world.e
144
+ data[offset + 6] = world.f
145
+ data[offset + 7] = 0
146
+ data[offset + 8] = world.g
147
+ data[offset + 9] = world.h
148
+ data[offset + 10] = world.i
149
+ data[offset + 11] = 0
150
+ data[offset + 12] = world.x
151
+ data[offset + 13] = world.y
152
+ data[offset + 14] = world.z
153
+ data[offset + 15] = 1
154
+ }
155
+
156
+ // TODO: Use the entire dimensions of the texture to pack values
157
+ texture.width = 4
158
+ texture.height = items.length
159
+ texture.data = data.buffer
160
+ }
@@ -0,0 +1,3 @@
1
+ export * from './skybox.js'
2
+ export * from './nodes/index.js'
3
+ export * from './resources/index.js'
@@ -0,0 +1 @@
1
+ export * from "./skybox.js"
@@ -0,0 +1,143 @@
1
+ /**@import { GPUTexture, WebGLRenderPipelineDescriptor } from '../../../core/index.js' */
2
+ import { CompareFunction, MeshVertexLayout, Shader } from "../../../core/index.js"
3
+ import { CullFace, PrimitiveTopology, TextureFormat } from "../../../constants/index.js"
4
+ import { Camera, Object3D, SkyBox } from "../../../objects/index.js"
5
+ import { RenderItem, Views } from "../../../renderer/index.js"
6
+ import { skyboxFragment, skyboxVertex } from "../../../shader/index.js"
7
+ import { assert } from "../../../utils/index.js"
8
+ import { SkyboxPipeline, SkyBoxMesh } from "../resources/index.js"
9
+
10
+ export class SkyBoxNode {
11
+ subgraph() {
12
+ return undefined
13
+ }
14
+
15
+ /**
16
+ * @param {import("../../../renderer/graph/index.js").RenderGraphContext} context
17
+ */
18
+ execute(context) {
19
+ const { renderer, renderDevice, objects } = context
20
+ const views = renderer.getResource(Views)
21
+
22
+ assert(views, "Views resource missing")
23
+
24
+ for (const view of views.items()) {
25
+ if (view.tag !== Camera.name) {
26
+ continue
27
+ }
28
+
29
+ const opaqueStage = view.renderStage.opaque || []
30
+ view.renderStage.opaque = opaqueStage
31
+
32
+ for (let i = 0; i < objects.length; i++) {
33
+ // SAFETY: Asssume the list is dense
34
+ const object = /**@type {Object3D}*/(objects[i])
35
+
36
+ object.traverseDFS((child) => {
37
+ if (!child.renderMask.test(view.renderMask)) {
38
+ return true
39
+ }
40
+
41
+ if (!(child instanceof SkyBox)) {
42
+ return true
43
+ }
44
+ const item = createSkyboxRenderItem(child, renderDevice, renderer)
45
+
46
+ opaqueStage.push(item)
47
+
48
+ return true
49
+ })
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * @param {SkyBox} object
57
+ * @param {import("../../../core/index.js").WebGLRenderDevice} device
58
+ * @param {import("../../../renderer/index.js").WebGLRenderer} renderer
59
+ * @returns {RenderItem}
60
+ */
61
+ function createSkyboxRenderItem(object, device, renderer) {
62
+ const skyboxMesh = renderer.getResource(SkyBoxMesh)
63
+
64
+ assert(skyboxMesh, "SkyBoxMesh resource missing")
65
+ const mesh = renderer.caches.getMesh(device, skyboxMesh.cube, renderer.attributes)
66
+ /** @type {{ lerp: number, day: GPUTexture | undefined, night: GPUTexture | undefined }} */
67
+ const uniforms = {
68
+ lerp: object.lerp,
69
+ day: undefined,
70
+ night: undefined
71
+ }
72
+
73
+ if (object.day) {
74
+ const dayTex = renderer.caches.getTexture(device, object.day)
75
+
76
+ uniforms.day = dayTex
77
+ }
78
+ if (object.night) {
79
+ const nightTex = renderer.caches.getTexture(device, object.night)
80
+
81
+ uniforms.night = nightTex
82
+ }
83
+ const item = new RenderItem({
84
+ pipelineId: getSkyboxRenderPipeline(device, renderer),
85
+ uniforms,
86
+ tag: SkyBox.name,
87
+ transform: object.transform.world,
88
+ mesh
89
+ })
90
+
91
+ return item
92
+ }
93
+
94
+ /**
95
+ * @param {import("../../../core/index.js").WebGLRenderDevice} device
96
+ * @param {import("../../../renderer/index.js").WebGLRenderer} renderer
97
+ */
98
+ function getSkyboxRenderPipeline(device, renderer) {
99
+ const skyboxPipeline = renderer.getResource(SkyboxPipeline)
100
+ const { caches, includes, defines: globalDefines } = renderer
101
+
102
+ assert(skyboxPipeline, "SkyboxPipeline resource missing")
103
+
104
+ if (skyboxPipeline.pipelineId !== undefined) {
105
+ return skyboxPipeline.pipelineId
106
+ }
107
+ /**
108
+ * @type {WebGLRenderPipelineDescriptor}
109
+ */
110
+ const descriptor = {
111
+ depthWrite: false,
112
+ depthCompare: CompareFunction.Lequal,
113
+ cullFace: CullFace.Front,
114
+ topology: PrimitiveTopology.Triangles,
115
+ vertexLayout: new MeshVertexLayout([]),
116
+ vertex: new Shader({
117
+ source: skyboxVertex
118
+ }),
119
+ fragment: {
120
+ source: new Shader({
121
+ source: skyboxFragment
122
+ }),
123
+ targets: [{
124
+ format: TextureFormat.RGBA8Unorm
125
+ }]
126
+ }
127
+ }
128
+
129
+ for (const [name, value] of globalDefines) {
130
+ descriptor.vertex.defines.set(name, value)
131
+ descriptor.fragment?.source?.defines?.set(name, value)
132
+ }
133
+ for (const [name, value] of includes) {
134
+ descriptor.vertex.includes.set(name, value)
135
+ descriptor.fragment?.source?.includes?.set(name, value)
136
+ }
137
+
138
+ const [_, newId] = caches.createRenderPipeline(device, descriptor)
139
+
140
+ skyboxPipeline.pipelineId = newId
141
+
142
+ return newId
143
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./skyboxpipeline.js"
2
+ export * from "./skyboxmesh.js"
@@ -0,0 +1,14 @@
1
+ import { CuboidMeshBuilder } from "../../../mesh/index.js";
2
+
3
+ export class SkyBoxMesh {
4
+ cube
5
+
6
+ constructor() {
7
+ const cuboid = new CuboidMeshBuilder()
8
+ cuboid.width = 1
9
+ cuboid.height = 1
10
+ cuboid.depth = 1
11
+
12
+ this.cube = cuboid.build()
13
+ }
14
+ }
@@ -0,0 +1,6 @@
1
+ export class SkyboxPipeline {
2
+ /**
3
+ * @type {number | undefined}
4
+ */
5
+ pipelineId
6
+ }
@@ -0,0 +1,137 @@
1
+ /**@import { GPUTexture, WebGLRenderDevice, WebGLRenderPipeline } from '../../core/index.js' */
2
+ import { Matrix4 } from "../../math/index.js";
3
+ import { TextureFilter } from "../../constants/index.js";
4
+ import { SkyBox } from "../../objects/index.js";
5
+ import { Plugin, SortViewsNode, WebGLRenderer } from "../../renderer/index.js";
6
+ import { Sampler } from "../../texture/index.js";
7
+ import { SkyboxPipeline, SkyBoxMesh } from "./resources/index.js";
8
+ import { SkyBoxNode } from "./nodes/index.js";
9
+ import { CameraViewNode } from "../camera/index.js";
10
+
11
+ export class SkyboxPlugin extends Plugin {
12
+ /**
13
+ * @override
14
+ * @param {WebGLRenderer} renderer
15
+ */
16
+ init(renderer) {
17
+ renderer.setResource(new SkyboxPipeline())
18
+ renderer.setResource(new SkyBoxMesh())
19
+ renderer.uniformBinders.set(SkyBox.name, uploadUniforms)
20
+ renderer.renderGraph.addNode(SkyBoxNode.name, new SkyBoxNode())
21
+ renderer.renderGraph.addDependency(CameraViewNode.name, SkyBoxNode.name)
22
+ renderer.renderGraph.addDependency(SkyBoxNode.name, SortViewsNode.name)
23
+ }
24
+ }
25
+
26
+ export class SkyBoxGroup {
27
+ /**
28
+ * @type {GPUTexture | undefined}
29
+ */
30
+ day
31
+ /**
32
+ * @type {GPUTexture | undefined}
33
+ */
34
+ night
35
+ /**
36
+ * @type {number}
37
+ */
38
+ lerp = 0
39
+
40
+ /**
41
+ * @param {number} lerp
42
+ * @param {GPUTexture} [day]
43
+ * @param {GPUTexture} [night]
44
+ */
45
+ constructor(lerp, day, night) {
46
+ this.day = day
47
+ this.night = night
48
+ this.lerp = lerp
49
+ }
50
+ }
51
+
52
+ /**
53
+ * @param {WebGLRenderDevice} device
54
+ * @param {WebGLRenderer} renderer
55
+ * @param {WebGLRenderPipeline} pipeline
56
+ * @param {SkyBoxGroup} bindGroup
57
+ * @param {Matrix4} transform
58
+ */
59
+ function uploadUniforms(device, renderer, pipeline, bindGroup, transform) {
60
+ const { day, night, lerp } = bindGroup
61
+ const modelInfo = pipeline.uniforms.get("model")
62
+ const dayInfo = pipeline.uniforms.get("day")
63
+ const nightInfo = pipeline.uniforms.get("night")
64
+ const lerpInfo = pipeline.uniforms.get("lerp")
65
+
66
+ if (modelInfo) {
67
+ device.context.uniformMatrix4fv(modelInfo.location, false, new Float32Array([...transform]))
68
+ }
69
+
70
+ if (day && dayInfo && dayInfo.texture_unit !== undefined) {
71
+ device.context.activeTexture(WebGL2RenderingContext.TEXTURE0 + dayInfo.texture_unit)
72
+ device.context.bindTexture(day.type, day.inner)
73
+ updateTextureSampler(device.context, day, renderer.defaults.textureSampler)
74
+ }
75
+
76
+ if (night && nightInfo && nightInfo.texture_unit !== undefined) {
77
+ device.context.activeTexture(WebGL2RenderingContext.TEXTURE0 + nightInfo.texture_unit)
78
+ device.context.bindTexture(night.type, night.inner)
79
+ updateTextureSampler(device.context, night, renderer.defaults.textureSampler)
80
+ }
81
+
82
+ if (lerpInfo) {
83
+ device.context.uniform1f(lerpInfo.location, lerp)
84
+ }
85
+ }
86
+
87
+ /**
88
+ * @param {WebGL2RenderingContext} context
89
+ * @param {GPUTexture} texture
90
+ * @param {Sampler} sampler
91
+ */
92
+ function updateTextureSampler(context, texture, sampler) {
93
+ const lod = sampler.lod
94
+ const anisotropyExtenstion = context.getExtension("EXT_texture_filter_anisotropic")
95
+
96
+ context.texParameteri(texture.type, context.TEXTURE_MAG_FILTER, sampler.magnificationFilter)
97
+ context.texParameteri(texture.type, context.TEXTURE_WRAP_S, sampler.wrapS)
98
+ context.texParameteri(texture.type, context.TEXTURE_WRAP_T, sampler.wrapT)
99
+ context.texParameteri(texture.type, context.TEXTURE_WRAP_R, sampler.wrapR)
100
+
101
+ if (lod) {
102
+ context.texParameteri(texture.type, context.TEXTURE_MIN_LOD, lod.min)
103
+ context.texParameteri(texture.type, context.TEXTURE_MAX_LOD, lod.max)
104
+ }
105
+
106
+ if (sampler.mipmapFilter !== undefined) {
107
+ if (sampler.minificationFilter === TextureFilter.Linear) {
108
+ if (sampler.mipmapFilter === TextureFilter.Linear) {
109
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.LINEAR_MIPMAP_LINEAR);
110
+ } else if (sampler.mipmapFilter === TextureFilter.Nearest) {
111
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.LINEAR_MIPMAP_NEAREST);
112
+ }
113
+ } else if (sampler.minificationFilter === TextureFilter.Nearest) {
114
+ if (sampler.mipmapFilter === TextureFilter.Linear) {
115
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.NEAREST_MIPMAP_LINEAR);
116
+ } else if (sampler.mipmapFilter === TextureFilter.Nearest) {
117
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.NEAREST_MIPMAP_NEAREST);
118
+ }
119
+ }
120
+ } else {
121
+ if (sampler.minificationFilter === TextureFilter.Nearest) {
122
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.NEAREST)
123
+ } else if (sampler.minificationFilter === TextureFilter.Linear) {
124
+ context.texParameteri(texture.type, context.TEXTURE_MIN_FILTER, context.LINEAR)
125
+ }
126
+ }
127
+ if (anisotropyExtenstion) {
128
+ context.texParameterf(texture.type, anisotropyExtenstion.TEXTURE_MAX_ANISOTROPY_EXT, sampler.anisotropy)
129
+ }
130
+
131
+ if (sampler.compare !== undefined) {
132
+ context.texParameteri(texture.type, context.TEXTURE_COMPARE_MODE, context.COMPARE_REF_TO_TEXTURE);
133
+ context.texParameteri(texture.type, context.TEXTURE_COMPARE_FUNC, sampler.compare)
134
+ } else {
135
+ context.texParameteri(texture.type, context.TEXTURE_COMPARE_MODE, context.NONE);
136
+ }
137
+ }
@@ -0,0 +1,179 @@
1
+ import { GPUMesh } from "../../core/index.js"
2
+ import { Affine3, Matrix4, Vector3 } from "../../math/index.js"
3
+ import { Object3D, RenderMask } from "../../objects/index.js"
4
+ import { RenderTarget } from "../../rendertarget/index.js"
5
+
6
+ export class View {
7
+ /**
8
+ * @type {RenderStages}
9
+ */
10
+ renderStage = new RenderStages()
11
+ /**
12
+ * @type {number}
13
+ */
14
+ order = 0
15
+ /**
16
+ * @type {RenderTarget}
17
+ */
18
+ renderTarget
19
+
20
+ /**
21
+ * @type {Matrix4}
22
+ */
23
+ projectionMatrix
24
+
25
+ /**
26
+ * @type {Matrix4}
27
+ */
28
+ viewMatrix
29
+
30
+ /**
31
+ * @type {Vector3}
32
+ */
33
+ viewPosition
34
+
35
+ /**
36
+ * @type {number}
37
+ */
38
+ near
39
+
40
+ /**
41
+ * @type {number}
42
+ */
43
+ far
44
+
45
+ /**
46
+ * @type {string}
47
+ */
48
+ tag
49
+ /**
50
+ * Render mask used to filter visible objects for this view.
51
+ * @type {RenderMask}
52
+ */
53
+ renderMask = new RenderMask()
54
+ /**
55
+ * Source object that created this view.
56
+ * @type {Object3D | undefined}
57
+ */
58
+ object
59
+
60
+ /**
61
+ * @param {ViewOptions} options
62
+ */
63
+ constructor({
64
+ renderTarget,
65
+ position,
66
+ projection,
67
+ view,
68
+ near,
69
+ far,
70
+ tag,
71
+ object,
72
+ renderMask = new RenderMask()
73
+ }) {
74
+ this.renderTarget = renderTarget
75
+ this.near = near
76
+ this.far = far
77
+ this.tag = tag
78
+ this.projectionMatrix = projection
79
+ this.viewMatrix = view
80
+ this.viewPosition = position
81
+ this.object = object
82
+ this.renderMask.copy(renderMask)
83
+ }
84
+
85
+ getData() {
86
+ return {
87
+ name: "CameraBlock",
88
+ data: new Float32Array([
89
+ ...this.viewMatrix,
90
+ ...this.projectionMatrix,
91
+ ...this.viewPosition,
92
+ this.near,
93
+ this.far
94
+ ]).buffer
95
+ }
96
+ }
97
+ }
98
+
99
+ export class RenderStages {
100
+ /**
101
+ * @type {RenderItem[] | undefined}
102
+ */
103
+ opaque
104
+ }
105
+ export class RenderItem {
106
+
107
+ /**
108
+ * @type {number}
109
+ */
110
+ pipelineId
111
+
112
+ /**
113
+ * @type {GPUMesh}
114
+ */
115
+ mesh
116
+
117
+ /**
118
+ * @type {Record<string, any>}
119
+ */
120
+ uniforms
121
+
122
+ /**
123
+ * @type {string}
124
+ */
125
+ tag
126
+
127
+ /**
128
+ * @type {Affine3}
129
+ */
130
+ transform
131
+
132
+ /**
133
+ * @param {RenderItemOptions} options
134
+ */
135
+ constructor({
136
+ pipelineId,
137
+ mesh,
138
+ tag,
139
+ uniforms,
140
+ transform
141
+ }) {
142
+ this.pipelineId = pipelineId
143
+ this.transform = transform
144
+ this.mesh = mesh
145
+ this.tag = tag
146
+ this.uniforms = uniforms
147
+ }
148
+ }
149
+
150
+ /**
151
+ * @typedef ViewOptions
152
+ * @property {RenderTarget} renderTarget
153
+ * @property {Vector3} position
154
+ * @property {Matrix4} projection
155
+ * @property {Matrix4} view
156
+ * @property {number} near
157
+ * @property {number} far
158
+ * @property {string} tag
159
+ * @property {Object3D} [object]
160
+ * @property {RenderMask} [renderMask]
161
+ */
162
+
163
+ /**
164
+ * @typedef RenderItemOptions
165
+ * @property {Affine3} transform
166
+ * @property {GPUMesh} mesh
167
+ * @property {number} pipelineId
168
+ * @property {Record<string, any>} uniforms
169
+ * @property {string} tag
170
+ */
171
+
172
+ /**
173
+ * @callback UniformBinder
174
+ * @param {WebGLRenderDevice} device
175
+ * @param {WebGLRenderer} renderer
176
+ * @param {WebGLRenderPipeline} pipeline
177
+ * @param {any} bindGroup
178
+ * @param {Matrix4} transform
179
+ */
@@ -0,0 +1,3 @@
1
+ export * from "./rendergraph.js"
2
+ export * from "./nodes.js"
3
+
@@ -0,0 +1,34 @@
1
+ /** @import { RenderGraphContext } from "./rendergraph.js" */
2
+ import { assert } from "../../utils/index.js"
3
+ import { Views } from "../views.js"
4
+
5
+ export class SortViewsNode {
6
+ subgraph() {
7
+ return undefined
8
+ }
9
+
10
+ /**
11
+ * @param {RenderGraphContext} context
12
+ */
13
+ execute(context) {
14
+ const views = context.renderer.getResource(Views)
15
+
16
+ assert(views, "Views resource missing")
17
+
18
+ const sorted = views.items()
19
+ .map((view, index) => ({ view, index }))
20
+ .sort((a, b) => {
21
+ const order = a.view.order - b.view.order
22
+
23
+ if (order !== 0) {
24
+ return order
25
+ }
26
+
27
+ return a.index - b.index
28
+ })
29
+ .map((entry) => entry.view)
30
+
31
+ views.clear()
32
+ views.push(...sorted)
33
+ }
34
+ }