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,138 @@
1
+ ---
2
+ title: "Materials and Lighting"
3
+ ---
4
+
5
+ # Materials and Lighting
6
+
7
+ This guide assumes you already have a working scene from [First Scene](/guide/first-scene).
8
+ Here, you will add lit materials and light objects in small steps.
9
+
10
+ ## What You Will Add
11
+
12
+ - a material choice based on visual style
13
+ - renderer plugins required for lighting
14
+ - ambient light for base visibility
15
+ - one direct light source
16
+ - a render list that includes lights
17
+
18
+ ## Step 1: Import Material and Light APIs
19
+
20
+ ```js
21
+ import {
22
+ BasicMaterial,
23
+ LambertMaterial,
24
+ PhongMaterial,
25
+ StandardMaterial,
26
+ AmbientLight,
27
+ DirectionalLight,
28
+ LightPlugin
29
+ } from "chorama";
30
+ ```
31
+
32
+ Use `BasicMaterial` when you do not need scene lighting.
33
+ Use `LambertMaterial`, `PhongMaterial`, or `StandardMaterial` when you want lights to affect the surface.
34
+
35
+ ## Step 2: Pick a Material Model
36
+
37
+ ```js
38
+ const basic = new BasicMaterial();
39
+ const lambert = new LambertMaterial();
40
+ const phong = new PhongMaterial();
41
+ const standard = new StandardMaterial({ roughness: 0.5, metallic: 0.1 });
42
+ ```
43
+
44
+ Quick guidance:
45
+
46
+ - `BasicMaterial`: unlit shading
47
+ - `LambertMaterial`: diffuse lit shading
48
+ - `PhongMaterial`: diffuse + specular highlight shading
49
+ - `StandardMaterial`: physically-based roughness/metallic shasing
50
+
51
+ For a first lit scene, start with `LambertMaterial`.
52
+
53
+ ## Step 3: Apply the Material to Your Mesh Object
54
+
55
+ ```js
56
+ const object = new MeshMaterial3D(mesh, lambert);
57
+ ```
58
+ The second parameter can be any of the materials shown in the previous step.
59
+ If you keep `BasicMaterial` as the material of the object, lights will not change the object's appearance.
60
+
61
+ ## Step 4: Enable the Lighting Pipeline in the Renderer
62
+
63
+ ```js
64
+ const renderer = new WebGLRenderer({
65
+ plugins: [
66
+ new LightPlugin(),
67
+ new MeshMaterialPlugin(),
68
+ new CameraPlugin()
69
+ ]
70
+ });
71
+ ```
72
+
73
+ `LightPlugin` must be present on the renderer for lit materials to respond to lights.
74
+
75
+ ## Step 5: Add Ambient Light
76
+
77
+ ```js
78
+ const ambient = new AmbientLight();
79
+ ambient.intensity = 0.15;
80
+ ```
81
+
82
+ Ambient light gives a soft base so unlit sides are still visible.
83
+ It is used to approximate indirect lighting for the entire scene.
84
+ Keep this low so directional/point/spot lights can affect the object's appearance.
85
+
86
+ ## Step 6: Add a Directional Light
87
+
88
+ ```js
89
+ const sun = new DirectionalLight();
90
+ sun.intensity = 1.0;
91
+ sun.transform.orientation.rotateX(-Math.PI / 4);
92
+ sun.transform.orientation.rotateZ(-Math.PI / 4);
93
+ ```
94
+
95
+ Directional light is a good first light because it is simple and predictable.
96
+ It behaves like a distant light source with parallel rays. In this case, the light
97
+ will point downwards onto the scene.
98
+
99
+ ## Step 7: Render with Object, Lights, and Camera
100
+
101
+ ```js
102
+ renderer.render([object, ambient, sun, camera], device);
103
+ ```
104
+
105
+ Your render list must include light objects each frame.
106
+ If lights are missing from the list, lit materials may look black or flat.
107
+
108
+ ## Step 8: Animate and Keep Scene Responsive
109
+
110
+ ```js
111
+ function frame() {
112
+ renderer.render([object, ambient, sun, camera], device);
113
+ requestAnimationFrame(frame);
114
+ }
115
+
116
+ requestAnimationFrame(frame);
117
+ ```
118
+
119
+ Keep your existing resize handler from [First Scene](/guide/first-scene).
120
+ Perspective scenes still require `camera.projection.aspect` updates on resize.
121
+
122
+ ## Switching Between Material Types
123
+
124
+ You can swap material at runtime to compare look and performance:
125
+
126
+ ```js
127
+ object.material = phong;
128
+ // object.material = standard;
129
+ // object.material = lambert;
130
+ ```
131
+
132
+ ## Reference Examples
133
+
134
+ - [Directional Light](/examples/lights/directional)
135
+ - [Point Light](/examples/lights/point)
136
+ - [Spot Light](/examples/lights/spot)
137
+
138
+ After this works, continue with [Textures and Assets](/guide/textures-and-assets)
@@ -0,0 +1,124 @@
1
+ ---
2
+ title: "Plugins and Render Pipeline"
3
+ ---
4
+
5
+ # Plugins and Render Pipeline
6
+
7
+ This renderer is plugin-driven.
8
+ Plugins discover scene objects, prepare render data, and contribute render work.
9
+
10
+ ## What You Will Add
11
+
12
+ - a plugin stack for your renderer
13
+ - a clear plugin order strategy
14
+
15
+ ## Step 1: Import Core Renderer and Plugins
16
+
17
+ ```js
18
+ import {
19
+ WebGLRenderer,
20
+ CameraPlugin,
21
+ MeshMaterialPlugin,
22
+ LightPlugin,
23
+ ShadowPlugin,
24
+ SkyboxPlugin
25
+ } from "chorama";
26
+ ```
27
+
28
+ Start with the smallest plugin set your scene needs.
29
+ Add others only when features require them.
30
+
31
+ ## Step 2: Build a Minimal Plugin Stack
32
+
33
+ ```js
34
+ const renderer = new WebGLRenderer({
35
+ plugins: [
36
+ new MeshMaterialPlugin(),
37
+ new CameraPlugin()
38
+ ]
39
+ });
40
+ ```
41
+
42
+ This stack is enough for camera + mesh/material scenes without lighting.
43
+
44
+ ## Step 3: Add Lighting Support
45
+
46
+ ```js
47
+ const renderer = new WebGLRenderer({
48
+ plugins: [
49
+ new LightPlugin(),
50
+ new MeshMaterialPlugin(),
51
+ new CameraPlugin()
52
+ ]
53
+ });
54
+ ```
55
+
56
+ `LightPlugin` provides light uniform data for lit shaders.
57
+ Without it, lit materials may render incorrectly.
58
+
59
+ ## Step 4: Add Shadows and Skybox When Needed
60
+
61
+ ```js
62
+ const renderer = new WebGLRenderer({
63
+ plugins: [
64
+ new ShadowPlugin(),
65
+ new LightPlugin(),
66
+ new SkyboxPlugin(),
67
+ new MeshMaterialPlugin(),
68
+ new CameraPlugin()
69
+ ]
70
+ });
71
+ ```
72
+
73
+ Use this fuller stack only when your scene needs shadows/skybox.
74
+ It is heavier than the minimal stack.
75
+
76
+ ## Step 5: Render as Usual
77
+
78
+ ```js
79
+ renderer.render(objects, device);
80
+ ```
81
+
82
+ The pipeline stays behind this single call.
83
+ You choose behavior by changing plugins and scene objects.
84
+
85
+ ## What Happens During `render()`
86
+
87
+ High-level flow:
88
+
89
+ 1. Object transforms are updated through scene traversal.
90
+ 2. Each plugin preprocesses scene data.
91
+ 3. Plugins contribute views/render items.
92
+ 4. Views are sorted and rendered.
93
+
94
+ This is why missing plugins often look like "nothing happens" rather than hard errors.
95
+
96
+ ## Plugin Roles
97
+
98
+ - `CameraPlugin`: creates camera views and per-view camera data.
99
+ - `MeshMaterialPlugin`: converts `MeshMaterial3D` objects into draw items.
100
+ - `LightPlugin`: collects light objects and uploads light blocks.
101
+ - `ShadowPlugin`: builds shadow passes/resources for shadow-casting lights.
102
+ - `SkyboxPlugin`: adds skybox rendering behavior.
103
+
104
+ ## Create a Custom Plugin
105
+
106
+ ```js
107
+ class MyPlugin extends Plugin {
108
+ init(renderer) {
109
+ // register resources, shader defines, or view fillers
110
+ }
111
+
112
+ preprocess(objects, device, renderer) {
113
+ // inspect scene, prepare data, push views/resources
114
+ }
115
+
116
+ getRenderItem(object, device, renderer) {
117
+ // return a render item for supported object types
118
+ return undefined;
119
+ }
120
+ }
121
+ ```
122
+
123
+ A custom plugin should solve one focused concern.
124
+ Avoid mixing unrelated responsibilities in one plugin.
@@ -0,0 +1,147 @@
1
+ ---
2
+ title: "Render Targets and Views"
3
+ ---
4
+
5
+ # Render Targets and Views
6
+
7
+ This guide assumes you already have a scene rendering from [First Scene](/guide/first-scene).
8
+ Here, we focus on where the camera renders and how to split output.
9
+
10
+ ## What You Will Add
11
+
12
+ - a canvas render target
13
+ - an offscreen image render target
14
+ - viewport/scissor based view layouts
15
+
16
+ ## Step 1: Import Render Target APIs
17
+
18
+ ```js
19
+ import {
20
+ CanvasTarget,
21
+ ImageRenderTarget,
22
+ ViewRectangle,
23
+ Texture,
24
+ TextureType,
25
+ TextureFormat,
26
+ Camera
27
+ } from "chorama";
28
+ ```
29
+
30
+ Use `CanvasTarget` for on-screen output.
31
+ Use `ImageRenderTarget` for offscreen passes.
32
+
33
+ ## Step 2: Create a Canvas Target (Most Common)
34
+
35
+ ```js
36
+ const canvasTarget = new CanvasTarget(canvas);
37
+ const camera = new Camera(canvasTarget);
38
+ ```
39
+
40
+ This is the default path for rendering directly to the page.
41
+
42
+ ## Step 3: Render a Scene to the Canvas Target
43
+
44
+ ```js
45
+ renderer.render([object, camera], device);
46
+ ```
47
+
48
+ If your scene is blank, first confirm the camera uses the expected target.
49
+
50
+ ## Step 4: Create an Offscreen Image Target
51
+
52
+ ```js
53
+ const imageTarget = new ImageRenderTarget({
54
+ width: 1024,
55
+ height: 1024,
56
+ color: [
57
+ new Texture({
58
+ type: TextureType.Texture2D,
59
+ format: TextureFormat.RGBA8Unorm,
60
+ width: 1024,
61
+ height: 1024
62
+ })
63
+ ],
64
+ internalDepthStencil: TextureFormat.Depth24PlusStencil8
65
+ });
66
+ ```
67
+
68
+ This creates a texture-backed target you can render into.
69
+
70
+ ## Step 5: Render Offscreen with a Dedicated Camera
71
+
72
+ ```js
73
+ const offscreenCamera = new Camera(imageTarget);
74
+ renderer.render([offscreenObject, offscreenCamera], device);
75
+ ```
76
+
77
+ Use a separate camera when offscreen pass framing differs from main pass.
78
+
79
+ ## Step 6: Use Offscreen Output as a Texture
80
+
81
+ ```js
82
+ const screenObject = new MeshMaterial3D(
83
+ mesh,
84
+ new BasicMaterial({ mainTexture: imageTarget.color[0] })
85
+ );
86
+
87
+ renderer.render([screenObject, camera], device);
88
+ ```
89
+
90
+ This is the core pattern for mirrors, portals, and postprocessing chains.
91
+
92
+ ## Step 7: Split Canvas with Viewports
93
+
94
+ Use multiple `CanvasTarget` instances on the same canvas.
95
+
96
+ ```js
97
+ const leftTarget = new CanvasTarget(canvas);
98
+ const rightTarget = new CanvasTarget(canvas);
99
+
100
+ leftTarget.viewport.offset.set(0, 0);
101
+ leftTarget.viewport.size.set(0.5, 1);
102
+
103
+ rightTarget.viewport.offset.set(0.5, 0);
104
+ rightTarget.viewport.size.set(0.5, 1);
105
+ ```
106
+
107
+ Viewport values are normalized (0 to 1) relative to full canvas size.
108
+
109
+ ## Step 8: Bind Cameras to Each View and Render
110
+
111
+ ```js
112
+ const leftCamera = new Camera(leftTarget);
113
+ const rightCamera = new Camera(rightTarget);
114
+
115
+ renderer.render([scene, leftCamera], device);
116
+ renderer.render([scene, rightCamera], device);
117
+ ```
118
+
119
+ This gives independent camera views in a single canvas.
120
+
121
+ ## Step 9: Use Scissor for Hard Split/Masking
122
+
123
+ ```js
124
+ leftTarget.scissor = new ViewRectangle();
125
+ rightTarget.scissor = new ViewRectangle();
126
+
127
+ leftTarget.scissor.offset.set(0, 0);
128
+ leftTarget.scissor.size.set(0.5, 1);
129
+
130
+ rightTarget.scissor.offset.set(0.5, 0);
131
+ rightTarget.scissor.size.set(0.5, 1);
132
+ ```
133
+
134
+ Scissor restricts actual draw area, useful for editor layouts and split bars.
135
+
136
+ ## Resize Rule for Multi-View Scenes
137
+
138
+ Keep canvas size and camera projection in sync on resize.
139
+ For split views, compute aspect per view region (not full canvas).
140
+
141
+ ## Reference Examples
142
+
143
+ - [Basic Canvas Target](/examples/rendertarget/basic_canvas)
144
+ - [Image Target](/examples/rendertarget/image_target)
145
+ - [Split Screen](/examples/rendertarget/split_screen)
146
+ - [Multiple Views](/examples/rendertarget/multiple_views)
147
+ - [Split View](/examples/rendertarget/split_view)
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: "Scene Graph and Transforms"
3
+ ---
4
+
5
+ # Scene Graph and Transforms
6
+
7
+ This guide assumes you already have a running scene from [First Scene](/guide/first-scene).
8
+ Here, we focus on parent-child relationships and transform behavior.
9
+
10
+ ## What You Will Add
11
+
12
+ - a parent object
13
+ - one or more child objects
14
+ - local transforms per node
15
+ - frame updates that propagate through hierarchy
16
+
17
+ ## Step 1: Import What You Need
18
+
19
+ ```js
20
+ import { Object3D, MeshMaterial3D, Quaternion } from "chorama";
21
+ ```
22
+
23
+ Use `Object3D` for grouping and transform hierarchy.
24
+ Use `MeshMaterial3D` when the node should be renderable.
25
+
26
+ ## Step 2: Create Parent and Child Nodes
27
+
28
+ ```js
29
+ const root = new Object3D();
30
+ const parent = new MeshMaterial3D(mesh, material);
31
+ const child = new MeshMaterial3D(mesh, material);
32
+ ```
33
+
34
+ `root` is a logical container.
35
+ `parent` and `child` are visible mesh nodes.
36
+
37
+ ## Step 3: Build the Hierarchy
38
+
39
+ ```js
40
+ root.add(parent);
41
+ parent.add(child);
42
+ ```
43
+
44
+ Now `child` inherits `parent` transform changes.
45
+ If parent rotates or moves, child follows automatically.
46
+
47
+ ## Step 4: Set Local Transforms
48
+
49
+ ```js
50
+ parent.transform.position.x = 0;
51
+ child.transform.position.x = 1;
52
+ ```
53
+
54
+ `child.transform.position.x = 1` means "one unit from parent", not world origin.
55
+ Think in local space first when building hierarchies.
56
+
57
+ ## Step 5: Animate the Parent
58
+
59
+ ```js
60
+ const stepRotation = Quaternion.fromEuler(0.01, 0.01, 0.0);
61
+
62
+ function updateScene() {
63
+ parent.transform.orientation.multiply(stepRotation);
64
+ }
65
+ ```
66
+
67
+ Rotating the parent creates orbital motion for the child due to inheritance.
68
+ This is the simplest way to verify propagation is working.
69
+
70
+ ## Step 6: Render the Hierarchy
71
+
72
+ ```js
73
+ function frame() {
74
+ updateScene();
75
+ renderer.render([root, camera], device);
76
+ requestAnimationFrame(frame);
77
+ }
78
+
79
+ requestAnimationFrame(frame);
80
+ ```
81
+
82
+ You can render the root and let traversal include descendants.
83
+ You do not need to pass every child separately if already attached.
84
+
85
+ ## Traverse the Graph for Bulk Operations
86
+
87
+ ```js
88
+ root.traverseDFS((node) => {
89
+ // Example: debug flags, tagging, filtering, or custom updates
90
+ return true;
91
+ });
92
+ ```
93
+
94
+ Use traversal when you need one operation across many descendants.
95
+ Return `true` to continue deeper traversal.
96
+
97
+ ## Reparent Safely
98
+
99
+ ```js
100
+ const newParent = new Object3D();
101
+ root.add(newParent);
102
+ newParent.add(child);
103
+ parent.remove(child);
104
+ ```
105
+
106
+ Reparenting changes which transform chain affects the object.
107
+
108
+ ## Reference Examples
109
+
110
+ - [Transform Propagation](/examples/transform/propagation)
111
+ - [Skinning](/examples/mesh/skinning)
112
+
113
+ After this works, continue with [Render Targets and Views](/guide/render-targets-and-views)
@@ -0,0 +1,120 @@
1
+ ---
2
+ title: "Textures and Assets"
3
+ ---
4
+
5
+ This guide assumes your scene already renders from [First Scene](/guide/first-scene).
6
+ Here, we focus only on bringing external assets into that scene.
7
+
8
+ ## What You Will Add
9
+
10
+ - image textures
11
+ - OBJ models
12
+ - glTF models
13
+ - safe runtime handling while assets stream in
14
+
15
+ ## Step 1: Import Loaders
16
+
17
+ ```js
18
+ import { TextureLoader, OBJLoader, GLTFLoader } from "chorama";
19
+ ```
20
+
21
+ Create one loader instance per asset type and reuse it.
22
+
23
+ ## Step 2: Load a Texture
24
+
25
+ ```js
26
+ const textureLoader = new TextureLoader();
27
+
28
+ const texture = textureLoader.load({
29
+ paths: ["/images/uv.jpg"],
30
+ textureSettings: { flipY: true }
31
+ });
32
+ ```
33
+
34
+ Keep paths relative to your app's static/public asset root.
35
+
36
+ ## Step 3: Apply the Texture to a Material
37
+
38
+ ```js
39
+ const material = new BasicMaterial({
40
+ mainTexture: texture
41
+ });
42
+
43
+ const object = new MeshMaterial3D(mesh, material);
44
+ ```
45
+
46
+ Once assigned, the texture updates automatically when loading completes.
47
+ You can render immediately, no manual onready callback is required for basic flow.
48
+
49
+ ## Step 4: Load an OBJ Model
50
+
51
+ ```js
52
+ const objLoader = new OBJLoader();
53
+
54
+ const objRoot = objLoader.load({
55
+ paths: ["/models/model.obj"]
56
+ });
57
+ ```
58
+
59
+ `objRoot` is available immediately and fills as data arrives.
60
+ You can include it in your render list right away.
61
+
62
+ ## Step 5: Optionally Patch Imported OBJ Materials
63
+
64
+ If you want to force a change across imported meshes, use `postprocessor`.
65
+ An example is to assign a texture to all objects in an obj file
66
+
67
+ ```js
68
+ const objRoot = objLoader.load({
69
+ paths: ["/models/obj/pirate_girl/pirate_girl.obj"],
70
+ postprocessor: (asset) => {
71
+ asset.traverseDFS((node) => {
72
+ if (node instanceof MeshMaterial3D) {
73
+ node.material.mainTexture = texture;
74
+ }
75
+ return true;
76
+ });
77
+ }
78
+ });
79
+ ```
80
+
81
+ ## Step 6: Load a glTF Scene
82
+
83
+ ```js
84
+ const gltfLoader = new GLTFLoader();
85
+
86
+ const sceneRoot = gltfLoader.load({
87
+ paths: ["/models/pirate_girl.gltf"]
88
+ });
89
+ ```
90
+
91
+ Use glTF when you want richer material data and better modern tooling support.
92
+
93
+ ## Step 7: Render Streaming Assets Safely
94
+
95
+ ```js
96
+ function frame() {
97
+ renderer.render([object, objRoot, sceneRoot, camera], device);
98
+ requestAnimationFrame(frame);
99
+ }
100
+
101
+ requestAnimationFrame(frame);
102
+ ```
103
+
104
+ Does not block rendering while waiting for loaders;
105
+ Render continuously with placeholders and loaded data will appear as they become ready.
106
+
107
+ ## Path Rules That Prevent Most Loading Errors
108
+
109
+ 1. Use forward slashes in URLs, even on Windows.
110
+ 2. Use absolute app-root paths like `...` when possible.
111
+ 3. Keep `.gltf` sidecar files (`.bin`, textures) in expected relative locations.
112
+ 4. Confirm your dev server actually serves the asset directory.
113
+
114
+ ## Reference Examples
115
+
116
+ - [OBJ Loader](/examples/loader/objloader)
117
+ - [glTF Loader](/examples/loader/gltfloader)
118
+ - [glTF Material Example](/examples/loader/gltf_material)
119
+
120
+ After this works, continue with [Scene Graph and Transforms](/guide/scene-graph-and-transforms)
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: "Troubleshooting"
3
+ ---
4
+
5
+ # Troubleshooting
6
+
7
+ ## Blank Canvas
8
+
9
+ - Confirm WebGL2 is available in your browser.
10
+ - Ensure you created `WebGLRenderDevice` with a valid canvas.
11
+ - Ensure `renderer.render([... , camera], device)` includes a camera.
12
+
13
+ ```js
14
+ const device = new WebGLRenderDevice(canvas, { depth: true });
15
+ ```
16
+
17
+ ## Object Is Black or Unlit
18
+
19
+ - Add `LightPlugin` for lit materials.
20
+ - Add at least one light (`AmbientLight`, `DirectionalLight`, etc.).
21
+ - Keep `MeshMaterialPlugin` and `CameraPlugin` enabled.
22
+
23
+ ## Distorted Aspect Ratio
24
+
25
+ Update canvas size and camera projection on resize.
26
+
27
+ ```js
28
+ if (camera.projection instanceof PerspectiveProjection) {
29
+ camera.projection.aspect = innerWidth / innerHeight;
30
+ }
31
+ ```
32
+
33
+ ## Missing Textures or Models
34
+
35
+ - Use correct asset URLs under `...`.
36
+ - Check browser network tab for 404s.
37
+ - For cube maps, provide all six faces in the expected order.
38
+
39
+ ## Shadows Not Visible
40
+
41
+ - Add `ShadowPlugin`.
42
+ - Assign `light.shadow` and tune `bias`/`normalBias`.
43
+ - Verify shadow camera bounds include your objects.
44
+
45
+ Useful full examples:
46
+
47
+ - [Rotating Cube](/examples/other/rotatingCube)
48
+ - [Directional Light](/examples/lights/directional)
49
+ - [Image Target](/examples/rendertarget/image_target)
package/env.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ declare module "*.glsl" {
2
+ const source: string;
3
+
4
+ export default source;
5
+ }
6
+
7
+ // Assisted by ChatGPT 5.3 Codex
8
+ declare module "@examples/rendergraph_gui" {
9
+ export function addRenderGraphGuiAddon(options: {
10
+ gui: import("dat.gui").GUI
11
+ renderer: import("chorama").WebGLRenderer
12
+ title?: string
13
+ position?: { x: number; y: number }
14
+ width?: number
15
+ }): {
16
+ refresh: () => void
17
+ dispose: () => void
18
+ }
19
+ }