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.
- package/.configs/tsconfig.lib.json +43 -0
- package/.configs/tsconfig.website.json +34 -0
- package/.github/workflows/static.yml +88 -0
- package/.vscode/launch.json +29 -0
- package/.vscode/tasks.json +19 -0
- package/README.md +127 -0
- package/assets/images/disappointed.jpg +0 -0
- package/assets/images/skybox/grimmnight_back.png +0 -0
- package/assets/images/skybox/grimmnight_bottom.png +0 -0
- package/assets/images/skybox/grimmnight_front.png +0 -0
- package/assets/images/skybox/grimmnight_left.png +0 -0
- package/assets/images/skybox/grimmnight_right.png +0 -0
- package/assets/images/skybox/grimmnight_top.png +0 -0
- package/assets/images/skybox/miramar_back.png +0 -0
- package/assets/images/skybox/miramar_bottom.png +0 -0
- package/assets/images/skybox/miramar_front.png +0 -0
- package/assets/images/skybox/miramar_left.png +0 -0
- package/assets/images/skybox/miramar_right.png +0 -0
- package/assets/images/skybox/miramar_top.png +0 -0
- package/assets/images/uv.jpg +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_BaseColor.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_Normal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_OcclusionRoughMetal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_BaseColor.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_Normal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_OcclusionRoughMetal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_BaseColor.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_Normal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_OcclusionRoughMetal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_BaseColor.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_Normal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_OcclusionRoughMetal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_BaseColor.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_Normal.png +0 -0
- package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_OcclusionRoughMetal.png +0 -0
- package/assets/models/gltf/flight_helmet/index.bin +0 -0
- package/assets/models/gltf/flight_helmet/index.gltf +705 -0
- package/assets/models/gltf/object.gltf +23 -0
- package/assets/models/gltf/pirate_girl/index.bin +0 -0
- package/assets/models/gltf/pirate_girl/index.gltf +2082 -0
- package/assets/models/obj/pirate_girl/pirate_girl.obj +18459 -0
- package/assets/models/obj/pirate_girl/pirate_girl.png +0 -0
- package/astro.config.mjs +45 -0
- package/content/guide/api-map.md +89 -0
- package/content/guide/camera-and-controls.md +98 -0
- package/content/guide/first-scene.md +176 -0
- package/content/guide/index.md +72 -0
- package/content/guide/installation.md +179 -0
- package/content/guide/materials-and-lighting.md +138 -0
- package/content/guide/plugins-and-render-pipeline.md +124 -0
- package/content/guide/render-targets-and-views.md +147 -0
- package/content/guide/scene-graph-and-transforms.md +113 -0
- package/content/guide/textures-and-assets.md +120 -0
- package/content/guide/troubleshooting.md +49 -0
- package/env.d.ts +19 -0
- package/examples/addons/rendergraph_gui.js +580 -0
- package/examples/camera/orthographic.js +120 -0
- package/examples/camera/perspective.js +138 -0
- package/examples/lights/directional.js +397 -0
- package/examples/lights/multiple_spot_lights.js +304 -0
- package/examples/lights/point.js +337 -0
- package/examples/lights/spot.js +366 -0
- package/examples/loader/gltf_material.js +111 -0
- package/examples/loader/gltfloader.js +78 -0
- package/examples/loader/objloader.js +95 -0
- package/examples/material/cullface.js +111 -0
- package/examples/material/materials.js +126 -0
- package/examples/material/standard/basic.js +164 -0
- package/examples/mesh/circle.js +117 -0
- package/examples/mesh/cuboid.js +151 -0
- package/examples/mesh/cylinder.js +139 -0
- package/examples/mesh/geometries.js +108 -0
- package/examples/mesh/meshTopology.js +103 -0
- package/examples/mesh/plane.js +117 -0
- package/examples/mesh/skinning.js +136 -0
- package/examples/mesh/uvsphere.js +113 -0
- package/examples/other/rotatingCube.js +93 -0
- package/examples/other/rotatingSphere.js +96 -0
- package/examples/rendertarget/basic_canvas.js +130 -0
- package/examples/rendertarget/depth_texture.js +130 -0
- package/examples/rendertarget/image_target.js +140 -0
- package/examples/rendertarget/multiple_views.js +158 -0
- package/examples/rendertarget/render_masks.js +173 -0
- package/examples/rendertarget/split_screen.js +123 -0
- package/examples/rendertarget/split_view.js +137 -0
- package/examples/skybox/skybox.js +111 -0
- package/examples/texture/arrays.js +156 -0
- package/examples/texture/textureWrap.js +118 -0
- package/examples/transform/propagation.js +92 -0
- package/package.json +55 -0
- package/rollup.config.js +66 -0
- package/scripts/stage-chorama.mjs +29 -0
- package/src/caches/cache.js +420 -0
- package/src/caches/index.js +2 -0
- package/src/caches/uniformbuffers.js +104 -0
- package/src/cameracontrols/index.js +258 -0
- package/src/constants/index.js +3 -0
- package/src/constants/mesh.js +197 -0
- package/src/constants/others.js +218 -0
- package/src/constants/texture.js +183 -0
- package/src/core/constants.js +14 -0
- package/src/core/extensions.js +42 -0
- package/src/core/index.js +7 -0
- package/src/core/layouts/index.js +4 -0
- package/src/core/layouts/meshvertex.js +60 -0
- package/src/core/layouts/uniform.js +21 -0
- package/src/core/layouts/uniformbuffer.js +15 -0
- package/src/core/layouts/vertexbuffer.js +43 -0
- package/src/core/limits.js +247 -0
- package/src/core/resources/blendparams.js +89 -0
- package/src/core/resources/framebuffer.js +127 -0
- package/src/core/resources/gpubuffer.js +32 -0
- package/src/core/resources/gpumesh.js +43 -0
- package/src/core/resources/gputexture.js +73 -0
- package/src/core/resources/index.js +5 -0
- package/src/core/shader.js +62 -0
- package/src/core/webgl/bindgroup.js +89 -0
- package/src/core/webgl/descriptors.js +104 -0
- package/src/core/webgl/index.js +5 -0
- package/src/core/webgl/renderpassencoder.js +96 -0
- package/src/core/webgl/renderpipeline.js +54 -0
- package/src/core/webgl/utils.js +371 -0
- package/src/core/webgl/webglrenderdevice.js +235 -0
- package/src/function.js +358 -0
- package/src/index.js +15 -0
- package/src/loader/gltf.js +2172 -0
- package/src/loader/index.js +3 -0
- package/src/loader/loader.js +174 -0
- package/src/loader/obj.js +188 -0
- package/src/loader/texture.js +85 -0
- package/src/loader/utils.js +16 -0
- package/src/material/basic.js +75 -0
- package/src/material/depth.js +73 -0
- package/src/material/index.js +8 -0
- package/src/material/lambert.js +73 -0
- package/src/material/material.js +106 -0
- package/src/material/normal.js +30 -0
- package/src/material/phong.js +86 -0
- package/src/material/raw.js +52 -0
- package/src/material/standard.js +221 -0
- package/src/math/index.js +3 -0
- package/src/math/transform.js +38 -0
- package/src/mesh/attribute/attribute.js +79 -0
- package/src/mesh/attribute/index.js +1 -0
- package/src/mesh/attributedata/index.js +1 -0
- package/src/mesh/attributedata/separate.js +180 -0
- package/src/mesh/builders/base.js +41 -0
- package/src/mesh/builders/circle.js +63 -0
- package/src/mesh/builders/cuboid.js +135 -0
- package/src/mesh/builders/cylinder.js +131 -0
- package/src/mesh/builders/index.js +7 -0
- package/src/mesh/builders/plane.js +73 -0
- package/src/mesh/builders/utils.js +20 -0
- package/src/mesh/builders/uvsphere.js +80 -0
- package/src/mesh/builders/wireframe.js +62 -0
- package/src/mesh/index.js +4 -0
- package/src/mesh/mesh.js +149 -0
- package/src/objects/bone.js +17 -0
- package/src/objects/camera/camera.js +56 -0
- package/src/objects/camera/index.js +2 -0
- package/src/objects/camera/projection.js +203 -0
- package/src/objects/debug/index.js +1 -0
- package/src/objects/debug/skeleton.js +28 -0
- package/src/objects/index.js +7 -0
- package/src/objects/light/ambient.js +20 -0
- package/src/objects/light/directional.js +29 -0
- package/src/objects/light/index.js +5 -0
- package/src/objects/light/point.js +32 -0
- package/src/objects/light/shadow/index.js +1 -0
- package/src/objects/light/shadow/shadow.js +67 -0
- package/src/objects/light/spot.js +56 -0
- package/src/objects/mesh.js +141 -0
- package/src/objects/object3d.js +167 -0
- package/src/objects/skybox.js +38 -0
- package/src/plugins/camera/camera.js +19 -0
- package/src/plugins/camera/index.js +2 -0
- package/src/plugins/camera/nodes/cameraview.js +46 -0
- package/src/plugins/camera/nodes/index.js +2 -0
- package/src/plugins/camera/nodes/opaquepass.js +79 -0
- package/src/plugins/index.js +6 -0
- package/src/plugins/light/index.js +2 -0
- package/src/plugins/light/light.js +23 -0
- package/src/plugins/light/nodes/index.js +1 -0
- package/src/plugins/light/nodes/light.js +127 -0
- package/src/plugins/meshmaterial/index.js +3 -0
- package/src/plugins/meshmaterial/meshmaterial.js +381 -0
- package/src/plugins/meshmaterial/nodes/index.js +1 -0
- package/src/plugins/meshmaterial/nodes/meshmaterial.js +50 -0
- package/src/plugins/meshmaterial/resources/index.js +1 -0
- package/src/plugins/meshmaterial/resources/meshmaterialpipelines.js +50 -0
- package/src/plugins/shadow/index.js +3 -0
- package/src/plugins/shadow/nodes/index.js +3 -0
- package/src/plugins/shadow/nodes/shadow.js +272 -0
- package/src/plugins/shadow/nodes/shadowOccluder.js +112 -0
- package/src/plugins/shadow/nodes/shadowOpaquePass.js +73 -0
- package/src/plugins/shadow/resources/ShadowMap.js +99 -0
- package/src/plugins/shadow/resources/index.js +2 -0
- package/src/plugins/shadow/resources/shadowpipelines.js +25 -0
- package/src/plugins/shadow/shadow.js +31 -0
- package/src/plugins/skeletonhelper/index.js +1 -0
- package/src/plugins/skeletonhelper/skeletonhelper.js +160 -0
- package/src/plugins/skybox/index.js +3 -0
- package/src/plugins/skybox/nodes/index.js +1 -0
- package/src/plugins/skybox/nodes/skybox.js +143 -0
- package/src/plugins/skybox/resources/index.js +2 -0
- package/src/plugins/skybox/resources/skyboxmesh.js +14 -0
- package/src/plugins/skybox/resources/skyboxpipeline.js +6 -0
- package/src/plugins/skybox/skybox.js +137 -0
- package/src/renderer/core/index.js +179 -0
- package/src/renderer/graph/index.js +3 -0
- package/src/renderer/graph/nodes.js +34 -0
- package/src/renderer/graph/rendergraph.js +182 -0
- package/src/renderer/index.js +5 -0
- package/src/renderer/plugin.js +36 -0
- package/src/renderer/renderer.js +179 -0
- package/src/renderer/views.js +28 -0
- package/src/rendertarget/canvastarget.js +30 -0
- package/src/rendertarget/image.js +132 -0
- package/src/rendertarget/index.js +3 -0
- package/src/rendertarget/rendertarget.js +89 -0
- package/src/shader/basicFragment.glsl +30 -0
- package/src/shader/basicVertex.glsl +87 -0
- package/src/shader/common/color.glsl +7 -0
- package/src/shader/common/common.glsl +25 -0
- package/src/shader/common/index.js +4 -0
- package/src/shader/common/light.glsl +437 -0
- package/src/shader/common/math.glsl +12 -0
- package/src/shader/debug/index.js +2 -0
- package/src/shader/debug/skeletonFragment.glsl +8 -0
- package/src/shader/debug/skeletonVertex.glsl +27 -0
- package/src/shader/depthFragment.glsl +37 -0
- package/src/shader/index.js +11 -0
- package/src/shader/lambertFragment.glsl +126 -0
- package/src/shader/normalFragment.glsl +25 -0
- package/src/shader/phongFragment.glsl +140 -0
- package/src/shader/skyboxFragment.glsl +16 -0
- package/src/shader/skyboxVertex.glsl +20 -0
- package/src/shader/standardFragment.glsl +274 -0
- package/src/texture/index.js +2 -0
- package/src/texture/sampler.js +111 -0
- package/src/texture/texture.js +234 -0
- package/src/utils/index.js +115 -0
- package/tsconfig.json +11 -0
- package/website/config/index.ts +1 -0
- package/website/config/navigation.ts +53 -0
- package/website/content.config.ts +92 -0
- package/website/layouts/DocLayout.astro +501 -0
- package/website/layouts/Example.astro +91 -0
- package/website/pages/examples/[...slug].astro +77 -0
- package/website/pages/examples/index.astro +98 -0
- package/website/pages/examples/samples/[...slug].astro +17 -0
- package/website/pages/guide/[slug].astro +30 -0
- package/website/pages/guide/index.astro +21 -0
- package/website/pages/index.astro +9 -0
- package/website/plugins/remark-link-base.js +23 -0
- package/website/utils/url.ts +30 -0
|
Binary file
|
package/astro.config.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineConfig } from "astro/config";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import remarkGfm from "remark-gfm";
|
|
5
|
+
import remarkGithubBlockquoteAlert from "remark-github-blockquote-alert";
|
|
6
|
+
import remarkLinkBase from "./website/plugins/remark-link-base.js";
|
|
7
|
+
|
|
8
|
+
function glsl() {
|
|
9
|
+
return {
|
|
10
|
+
name: "glsl",
|
|
11
|
+
enforce: "pre",
|
|
12
|
+
load(id) {
|
|
13
|
+
if (!id.endsWith(".glsl")) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return `export default ${JSON.stringify(readFileSync(id, "utf8"))}`;
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
output:'static',
|
|
24
|
+
srcDir: "./website",
|
|
25
|
+
publicDir: "./assets",
|
|
26
|
+
outDir: "./dist/website",
|
|
27
|
+
vite: {
|
|
28
|
+
plugins: [glsl()],
|
|
29
|
+
resolve: {
|
|
30
|
+
alias: {
|
|
31
|
+
"chorama": path.resolve("./src/index.js"),
|
|
32
|
+
"@configs": path.resolve("./website/config"),
|
|
33
|
+
"@layouts": path.resolve("./website/layouts"),
|
|
34
|
+
"@components": path.resolve("./website/components"),
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
markdown: {
|
|
39
|
+
remarkPlugins: [
|
|
40
|
+
remarkGfm,
|
|
41
|
+
remarkGithubBlockquoteAlert,
|
|
42
|
+
remarkLinkBase,
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "API Map"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# API Map
|
|
6
|
+
|
|
7
|
+
This is a high-level map of the public surface exported from `src/index.js`.
|
|
8
|
+
|
|
9
|
+
## Quick Import Example
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import {
|
|
13
|
+
WebGLRenderDevice,
|
|
14
|
+
WebGLRenderer,
|
|
15
|
+
Camera,
|
|
16
|
+
MeshMaterial3D,
|
|
17
|
+
MeshMaterialPlugin,
|
|
18
|
+
CameraPlugin
|
|
19
|
+
} from "chorama";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Rendering Core
|
|
23
|
+
|
|
24
|
+
- `WebGLRenderDevice`
|
|
25
|
+
- `WebGLRenderer`
|
|
26
|
+
- Core descriptors/pipeline types from `core`
|
|
27
|
+
|
|
28
|
+
## Scene Objects
|
|
29
|
+
|
|
30
|
+
- `Object3D`
|
|
31
|
+
- `MeshMaterial3D`
|
|
32
|
+
- `Camera`
|
|
33
|
+
- `SkyBox`
|
|
34
|
+
- `Bone3D`
|
|
35
|
+
|
|
36
|
+
## Materials
|
|
37
|
+
|
|
38
|
+
- `BasicMaterial`
|
|
39
|
+
- `LambertMaterial`
|
|
40
|
+
- `PhongMaterial`
|
|
41
|
+
- `StandardMaterial`
|
|
42
|
+
- `RawMaterial`
|
|
43
|
+
- Debug variants (`NormalMaterial`, `DepthMaterial`)
|
|
44
|
+
|
|
45
|
+
## Lighting
|
|
46
|
+
|
|
47
|
+
- `AmbientLight`
|
|
48
|
+
- `DirectionalLight`
|
|
49
|
+
- `PointLight`
|
|
50
|
+
- `SpotLight`
|
|
51
|
+
- Shadow helpers
|
|
52
|
+
|
|
53
|
+
## Geometry and Mesh
|
|
54
|
+
|
|
55
|
+
- `Mesh`
|
|
56
|
+
- Mesh builders: `PlaneMeshBuilder`, `CuboidMeshBuilder`, `UVSphereMeshBuilder`, etc.
|
|
57
|
+
- `Attribute` and attribute-data utilities
|
|
58
|
+
|
|
59
|
+
## Camera and Control
|
|
60
|
+
|
|
61
|
+
- `PerspectiveProjection`
|
|
62
|
+
- `OrthographicProjection`
|
|
63
|
+
- `OrbitCameraControls`
|
|
64
|
+
|
|
65
|
+
## Assets and Textures
|
|
66
|
+
|
|
67
|
+
- `TextureLoader`
|
|
68
|
+
- `OBJLoader`
|
|
69
|
+
- `GLTFLoader`
|
|
70
|
+
- `Texture`, `Sampler`
|
|
71
|
+
|
|
72
|
+
## Render Targets
|
|
73
|
+
|
|
74
|
+
- `CanvasTarget`
|
|
75
|
+
- `ImageTarget`
|
|
76
|
+
- `RenderTarget`
|
|
77
|
+
|
|
78
|
+
## Plugins
|
|
79
|
+
|
|
80
|
+
- `CameraPlugin`
|
|
81
|
+
- `MeshMaterialPlugin`
|
|
82
|
+
- `LightPlugin`
|
|
83
|
+
- `ShadowPlugin`
|
|
84
|
+
- `SkyboxPlugin`
|
|
85
|
+
|
|
86
|
+
For real usage patterns:
|
|
87
|
+
|
|
88
|
+
- [Rotating Cube](/examples/other/rotatingCube)
|
|
89
|
+
- [Examples Overview](/examples)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Camera and Controls"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Camera and Controls
|
|
6
|
+
|
|
7
|
+
This guide assumes you already have a working render loop from [First Scene](/guide/first-scene).
|
|
8
|
+
Here, we only focus on camera setup and controls.
|
|
9
|
+
|
|
10
|
+
## What You Will Add
|
|
11
|
+
|
|
12
|
+
- one camera bound to a render target
|
|
13
|
+
- a perspective projection setup
|
|
14
|
+
- orbit controls for mouse/touch navigation
|
|
15
|
+
|
|
16
|
+
## Step 1: Import Camera APIs
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import {
|
|
20
|
+
Camera,
|
|
21
|
+
PerspectiveProjection,
|
|
22
|
+
OrthographicProjection,
|
|
23
|
+
OrbitCameraControls
|
|
24
|
+
} from "chorama";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
You only need `OrthographicProjection` if you plan to switch projection type.
|
|
28
|
+
|
|
29
|
+
## Step 2: Create a Camera
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const camera = new Camera(target);
|
|
33
|
+
camera.transform.position.z = 3;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`target` should be your existing `CanvasTarget`.
|
|
37
|
+
The `z` offset keeps objects visible in front of the camera.
|
|
38
|
+
|
|
39
|
+
## Step 3: Configure Perspective Projection
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
if (camera.projection instanceof PerspectiveProjection) {
|
|
43
|
+
camera.projection.fov = Math.PI / 3;
|
|
44
|
+
camera.projection.aspect = innerWidth / innerHeight;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use this as the default for most real-time 3D scenes.
|
|
49
|
+
|
|
50
|
+
## Step 4: Add Orbit Controls
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
const controls = new OrbitCameraControls(camera, canvas);
|
|
54
|
+
controls.distance = 4;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`canvas` should be the element receiving pointer input.
|
|
58
|
+
`distance` controls how far the orbit camera stays from its target.
|
|
59
|
+
|
|
60
|
+
## Step 5: Update Controls in the Frame Loop
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
function frame() {
|
|
64
|
+
controls.update();
|
|
65
|
+
renderer.render([object, camera], device);
|
|
66
|
+
requestAnimationFrame(frame);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
requestAnimationFrame(frame);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Call `controls.update()` every frame before rendering.
|
|
73
|
+
If you skip it, input changes will not be applied.
|
|
74
|
+
|
|
75
|
+
## Switch to Orthographic Projection
|
|
76
|
+
|
|
77
|
+
Use orthographic projection when you need no perspective foreshortening.
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
const ortho = new OrthographicProjection();
|
|
81
|
+
ortho.left = -5;
|
|
82
|
+
ortho.right = 5;
|
|
83
|
+
ortho.top = 5;
|
|
84
|
+
ortho.bottom = -5;
|
|
85
|
+
|
|
86
|
+
camera.projection = ortho;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For orthographic cameras, update bounds yourself when viewport shape changes.
|
|
90
|
+
|
|
91
|
+
## Reference Examples
|
|
92
|
+
|
|
93
|
+
If you want to compare against an example, see:
|
|
94
|
+
|
|
95
|
+
- [Perspective Camera](/examples/camera/perspective)
|
|
96
|
+
- [Orthographic Camera](/examples/camera/orthographic)
|
|
97
|
+
|
|
98
|
+
After this works, continue with [Materials and Lighting](/guide/materials-and-lighting).
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "First Scene"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# First Scene
|
|
6
|
+
|
|
7
|
+
This guide helps you render your first object on screen with the smallest useful setup.
|
|
8
|
+
You will build one scene with:
|
|
9
|
+
|
|
10
|
+
- one canvas
|
|
11
|
+
- one render device
|
|
12
|
+
- one renderer
|
|
13
|
+
- one camera
|
|
14
|
+
- one cube mesh
|
|
15
|
+
- one animation loop
|
|
16
|
+
|
|
17
|
+
The goal is to get a stable baseline you can reuse in every new project.
|
|
18
|
+
|
|
19
|
+
## What You Will Build
|
|
20
|
+
|
|
21
|
+
At the end, you will have a rotating cube rendered each frame.
|
|
22
|
+
No lighting setup, model loading, or advanced scene graph features are required here.
|
|
23
|
+
Those topics are covered in other dedicated guides.
|
|
24
|
+
|
|
25
|
+
## Before You Start
|
|
26
|
+
|
|
27
|
+
Make sure you already have a working local install from [Installation](/guide/installation).
|
|
28
|
+
You should be able to import from `chorama` or your local alias path.
|
|
29
|
+
|
|
30
|
+
## Build Your first scene
|
|
31
|
+
|
|
32
|
+
In your source file, do the following:
|
|
33
|
+
|
|
34
|
+
### Step 1: Import what you need
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import {
|
|
38
|
+
WebGLRenderDevice,
|
|
39
|
+
CanvasTarget,
|
|
40
|
+
WebGLRenderer,
|
|
41
|
+
Camera,
|
|
42
|
+
PerspectiveProjection,
|
|
43
|
+
MeshMaterial3D,
|
|
44
|
+
BasicMaterial,
|
|
45
|
+
CuboidMeshBuilder,
|
|
46
|
+
Quaternion,
|
|
47
|
+
MeshMaterialPlugin,
|
|
48
|
+
CameraPlugin
|
|
49
|
+
} from "chorama";
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This imports all the items we require for this setup.
|
|
53
|
+
|
|
54
|
+
### Step 2: Create and mount a canvas
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const canvas = document.createElement("canvas");
|
|
58
|
+
document.body.append(canvas);
|
|
59
|
+
```
|
|
60
|
+
Create the canvas and appends it to the body of the html document
|
|
61
|
+
|
|
62
|
+
### Step 3: Create device and render target
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const device = new WebGLRenderDevice(canvas, { depth: true });
|
|
66
|
+
const target = new CanvasTarget(canvas);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The `device` manages GPU-side rendering operations.
|
|
70
|
+
The `target` is the camera output surface.
|
|
71
|
+
|
|
72
|
+
### Step 4: Create renderer and required plugins
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const renderer = new WebGLRenderer({
|
|
76
|
+
plugins: [new MeshMaterialPlugin(), new CameraPlugin()]
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
These two plugins are required for this scene:
|
|
81
|
+
|
|
82
|
+
- `MeshMaterialPlugin` draws mesh plus material objects.
|
|
83
|
+
- `CameraPlugin` enables camera processing in the render pass.
|
|
84
|
+
|
|
85
|
+
### Step 5: Create and position a camera
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const camera = new Camera(target);
|
|
89
|
+
camera.transform.position.z = 2.5;
|
|
90
|
+
|
|
91
|
+
if (camera.projection instanceof PerspectiveProjection) {
|
|
92
|
+
camera.projection.fov = Math.PI / 3;
|
|
93
|
+
camera.projection.aspect = 1;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Moving camera on `z` ensures the cube is in front of the view.
|
|
98
|
+
The initial `aspect` is a temporary placeholder; resize will set the real value.
|
|
99
|
+
|
|
100
|
+
### Step 6: Create a cube object
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
const cubeMesh = new CuboidMeshBuilder().build();
|
|
104
|
+
const cubeMaterial = new BasicMaterial();
|
|
105
|
+
const cube = new MeshMaterial3D(cubeMesh, cubeMaterial);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This creates one drawable object with default shading.
|
|
109
|
+
Using `BasicMaterial` for an object that has no lighting applied to it.
|
|
110
|
+
|
|
111
|
+
### Step 7: Define per-frame rotation
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const stepRotation = Quaternion.fromEuler(0.01, 0.01, 0.0);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This rotation is multiplied into cube orientation each frame to animate motion.
|
|
118
|
+
|
|
119
|
+
### Step 8: Add resize handling
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
function resize() {
|
|
123
|
+
const cssWidth = window.innerWidth;
|
|
124
|
+
const cssHeight = window.innerHeight;
|
|
125
|
+
const dpr = window.devicePixelRatio || 1;
|
|
126
|
+
|
|
127
|
+
canvas.style.width = cssWidth + "px";
|
|
128
|
+
canvas.style.height = cssHeight + "px";
|
|
129
|
+
canvas.width = Math.floor(cssWidth * dpr);
|
|
130
|
+
canvas.height = Math.floor(cssHeight * dpr);
|
|
131
|
+
|
|
132
|
+
if (camera.projection instanceof PerspectiveProjection) {
|
|
133
|
+
camera.projection.aspect = cssWidth / cssHeight;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
window.addEventListener("resize", resize);
|
|
138
|
+
resize();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
This keeps render resolution sharp and camera projection correct.
|
|
142
|
+
If you skip this, stretching and blur are likely on resize or high-DPI screens.
|
|
143
|
+
|
|
144
|
+
### Step 9: Start the render loop
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
function frame() {
|
|
148
|
+
cube.transform.orientation.multiply(stepRotation);
|
|
149
|
+
renderer.render([cube, camera], device);
|
|
150
|
+
requestAnimationFrame(frame);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
requestAnimationFrame(frame);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Each frame does three things: update state, render, schedule next frame.
|
|
157
|
+
|
|
158
|
+
## What You Can Try Next
|
|
159
|
+
|
|
160
|
+
Change only one variable at a time:
|
|
161
|
+
|
|
162
|
+
- move camera: `camera.transform.position.z = 4`
|
|
163
|
+
- stop rotation: remove `cube.transform.orientation.multiply(stepRotation)`
|
|
164
|
+
- rotate one axis only: `Quaternion.fromEuler(0.0, 0.01, 0.0)`
|
|
165
|
+
- change shape: replace `CuboidMeshBuilder` with another mesh builder
|
|
166
|
+
|
|
167
|
+
These changes help verify your scene wiring before adding complexity.
|
|
168
|
+
|
|
169
|
+
## Reference Example
|
|
170
|
+
|
|
171
|
+
If you want to compare against an example, see:
|
|
172
|
+
|
|
173
|
+
- [Rotating Cube](/examples/other/rotatingCube)
|
|
174
|
+
|
|
175
|
+
After this works, continue with [Camera and Controls](/guide/camera-and-controls).
|
|
176
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Guide"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Guide
|
|
6
|
+
|
|
7
|
+
This guide helps you build scenes with Chorama using practical, task-first steps.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Chorama is a modular WebGL2 rendering library focused on explicit control: you compose render behavior with plugins, build scenes from reusable object/material/light primitives, and keep direct visibility into the render flow.
|
|
12
|
+
|
|
13
|
+
> [!WARNING]
|
|
14
|
+
> Chorama is currently experimental and is not recommended for production use.
|
|
15
|
+
> Expect API changes, behavior changes and breaking changes as the library evolves.
|
|
16
|
+
|
|
17
|
+
This guide is structured to take you from first render to production-style scene setup. Instead of covering every class in isolation first, each chapter is anchored to a concrete task and points you to full runnable examples.
|
|
18
|
+
|
|
19
|
+
By the end of this guide, you should be able to:
|
|
20
|
+
|
|
21
|
+
- Set up a render loop with `WebGLRenderDevice`, `CanvasTarget`, and `WebGLRenderer`
|
|
22
|
+
- Build and animate scene objects with camera, materials, and lights
|
|
23
|
+
- Load texture/model assets and handle async content safely
|
|
24
|
+
- Use render targets and view configuration for offscreen and multi-view scenarios
|
|
25
|
+
- Understand the plugin-driven pipeline enough to debug and extend behavior
|
|
26
|
+
|
|
27
|
+
## Who This Guide Is For
|
|
28
|
+
|
|
29
|
+
Use this if you want direct WebGL2 control but still want reusable building blocks.
|
|
30
|
+
|
|
31
|
+
## How To Use This Guide
|
|
32
|
+
|
|
33
|
+
- New to Chorama: follow the reading order from top to bottom.
|
|
34
|
+
- Migrating from another renderer: start at [First Scene](/guide/first-scene), then jump to [Plugins and Render Pipeline](/guide/plugins-and-render-pipeline).
|
|
35
|
+
- Looking for a specific API: use [API Map](/guide/api-map) as an index, then return to task pages for applied usage.
|
|
36
|
+
- Blocked on behavior: check [Troubleshooting](/guide/troubleshooting), then compare your setup against a matching example route.
|
|
37
|
+
|
|
38
|
+
## Reading Order
|
|
39
|
+
|
|
40
|
+
1. [Installation](/guide/installation)
|
|
41
|
+
2. [First Scene](/guide/first-scene)
|
|
42
|
+
3. [Camera and Controls](/guide/camera-and-controls)
|
|
43
|
+
4. [Materials and Lighting](/guide/materials-and-lighting)
|
|
44
|
+
5. [Textures and Assets](/guide/textures-and-assets)
|
|
45
|
+
6. [Render Targets and Views](/guide/render-targets-and-views)
|
|
46
|
+
7. [Scene Graph and Transforms](/guide/scene-graph-and-transforms)
|
|
47
|
+
8. [Plugins and Render Pipeline](/guide/plugins-and-render-pipeline)
|
|
48
|
+
9. [API Map](/guide/api-map)
|
|
49
|
+
10. [Troubleshooting](/guide/troubleshooting)
|
|
50
|
+
|
|
51
|
+
## Core Flow
|
|
52
|
+
|
|
53
|
+
The snippet below creates the minimum pieces needed to render a scene:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import { WebGLRenderDevice, CanvasTarget, WebGLRenderer, Camera } from "chorama";
|
|
57
|
+
|
|
58
|
+
const canvas = document.createElement("canvas");
|
|
59
|
+
const device = new WebGLRenderDevice(canvas, { depth: true });
|
|
60
|
+
const target = new CanvasTarget(canvas);
|
|
61
|
+
const renderer = new WebGLRenderer();
|
|
62
|
+
const camera = new Camera(target);
|
|
63
|
+
```
|
|
64
|
+
The `canvas` is the HTML surface where we draw on (or in a more technical terms, render to).
|
|
65
|
+
The `WebGLRenderDevice` executes our draw commands.
|
|
66
|
+
The `CanvasTarget` tells the camera where to render to. There is another type of target but thats for later.
|
|
67
|
+
The `WebGLRenderer` runs the render pipeline each frame.
|
|
68
|
+
The `Camera` provides view/projection data the renderer needs.
|
|
69
|
+
|
|
70
|
+
This snippet exists to show the baseline setup used in almost every example, so later chapters can add one concept at a time without repeating setup details.
|
|
71
|
+
|
|
72
|
+
For a complete runnable example, start with [Rotating Cube](/examples/other/rotatingCube).
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Installation"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Installation
|
|
6
|
+
|
|
7
|
+
Choose how you want to use the library:
|
|
8
|
+
|
|
9
|
+
- If you want to use it now: use **Manual Installation**.
|
|
10
|
+
- If you are waiting for package distribution: see **NPM** or **CDN**.
|
|
11
|
+
|
|
12
|
+
## NPM
|
|
13
|
+
|
|
14
|
+
> [!Note]
|
|
15
|
+
> This method is not yet available.
|
|
16
|
+
|
|
17
|
+
## CDN
|
|
18
|
+
|
|
19
|
+
> [!Note]
|
|
20
|
+
> This method is not yet available.
|
|
21
|
+
|
|
22
|
+
## Manual Installation
|
|
23
|
+
|
|
24
|
+
### 1) Requirements
|
|
25
|
+
|
|
26
|
+
Install these first:
|
|
27
|
+
|
|
28
|
+
- [Git](https://git-scm.com/downloads) to clone the source code
|
|
29
|
+
- [Node.js 18+](https://nodejs.org/) (includes npm) to install dependencies and build
|
|
30
|
+
- A browser with WebGL2 support to run your app/examples
|
|
31
|
+
|
|
32
|
+
### 2) Clone the repository and install dependencies
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/waynemwashuma/chorama.git
|
|
36
|
+
cd chorama
|
|
37
|
+
npm install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3) Build the library files
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm run build-src
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This creates build output in `dist/`, including:
|
|
47
|
+
|
|
48
|
+
- `dist/index.umd.js`
|
|
49
|
+
- `dist/index.module.js`
|
|
50
|
+
|
|
51
|
+
Optional: if you also want local docs/examples output, run:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm run build
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 4) Copy files to your project
|
|
58
|
+
|
|
59
|
+
Copy one or both build files into your own project.
|
|
60
|
+
|
|
61
|
+
- Use `dist/index.module.js` for ESM usage (recommended).
|
|
62
|
+
- Use `dist/index.umd.js` for plain script-tag usage.
|
|
63
|
+
|
|
64
|
+
Example layout used below:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
your-project/
|
|
68
|
+
libs/
|
|
69
|
+
chorama/
|
|
70
|
+
index.module.js
|
|
71
|
+
index.umd.js
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 5) Use in your project
|
|
75
|
+
|
|
76
|
+
#### ESM (recommended)
|
|
77
|
+
|
|
78
|
+
If you use a bundler, set an alias so your app can import from `"chorama"` directly.
|
|
79
|
+
|
|
80
|
+
##### Vite (`vite.config.js`)
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
import { defineConfig } from "vite";
|
|
84
|
+
import path from "node:path";
|
|
85
|
+
import { fileURLToPath } from "node:url";
|
|
86
|
+
|
|
87
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
88
|
+
const __dirname = path.dirname(__filename);
|
|
89
|
+
|
|
90
|
+
export default defineConfig({
|
|
91
|
+
resolve: {
|
|
92
|
+
alias: {
|
|
93
|
+
chorama: path.resolve(__dirname, "libs/chorama/index.module.js")
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
##### Webpack (`webpack.config.js`)
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
const path = require("node:path");
|
|
103
|
+
|
|
104
|
+
module.exports = {
|
|
105
|
+
resolve: {
|
|
106
|
+
alias: {
|
|
107
|
+
chorama: path.resolve(__dirname, "libs/chorama/index.module.js")
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Then import in app code:
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
import { WebGLRenderer, MeshMaterialPlugin, CameraPlugin } from "chorama";
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Plain HTML with browser import maps (no bundler)
|
|
120
|
+
|
|
121
|
+
Use the ESM file with an import map:
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!doctype html>
|
|
125
|
+
<html>
|
|
126
|
+
<head>
|
|
127
|
+
<meta charset="utf-8" />
|
|
128
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
129
|
+
<title>Chorama - Import Map</title>
|
|
130
|
+
<script type="importmap">
|
|
131
|
+
{
|
|
132
|
+
"imports": {
|
|
133
|
+
"chorama": "./libs/chorama/index.module.js"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
</script>
|
|
137
|
+
</head>
|
|
138
|
+
<body>
|
|
139
|
+
<canvas id="app"></canvas>
|
|
140
|
+
<script type="module">
|
|
141
|
+
import { WebGLRenderer, MeshMaterialPlugin, CameraPlugin } from "chorama";
|
|
142
|
+
|
|
143
|
+
const canvas = document.getElementById("app");
|
|
144
|
+
const renderer = new WebGLRenderer({
|
|
145
|
+
canvas,
|
|
146
|
+
plugins: [new MeshMaterialPlugin(), new CameraPlugin()]
|
|
147
|
+
});
|
|
148
|
+
</script>
|
|
149
|
+
</body>
|
|
150
|
+
</html>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### Plain HTML with script tag (UMD)
|
|
154
|
+
|
|
155
|
+
Use the UMD build if you do not want modules:
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<!doctype html>
|
|
159
|
+
<html>
|
|
160
|
+
<head>
|
|
161
|
+
<meta charset="utf-8" />
|
|
162
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
163
|
+
<title>Chorama - Plain HTML</title>
|
|
164
|
+
<script src="./libs/chorama/index.umd.js"></script>
|
|
165
|
+
</head>
|
|
166
|
+
<body>
|
|
167
|
+
<canvas id="app"></canvas>
|
|
168
|
+
<script>
|
|
169
|
+
const { WebGLRenderer, MeshMaterialPlugin, CameraPlugin } = window.CHORAMA;
|
|
170
|
+
const canvas = document.getElementById("app");
|
|
171
|
+
|
|
172
|
+
const renderer = new WebGLRenderer({
|
|
173
|
+
canvas,
|
|
174
|
+
plugins: [new MeshMaterialPlugin(), new CameraPlugin()]
|
|
175
|
+
});
|
|
176
|
+
</script>
|
|
177
|
+
</body>
|
|
178
|
+
</html>
|
|
179
|
+
```
|