retiam 1.0.1 → 1.0.2
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/bin/render-config.js +0 -1
- package/dist/{UTIF-CuM_xgsi.js → UTIF-X7q9996p.js} +1 -1
- package/dist/{index-C7UzgTiw.js → index-Be4c9A99.js} +5727 -5680
- package/dist/{main-CCBHkqdA.js → main-IC5HXR90.js} +1 -1
- package/dist/retiam.es.js +739 -734
- package/dist/src/engine/_core/Material.d.ts +13 -18
- package/dist/src/engine/_core/Scene.d.ts +3 -0
- package/dist/src/engine/_core/SnapshotManager.d.ts +3 -0
- package/dist/src/engine/components/fragment/ModelFragment.d.ts +1 -6
- package/dist/src/engine/material/shading/CelShading.d.ts +16 -0
- package/dist/src/engine/material/shading/ClayShading.d.ts +6 -0
- package/dist/src/engine/material/shading/GoochShading.d.ts +14 -0
- package/dist/src/engine/material/shading/PBRShading.d.ts +6 -0
- package/dist/src/engine/material/shading/Shading.d.ts +17 -0
- package/dist/src/engine/material/shading/index.d.ts +5 -0
- package/dist/src/engine/render/RenderConfig.d.ts +1 -23
- package/dist/src/index.d.ts +1 -0
- package/package.json +3 -2
- package/readme.md +298 -16
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Color } from '../math/Color';
|
|
2
2
|
import { SubTexture } from '../loader/SubTexture';
|
|
3
|
-
import { ShadingStyle } from '../
|
|
3
|
+
import { Shading, ShadingStyle } from '../material/shading';
|
|
4
4
|
export type TextureSource = string | ImageBitmap | HTMLCanvasElement | OffscreenCanvas | HTMLImageElement | HTMLVideoElement | HTMLElement | SubTexture;
|
|
5
5
|
/**
|
|
6
6
|
* Bitmask flags to track which material properties were explicitly set by the user.
|
|
@@ -21,8 +21,7 @@ export declare enum MaterialFlags {
|
|
|
21
21
|
ALBEDO_IDX = 2048,
|
|
22
22
|
NORMAL_IDX = 4096,
|
|
23
23
|
NORMAL_SCALE = 8192,
|
|
24
|
-
SHADING_STYLE = 16384
|
|
25
|
-
STYLE_PARAMS = 32768
|
|
24
|
+
SHADING_STYLE = 16384
|
|
26
25
|
}
|
|
27
26
|
/**
|
|
28
27
|
* Manages rendering material parameters (reflectance, roughness, metallic, normal scaling) for an [[Entity]],
|
|
@@ -52,6 +51,7 @@ export declare class Material {
|
|
|
52
51
|
readonly _emColor: Float32Array;
|
|
53
52
|
private _albedoMap?;
|
|
54
53
|
private _normalMap?;
|
|
54
|
+
private _shading;
|
|
55
55
|
/**
|
|
56
56
|
* Creates a new Material instance.
|
|
57
57
|
*
|
|
@@ -151,22 +151,17 @@ export declare class Material {
|
|
|
151
151
|
setSpecular(v: number): Material;
|
|
152
152
|
/** Sets the normal map scale strength. */
|
|
153
153
|
setNormalScale(v: number): Material;
|
|
154
|
-
/**
|
|
154
|
+
/** Surface lighting override. Null inherits the parent material or scene default. */
|
|
155
|
+
get shading(): Shading | null;
|
|
156
|
+
set shading(value: Shading | null);
|
|
157
|
+
/** Selects a shading model using its name, or -1 to inherit. */
|
|
155
158
|
get shadingStyle(): ShadingStyle | number;
|
|
156
|
-
set shadingStyle(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
set celBands(v: number);
|
|
163
|
-
get rimStrength(): number;
|
|
164
|
-
set rimStrength(v: number);
|
|
165
|
-
get rimPower(): number;
|
|
166
|
-
set rimPower(v: number);
|
|
167
|
-
setShadingStyle(v: ShadingStyle | number): Material;
|
|
168
|
-
setGooch(warm?: number, cool?: number): Material;
|
|
169
|
-
setCel(bands?: number, rimStrength?: number): Material;
|
|
159
|
+
set shadingStyle(value: ShadingStyle | number);
|
|
160
|
+
setShadingStyle(value: ShadingStyle | number): this;
|
|
161
|
+
setGooch(warm?: number, cool?: number): this;
|
|
162
|
+
setCel(bands?: number, rimStrength?: number, rimPower?: number): this;
|
|
163
|
+
/** Numeric settings interpolate within a model; model changes happen at the endpoint. */
|
|
164
|
+
interpolateShading(start: Material, target: Material, t: number): void;
|
|
170
165
|
/** Clones this material instance. */
|
|
171
166
|
copy(): Material;
|
|
172
167
|
clone(): Material;
|
|
@@ -11,6 +11,7 @@ import { Entity } from './Entity';
|
|
|
11
11
|
import { Compute, ComputeCommand } from '../compute/Compute';
|
|
12
12
|
import { RenderCommand } from './SceneInterface';
|
|
13
13
|
import { RenderConfig } from '../render/RenderConfig';
|
|
14
|
+
import { Shading } from '../material/shading';
|
|
14
15
|
import { Pass } from '../render/frame_graph/Pass';
|
|
15
16
|
import { GroupAnimator } from '../animation/GroupAnimator';
|
|
16
17
|
import { SnapshotManager } from './SnapshotManager';
|
|
@@ -386,6 +387,8 @@ export declare class Scene {
|
|
|
386
387
|
*/
|
|
387
388
|
onAfterReset(): void;
|
|
388
389
|
enableFrameFeedback(): FrameFeedbackFeature;
|
|
390
|
+
/** Default surface lighting for this scene; individual materials can override it. */
|
|
391
|
+
shading: Shading;
|
|
389
392
|
_renderConfig: RenderConfig;
|
|
390
393
|
get renderConfig(): RenderConfig;
|
|
391
394
|
addCompute(...compute_commands: ComputeCommand[]): void;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Scene } from './Scene';
|
|
2
|
+
import { Shading } from '../material/shading';
|
|
2
3
|
export interface EntitySnapshot {
|
|
3
4
|
id: number;
|
|
4
5
|
visibility: boolean;
|
|
5
6
|
stateData: Float32Array;
|
|
7
|
+
shading?: Shading | null;
|
|
6
8
|
}
|
|
7
9
|
export interface AnimationSnapshot {
|
|
8
10
|
type: string;
|
|
@@ -30,6 +32,7 @@ export interface SceneSnapshot {
|
|
|
30
32
|
entities: EntitySnapshot[];
|
|
31
33
|
animations: AnimationSnapshot[];
|
|
32
34
|
isPaused: boolean;
|
|
35
|
+
shading?: Shading;
|
|
33
36
|
}
|
|
34
37
|
/**
|
|
35
38
|
* Manages deterministic scene state checkpoints and snapshots.
|
|
@@ -6,13 +6,8 @@ export declare class ModelFragment extends FragmentComponent {
|
|
|
6
6
|
private _lastShadowState;
|
|
7
7
|
private _lastShadowMethod;
|
|
8
8
|
private _lastLightSize;
|
|
9
|
-
private
|
|
9
|
+
private _shading;
|
|
10
10
|
private _lastIsTransparent;
|
|
11
|
-
private _lastGoochWarm;
|
|
12
|
-
private _lastGoochCool;
|
|
13
|
-
private _lastCelBands;
|
|
14
|
-
private _lastCelRimStrength;
|
|
15
|
-
private _lastCelRimPower;
|
|
16
11
|
prepare(scene: Scene, state?: State): void;
|
|
17
12
|
setup(builder: ShaderBuilder, passName: string): void;
|
|
18
13
|
isPassActive(passName: string, state: State): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Shading } from './Shading';
|
|
2
|
+
export interface CelShadingOptions {
|
|
3
|
+
bands?: number;
|
|
4
|
+
rimStrength?: number;
|
|
5
|
+
rimPower?: number;
|
|
6
|
+
}
|
|
7
|
+
/** Cartoon lighting bands with an optional silhouette highlight. */
|
|
8
|
+
export declare class CelShading extends Shading {
|
|
9
|
+
bands: number;
|
|
10
|
+
rimStrength: number;
|
|
11
|
+
rimPower: number;
|
|
12
|
+
constructor({ bands, rimStrength, rimPower }?: CelShadingOptions);
|
|
13
|
+
writeParameters(target: Float32Array, offset: number): void;
|
|
14
|
+
interpolate(start: CelShading, target: CelShading, t: number): void;
|
|
15
|
+
clone(): CelShading;
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Shading } from './Shading';
|
|
2
|
+
export interface GoochShadingOptions {
|
|
3
|
+
warm?: number;
|
|
4
|
+
cool?: number;
|
|
5
|
+
}
|
|
6
|
+
/** Warm/cool lighting for technical illustrations. */
|
|
7
|
+
export declare class GoochShading extends Shading {
|
|
8
|
+
warm: number;
|
|
9
|
+
cool: number;
|
|
10
|
+
constructor({ warm, cool }?: GoochShadingOptions);
|
|
11
|
+
writeParameters(target: Float32Array, offset: number): void;
|
|
12
|
+
interpolate(start: GoochShading, target: GoochShading, t: number): void;
|
|
13
|
+
clone(): GoochShading;
|
|
14
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare enum ShadingStyle {
|
|
2
|
+
PBR = "pbr",
|
|
3
|
+
GOOCH = "gooch",
|
|
4
|
+
CEL = "cel",
|
|
5
|
+
CLAY = "clay"
|
|
6
|
+
}
|
|
7
|
+
/** A surface lighting model. Numeric parameters are written to the material GPU buffer. */
|
|
8
|
+
export declare abstract class Shading {
|
|
9
|
+
readonly style: ShadingStyle;
|
|
10
|
+
readonly chunk: string;
|
|
11
|
+
readonly fragment: string;
|
|
12
|
+
protected constructor(style: ShadingStyle, chunk: string, fragment: string);
|
|
13
|
+
writeParameters(target: Float32Array, offset: number): void;
|
|
14
|
+
/** Interpolate numeric settings between two instances of this lighting model. */
|
|
15
|
+
interpolate(start: Shading, target: Shading, t: number): void;
|
|
16
|
+
abstract clone(): Shading;
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Shading, ShadingStyle } from './Shading';
|
|
2
|
+
export { PBRShading } from './PBRShading';
|
|
3
|
+
export { CelShading, type CelShadingOptions } from './CelShading';
|
|
4
|
+
export { GoochShading, type GoochShadingOptions } from './GoochShading';
|
|
5
|
+
export { ClayShading } from './ClayShading';
|
|
@@ -17,12 +17,7 @@ export declare enum DenoiserType {
|
|
|
17
17
|
OIDN = "oidn",
|
|
18
18
|
NATIVE = "native"
|
|
19
19
|
}
|
|
20
|
-
export
|
|
21
|
-
PBR = "pbr",
|
|
22
|
-
GOOCH = "gooch",
|
|
23
|
-
CEL = "cel",
|
|
24
|
-
CLAY = "clay"
|
|
25
|
-
}
|
|
20
|
+
export { ShadingStyle } from '../material/shading/Shading';
|
|
26
21
|
export declare enum ShadowMethod {
|
|
27
22
|
PCF = "pcf",
|
|
28
23
|
PCSS = "pcss"
|
|
@@ -37,12 +32,6 @@ export declare class RenderConfig {
|
|
|
37
32
|
shadowMethod: ShadowMethod;
|
|
38
33
|
lightSize: number;
|
|
39
34
|
frustumCulling: boolean;
|
|
40
|
-
shadingStyle: ShadingStyle;
|
|
41
|
-
celBands: number;
|
|
42
|
-
celRimStrength: number;
|
|
43
|
-
celRimPower: number;
|
|
44
|
-
goochWarm: number;
|
|
45
|
-
goochCool: number;
|
|
46
35
|
raytraceEnabled: boolean;
|
|
47
36
|
rtSamples: number;
|
|
48
37
|
rtMaxAccumulation: number;
|
|
@@ -51,15 +40,4 @@ export declare class RenderConfig {
|
|
|
51
40
|
bounce_count: number;
|
|
52
41
|
denoiser: DenoiserType;
|
|
53
42
|
oidnModel: string;
|
|
54
|
-
/** Apply Cel/Toon shading with optional parameters. Chainable. */
|
|
55
|
-
setCel(options?: {
|
|
56
|
-
bands?: number;
|
|
57
|
-
rimStrength?: number;
|
|
58
|
-
rimPower?: number;
|
|
59
|
-
}): this;
|
|
60
|
-
/** Apply Gooch technical illustration shading. Chainable. */
|
|
61
|
-
setGooch(options?: {
|
|
62
|
-
warm?: number;
|
|
63
|
-
cool?: number;
|
|
64
|
-
}): this;
|
|
65
43
|
}
|
package/dist/src/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "retiam",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "WebGPU powered animation engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/retiam.es.js",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
46
46
|
"test:distribution": "node --import tsx --test test/library_portability_test.ts test/package_contents_test.mjs test/render_config_test.mjs",
|
|
47
47
|
"test:create": "node --test test/create_retiam_test.mjs",
|
|
48
|
+
"test:shading": "npm run build && node --test test/shading_test.mjs test/shading_browser.test.mjs",
|
|
48
49
|
"test:studio-layout": "node --test test/studio_layout.test.mjs",
|
|
49
50
|
"unit-test": "ts-node-esm test/test.ts",
|
|
50
51
|
"gen-context": "ts-node tools/context_gen/context_generator.ts ./src",
|
|
@@ -104,4 +105,4 @@
|
|
|
104
105
|
"woff2-encoder": "^2.0.0",
|
|
105
106
|
"ws": "^8.16.0"
|
|
106
107
|
}
|
|
107
|
-
}
|
|
108
|
+
}
|
package/readme.md
CHANGED
|
@@ -12,20 +12,60 @@ Retiam is a TypeScript animation engine built on WebGPU. Write scenes for mathem
|
|
|
12
12
|
- **Rendering:** combine 2D paths, 3D meshes, lighting, shadows, compute effects, and post-processing.
|
|
13
13
|
- **Specialized libraries:** add charts, graphs, physics, procedural shapes, sketch styling, and emphasis animations through separate imports.
|
|
14
14
|
- **Audio and output:** work with audio, narration, and subtitles; inspect snapshots, render video, or share scenes as web components.
|
|
15
|
+
- **Retiam Studio:** edit scenes alongside a live preview, tune supported values with inspectors, and control playback from your generated project.
|
|
15
16
|
|
|
16
17
|
## Getting started
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
| Method | Use it for | Result |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| [npm project and Studio](#create-a-project-with-studio) | Author and preview TypeScript scenes, then render video | Source project, MP4 and snapshots |
|
|
22
|
+
| [CDN modules](#use-retiam-from-a-cdn) | Add a live scene directly to a browser page | Interactive WebGPU canvas |
|
|
23
|
+
| [Embedded export](#export-an-independent-web-embed) | Share a finished animation on another website | Hosted web component and bundled assets |
|
|
24
|
+
|
|
25
|
+
### Create a project with Studio
|
|
26
|
+
|
|
27
|
+
Use Node.js 20.19 or newer and a WebGPU-capable browser. The project generator
|
|
28
|
+
creates a TypeScript application, installs its dependencies, and opens Retiam
|
|
29
|
+
Studio with a **Write** animation of “Retiam”:
|
|
20
30
|
|
|
21
31
|
```bash
|
|
22
|
-
npx create-retiam my-animation
|
|
32
|
+
npx create-retiam@latest my-animation
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The generated project declares
|
|
36
|
+
`"retiam": "latest"`. Its initial install uses npm's `latest` engine release;
|
|
37
|
+
the package manager's lockfile records the resolved version for later installs.
|
|
38
|
+
|
|
39
|
+
The editor opens below the preview. Drag the divider to resize it, or use the
|
|
40
|
+
layout control to dock it on the left or right. Studio remembers your choice.
|
|
41
|
+
Single-scene projects show the preview and editor; scene navigation and search
|
|
42
|
+
appear when more scenes are added and the page reloads.
|
|
43
|
+
|
|
44
|
+
Press Ctrl+C to stop the server. To reopen Studio:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cd my-animation
|
|
48
|
+
npm run dev
|
|
23
49
|
```
|
|
24
50
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
51
|
+
Edit `src/scenes/Retiam.ts` in your editor or Studio. The generated project also
|
|
52
|
+
includes `config.js` for CLI rendering, `studio/` for the local editor, and the
|
|
53
|
+
Vite and TypeScript configuration. In Studio, **Run** or **Ctrl/Command+Enter**
|
|
54
|
+
applies and saves edits. Add default-exported Scene classes under `src/scenes/`
|
|
55
|
+
to make them available in the scene browser after reloading.
|
|
56
|
+
|
|
57
|
+
| Generator option | Behavior |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `--no-start` | Install dependencies without starting Studio |
|
|
60
|
+
| `--no-install` | Generate files without installing or starting |
|
|
61
|
+
| `--no-open` | Start the server without opening a browser |
|
|
62
|
+
| `--title "Hello"` | Change the starter animation text |
|
|
63
|
+
| `--pm npm\|pnpm\|yarn\|bun` | Choose the package manager |
|
|
64
|
+
|
|
65
|
+
The [`create-retiam` package](packages/create-retiam/README.md)
|
|
66
|
+
is released separately from the engine. Publish the engine version required by
|
|
67
|
+
its starter before publishing the generator. Generator updates apply to new
|
|
68
|
+
projects; existing projects keep their own Studio and configuration files.
|
|
29
69
|
|
|
30
70
|
### Manual setup
|
|
31
71
|
|
|
@@ -33,7 +73,7 @@ Install Retiam in your own TypeScript application:
|
|
|
33
73
|
|
|
34
74
|
```bash
|
|
35
75
|
npm install retiam
|
|
36
|
-
npm install --save-dev typescript vite @webgpu/types
|
|
76
|
+
npm install --save-dev typescript "vite@^6.1.1" @webgpu/types
|
|
37
77
|
```
|
|
38
78
|
|
|
39
79
|
Follow the [installation guide](https://abhilasbiswas.github.io/retiam-docs/installation/) for the complete project structure, TypeScript configuration, and browser entry point. To use an unpublished checkout, run `npm pack` in this repository and install the generated `.tgz` file in your application.
|
|
@@ -93,21 +133,259 @@ window.addEventListener("pagehide", () => scene.destroy(), { once: true });
|
|
|
93
133
|
|
|
94
134
|
The host page needs a `<canvas id="canvas"></canvas>` with an explicit CSS display size. Continue with [your first scene](https://abhilasbiswas.github.io/retiam-docs/first-scene/) for animation, camera, and lifecycle guidance.
|
|
95
135
|
|
|
136
|
+
## Use Retiam from a CDN
|
|
137
|
+
|
|
138
|
+
Import Retiam directly in a browser page. The published module is available at
|
|
139
|
+
**[jsDelivr](https://cdn.jsdelivr.net/npm/retiam@latest/dist/retiam.es.min.js)**.
|
|
140
|
+
This example loads the core and charts entries through the latest release tag:
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<!doctype html>
|
|
144
|
+
<html lang="en">
|
|
145
|
+
<head>
|
|
146
|
+
<meta charset="utf-8" />
|
|
147
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
148
|
+
<title>Retiam CDN animation</title>
|
|
149
|
+
<style>
|
|
150
|
+
html, body { margin: 0; width: 100%; height: 100%; }
|
|
151
|
+
canvas { display: block; width: 100%; height: 100%; }
|
|
152
|
+
</style>
|
|
153
|
+
<script type="importmap">
|
|
154
|
+
{
|
|
155
|
+
"imports": {
|
|
156
|
+
"retiam": "https://cdn.jsdelivr.net/npm/retiam@latest/dist/retiam.es.min.js",
|
|
157
|
+
"retiam/charts": "https://cdn.jsdelivr.net/npm/retiam@latest/dist/libs/charts/index.js"
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
</script>
|
|
161
|
+
</head>
|
|
162
|
+
<body>
|
|
163
|
+
<canvas id="canvas"></canvas>
|
|
164
|
+
<script type="module">
|
|
165
|
+
import { Scene, Circle, Create, CameraModel, hex } from 'retiam';
|
|
166
|
+
|
|
167
|
+
class BrowserScene extends Scene {
|
|
168
|
+
async run() {
|
|
169
|
+
this.clearColor(hex('#080C14'));
|
|
170
|
+
this.camera.model = CameraModel.ORTHOGRAPHIC;
|
|
171
|
+
this.camera.orthoScale = 12;
|
|
172
|
+
this.camera.position.set([0, 0, 20]);
|
|
173
|
+
this.camera.lookAt([0, 0, 0]);
|
|
174
|
+
const circle = new Circle(1, { fill: hex('#38BDF8') });
|
|
175
|
+
this.add(circle);
|
|
176
|
+
await this.play(new Create(circle, { duration: 1200 }));
|
|
177
|
+
await this.wait(1000);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const scene = new BrowserScene();
|
|
182
|
+
scene.start(document.querySelector('#canvas')).catch(console.error);
|
|
183
|
+
window.addEventListener('pagehide', () => scene.destroy(), { once: true });
|
|
184
|
+
</script>
|
|
185
|
+
</body>
|
|
186
|
+
</html>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Serve the page over HTTPS or localhost, with a WebGPU-capable browser. No Retiam
|
|
190
|
+
npm installation is needed for this page. Add import-map entries for any other
|
|
191
|
+
sublibraries you use, such as `retiam/shapes`, with the same release tag. jsDelivr
|
|
192
|
+
serves the module's related chunks, fonts, workers and WASM assets. A CDN page
|
|
193
|
+
runs the animation live; the [npm CLI workflow](#cli-and-video-rendering) produces
|
|
194
|
+
video and snapshots.
|
|
195
|
+
|
|
196
|
+
## Export an independent web embed
|
|
197
|
+
|
|
198
|
+
Bundle a finished scene into a custom element for a blog, documentation page or
|
|
199
|
+
another application. The exported files include the engine code and emitted
|
|
200
|
+
assets needed by that scene. The receiving site needs WebGPU and those files.
|
|
201
|
+
|
|
202
|
+
This recipe uses Vite 6, matching the generated project's toolchain. For a
|
|
203
|
+
generated npm project, save the following as `src/embed.ts`. Each element
|
|
204
|
+
owns its canvas and Scene, handles resizing, and cleans up when removed.
|
|
205
|
+
|
|
206
|
+
<details>
|
|
207
|
+
<summary>src/embed.ts</summary>
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import MyScene from './scenes/Retiam';
|
|
211
|
+
|
|
212
|
+
// A separate name lets this bundle coexist with other scene components.
|
|
213
|
+
class MyRetiamSceneElement extends HTMLElement {
|
|
214
|
+
private cleanup?: () => void;
|
|
215
|
+
|
|
216
|
+
connectedCallback() {
|
|
217
|
+
this.cleanup?.();
|
|
218
|
+
const canvas = document.createElement('canvas');
|
|
219
|
+
canvas.style.cssText = 'display:block;width:100%;height:100%';
|
|
220
|
+
this.replaceChildren(canvas);
|
|
221
|
+
const scene = new MyScene();
|
|
222
|
+
let cancelled = false, started = false, resizeFrame = 0;
|
|
223
|
+
let observer: ResizeObserver | undefined;
|
|
224
|
+
|
|
225
|
+
this.cleanup = () => {
|
|
226
|
+
cancelled = true;
|
|
227
|
+
observer?.disconnect();
|
|
228
|
+
cancelAnimationFrame(resizeFrame);
|
|
229
|
+
if (started) scene.destroy();
|
|
230
|
+
// A pending initialization cleans up in its continuation below.
|
|
231
|
+
};
|
|
232
|
+
void scene.start(canvas).then(() => {
|
|
233
|
+
started = true;
|
|
234
|
+
if (cancelled) { scene.destroy(); return; }
|
|
235
|
+
observer = new ResizeObserver(() => {
|
|
236
|
+
cancelAnimationFrame(resizeFrame);
|
|
237
|
+
resizeFrame = requestAnimationFrame(() => {
|
|
238
|
+
// Current composer resizing listens to the window resize event.
|
|
239
|
+
window.dispatchEvent(new Event('resize'));
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
observer.observe(this);
|
|
243
|
+
this.dispatchEvent(new CustomEvent('scene-ready', { bubbles: true }));
|
|
244
|
+
}).catch(error => {
|
|
245
|
+
scene.destroy();
|
|
246
|
+
if (!cancelled) {
|
|
247
|
+
const message = document.createElement('p');
|
|
248
|
+
message.setAttribute('role', 'alert');
|
|
249
|
+
message.textContent = String(error);
|
|
250
|
+
this.replaceChildren(message);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
disconnectedCallback() {
|
|
256
|
+
this.cleanup?.();
|
|
257
|
+
this.cleanup = undefined;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (!customElements.get('my-retiam-scene')) {
|
|
262
|
+
customElements.define('my-retiam-scene', MyRetiamSceneElement);
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
</details>
|
|
267
|
+
|
|
268
|
+
For a manual project, change the scene import to your scene module. The
|
|
269
|
+
[npm embed recipe](https://abhilasbiswas.github.io/retiam-docs/export/#embed-from-npm)
|
|
270
|
+
explains lifecycle handling, multiple instances and hosting.
|
|
271
|
+
|
|
272
|
+
Save this as `vite.embed.config.ts`:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { defineConfig } from 'vite';
|
|
276
|
+
|
|
277
|
+
export default defineConfig({
|
|
278
|
+
base: './',
|
|
279
|
+
build: {
|
|
280
|
+
target: 'es2022',
|
|
281
|
+
outDir: 'outputs/embed',
|
|
282
|
+
lib: {
|
|
283
|
+
entry: 'src/embed.ts',
|
|
284
|
+
formats: ['es'],
|
|
285
|
+
fileName: 'my-scene',
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Build the component:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
npx vite build --config vite.embed.config.ts
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Copy the **whole** `outputs/embed` folder to your website, for example under
|
|
298
|
+
`/embeds/my-scene/`, then mount the custom element:
|
|
299
|
+
|
|
300
|
+
```html
|
|
301
|
+
<script type="module" src="/embeds/my-scene/my-scene.js"></script>
|
|
302
|
+
<my-retiam-scene style="display:block;width:100%;height:540px"></my-retiam-scene>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The receiving site needs no npm installation or separate Retiam CDN import.
|
|
306
|
+
Preserve emitted files and their relative paths. Assets or services explicitly
|
|
307
|
+
referenced by remote URLs still need hosting. Use a distinct custom-element name
|
|
308
|
+
for each different scene bundle. An MP4 is the alternative when the receiving
|
|
309
|
+
page only needs video playback.
|
|
310
|
+
|
|
311
|
+
The engine repository also provides an export CLI:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
npx retiam export scenes/MyScene.ts outputs/embed
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Its current implementation expects the engine repository's `src/engine` layout.
|
|
318
|
+
Use the package-based Vite recipe above for generated and other external npm
|
|
319
|
+
projects. See [repository export](https://abhilasbiswas.github.io/retiam-docs/export/#standalone-embeds)
|
|
320
|
+
for the CLI's script and `<retiam-scene>` usage.
|
|
321
|
+
|
|
96
322
|
## CLI and video rendering
|
|
97
323
|
|
|
98
|
-
|
|
324
|
+
Run these commands from the generated project folder containing `package.json`
|
|
325
|
+
and `config.js`:
|
|
99
326
|
|
|
100
327
|
```bash
|
|
101
|
-
npx retiam lint scenes/
|
|
102
|
-
npx retiam snapshot scenes/
|
|
103
|
-
npx retiam render scenes/
|
|
328
|
+
npx retiam lint src/scenes/Retiam.ts --json
|
|
329
|
+
npx retiam snapshot src/scenes/Retiam.ts --times 1.0,2.5,4.0 --json
|
|
330
|
+
npx retiam render src/scenes/Retiam.ts
|
|
104
331
|
```
|
|
105
332
|
|
|
106
|
-
Puppeteer is a required production dependency of Retiam
|
|
333
|
+
Puppeteer is a required production dependency of Retiam and is installed automatically with the package. Render and snapshot commands need a working Chrome/WebGPU setup. Video rendering also requires FFmpeg on your `PATH`.
|
|
107
334
|
|
|
108
|
-
|
|
335
|
+
### Render configuration
|
|
109
336
|
|
|
110
|
-
|
|
337
|
+
The generated [config.js](packages/create-retiam/starter/config.js) contains CLI
|
|
338
|
+
output and renderer quality settings with their defaults and comments. The default output
|
|
339
|
+
is 1920×1080 at 60 fps, MP4 at `20M`, in `outputs/video`. `maxDuration: 0` renders
|
|
340
|
+
until the scene finishes; set a limit for scenes that loop indefinitely.
|
|
341
|
+
|
|
342
|
+
For a smaller draft, edit the output fields in `config.js`:
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
export default {
|
|
346
|
+
width: 1280,
|
|
347
|
+
height: 720,
|
|
348
|
+
fps: 30,
|
|
349
|
+
videoBitrate: '8M',
|
|
350
|
+
outputFormat: 'mp4',
|
|
351
|
+
outputDir: './outputs/video',
|
|
352
|
+
maxDuration: 4000, // milliseconds
|
|
353
|
+
};
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The renderer starts with built-in defaults, loads `config.js` from the calling
|
|
357
|
+
project, then applies CLI flags. If `retiam.config.js` exists, it is used instead
|
|
358
|
+
of `config.js`. For example, this renders at 60 fps while retaining the other
|
|
359
|
+
file settings:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
npx retiam render src/scenes/Retiam.ts -f 60
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
The complete file also covers anti-aliasing, transparency layers, shadows,
|
|
366
|
+
culling, raytracing, denoising, local server ports, and input replay.
|
|
367
|
+
See the [configuration reference](https://abhilasbiswas.github.io/retiam-docs/export/#render-configuration).
|
|
368
|
+
|
|
369
|
+
Choose surface appearance in scene code and materials:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { CelShading, GoochShading } from 'retiam';
|
|
373
|
+
|
|
374
|
+
this.shading = new CelShading({ bands: 3 }); // Scene default
|
|
375
|
+
sphere.material.shading = new GoochShading({ warm: 0.6, cool: 0.4 });
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Each shading model supplies its own WGSL. Numeric parameters update through the
|
|
379
|
+
material buffer without recompiling shaders. These styles apply to rasterized
|
|
380
|
+
3D models; raytracing uses its own physically based lighting.
|
|
381
|
+
|
|
382
|
+
For the manual setup above, use `scenes/FirstScene.ts` as the scene path. Rendering
|
|
383
|
+
and snapshots serve the project's `index.html`; a host that supports selecting
|
|
384
|
+
different scenes must load the CLI's `file` query parameter. The
|
|
385
|
+
[manual installation guide](https://abhilasbiswas.github.io/retiam-docs/installation/#create-a-consumer-application)
|
|
386
|
+
includes that bootstrap. Render duration (`-d`) is in milliseconds, snapshot
|
|
387
|
+
times are in seconds, and output (`-o`) is a directory. Render filenames include
|
|
388
|
+
a timestamp.
|
|
111
389
|
|
|
112
390
|
See [rendering and export](https://abhilasbiswas.github.io/retiam-docs/export/) for project setup and encoding options, or follow [package-based embeds](https://abhilasbiswas.github.io/retiam-docs/export/#embed-from-npm) to bundle a scene for another website. Run `npx retiam help` for the command reference.
|
|
113
391
|
|
|
@@ -126,10 +404,14 @@ Import shared scene primitives from `retiam` and specialized functionality from
|
|
|
126
404
|
| `retiam/rough` | RoughJS styling integration |
|
|
127
405
|
| `retiam/tts` | Microsoft Edge speech synthesis, narration, and subtitles |
|
|
128
406
|
|
|
129
|
-
See the [library guide](https://abhilasbiswas.github.io/retiam-docs/libraries/) for import boundaries and examples.
|
|
407
|
+
See the [library guide](https://abhilasbiswas.github.io/retiam-docs/libraries/) for import boundaries and examples. `roughjs` is a required production dependency and is installed automatically.
|
|
130
408
|
|
|
131
409
|
Built-in fonts and imported engine assets are included in the library package. Application media is managed separately. Edge speech synthesis in the browser requires a compatible service. See [asset workflows](https://abhilasbiswas.github.io/retiam-docs/asset-workflows/) and [speech and subtitles](https://abhilasbiswas.github.io/retiam-docs/speech-subtitles/) for setup.
|
|
132
410
|
|
|
411
|
+
MSDF font generation runs in a browser worker using the WASM supplied by
|
|
412
|
+
`@zappar/msdf-generator`, a production dependency. The repository's font-baking
|
|
413
|
+
tools, including `msdf-bmfont-xml` and `msdf-atlas-gen`, remain development tools.
|
|
414
|
+
|
|
133
415
|
## Repository development
|
|
134
416
|
|
|
135
417
|
Use Node.js 24, matching the documentation CI configuration.
|