@chromatic-coherence/generative-engine 1.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/LICENSE +36 -0
- package/README.md +80 -0
- package/dist/geometry.d.ts +40 -0
- package/dist/geometry.js +203 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/math.d.ts +45 -0
- package/dist/math.js +151 -0
- package/dist/post.d.ts +57 -0
- package/dist/post.js +213 -0
- package/dist/shaders.d.ts +17 -0
- package/dist/shaders.js +307 -0
- package/dist/world.d.ts +263 -0
- package/dist/world.js +764 -0
- package/package.json +44 -0
package/dist/world.d.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { V3, M4, TransformSpec } from "./math.js";
|
|
2
|
+
import { Mesh } from "./geometry.js";
|
|
3
|
+
export type LineOpts = {
|
|
4
|
+
hue: number;
|
|
5
|
+
sat?: number;
|
|
6
|
+
light?: number;
|
|
7
|
+
alpha: number;
|
|
8
|
+
group?: string;
|
|
9
|
+
};
|
|
10
|
+
export type GlowOpts = {
|
|
11
|
+
hue?: number;
|
|
12
|
+
white?: boolean;
|
|
13
|
+
size: number;
|
|
14
|
+
alpha: number;
|
|
15
|
+
group?: string;
|
|
16
|
+
};
|
|
17
|
+
export type FaceOpts = {
|
|
18
|
+
hue: number;
|
|
19
|
+
sat?: number;
|
|
20
|
+
light?: number;
|
|
21
|
+
alpha?: number;
|
|
22
|
+
group?: string;
|
|
23
|
+
/** per-face material gloss 0..1 (drives GGX roughness + specular): skin ~0.5, cloth ~0.05 */
|
|
24
|
+
gloss?: number;
|
|
25
|
+
/** per-face perfusion 0..1: blood near the surface (ruddiness, subsurface bleed, pulse) */
|
|
26
|
+
blood?: number;
|
|
27
|
+
};
|
|
28
|
+
export type RibbonOpts = {
|
|
29
|
+
hue: number;
|
|
30
|
+
sat?: number;
|
|
31
|
+
light?: number;
|
|
32
|
+
alpha: number;
|
|
33
|
+
/** stroke width in CSS pixels (the whole point of ribbons over gl.LINES) */
|
|
34
|
+
width: number;
|
|
35
|
+
group?: string;
|
|
36
|
+
};
|
|
37
|
+
export type PointLight = {
|
|
38
|
+
p: V3;
|
|
39
|
+
intensity: number;
|
|
40
|
+
falloff: number;
|
|
41
|
+
};
|
|
42
|
+
export type Projected = {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
s: number;
|
|
46
|
+
z: number;
|
|
47
|
+
};
|
|
48
|
+
export type GrowFn = (t: number, dt: number, w: World) => void;
|
|
49
|
+
export type WorldOpts = {
|
|
50
|
+
canvas: HTMLCanvasElement;
|
|
51
|
+
maxDpr?: number;
|
|
52
|
+
drift?: number;
|
|
53
|
+
parallax?: number;
|
|
54
|
+
controls?: boolean;
|
|
55
|
+
/** shadow maps — lights[0] casts. true, or { size (px, default 2048), softness, bias } */
|
|
56
|
+
shadows?: boolean | {
|
|
57
|
+
size?: number;
|
|
58
|
+
softness?: number;
|
|
59
|
+
bias?: number;
|
|
60
|
+
};
|
|
61
|
+
/** "light" renders the same recipe as ink on paper. Default "dark". */
|
|
62
|
+
theme?: "dark" | "light";
|
|
63
|
+
/** the engine owns its ground: fog and fades resolve toward this colour.
|
|
64
|
+
* "transparent" renders direct-to-canvas with no post chain (legacy compositing). */
|
|
65
|
+
background?: {
|
|
66
|
+
hue: number;
|
|
67
|
+
sat?: number;
|
|
68
|
+
light?: number;
|
|
69
|
+
} | "transparent";
|
|
70
|
+
/** the HDR post chain (bloom + SSAO + composite + FXAA). Default true. */
|
|
71
|
+
post?: boolean;
|
|
72
|
+
camera?: {
|
|
73
|
+
target?: V3;
|
|
74
|
+
dist?: number;
|
|
75
|
+
pitch?: number;
|
|
76
|
+
yaw?: number;
|
|
77
|
+
fov?: number;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export declare class World {
|
|
81
|
+
private canvas;
|
|
82
|
+
private gl;
|
|
83
|
+
private overlay;
|
|
84
|
+
private og;
|
|
85
|
+
private opts;
|
|
86
|
+
private pFace;
|
|
87
|
+
private pLine;
|
|
88
|
+
private pPt;
|
|
89
|
+
private pRib;
|
|
90
|
+
private pDepth;
|
|
91
|
+
private post;
|
|
92
|
+
private ink;
|
|
93
|
+
private bg;
|
|
94
|
+
private transparent;
|
|
95
|
+
private shadowsOn;
|
|
96
|
+
private shadowSize;
|
|
97
|
+
private shadowSoft;
|
|
98
|
+
private shadowBias;
|
|
99
|
+
private shadowFBO;
|
|
100
|
+
private shadowTex;
|
|
101
|
+
private svp;
|
|
102
|
+
private sFace;
|
|
103
|
+
private sLine;
|
|
104
|
+
private sPt;
|
|
105
|
+
private sRib;
|
|
106
|
+
private dFaceA;
|
|
107
|
+
private dLineA;
|
|
108
|
+
private dPtA;
|
|
109
|
+
private dRibA;
|
|
110
|
+
private labels;
|
|
111
|
+
private bFace;
|
|
112
|
+
private bLine;
|
|
113
|
+
private bPt;
|
|
114
|
+
private bRib;
|
|
115
|
+
private bFaceD;
|
|
116
|
+
private bLineD;
|
|
117
|
+
private bPtD;
|
|
118
|
+
private bRibD;
|
|
119
|
+
private staticDirty;
|
|
120
|
+
private hooks;
|
|
121
|
+
private raf;
|
|
122
|
+
private t0;
|
|
123
|
+
private tPrev;
|
|
124
|
+
private disposed;
|
|
125
|
+
private lastT;
|
|
126
|
+
private cleanup;
|
|
127
|
+
private fLight;
|
|
128
|
+
private fRib;
|
|
129
|
+
cam: {
|
|
130
|
+
target: V3;
|
|
131
|
+
dist: number;
|
|
132
|
+
pitch: number;
|
|
133
|
+
yawBase: number;
|
|
134
|
+
yawUser: number;
|
|
135
|
+
pitchUser: number;
|
|
136
|
+
distT: number;
|
|
137
|
+
fov: number;
|
|
138
|
+
};
|
|
139
|
+
light: {
|
|
140
|
+
dir: V3;
|
|
141
|
+
ambient: number;
|
|
142
|
+
diffuse: number;
|
|
143
|
+
signed: boolean;
|
|
144
|
+
};
|
|
145
|
+
/** up to 8 point lights; lights[0] casts the shadow map (when shadows are on) */
|
|
146
|
+
lights: PointLight[];
|
|
147
|
+
/** per-pixel specular strength (0 = matte); skin catches the light around 0.5 */
|
|
148
|
+
specular: number;
|
|
149
|
+
ambientSky: V3;
|
|
150
|
+
ambientGround: V3;
|
|
151
|
+
/** filmic tone map (ACES-ish) — runs in the composite pass now */
|
|
152
|
+
filmic: boolean;
|
|
153
|
+
/** the colour grade: violet-cool shadows, warm highlights — composite pass */
|
|
154
|
+
grade: boolean;
|
|
155
|
+
/** cinematic vignette 0..1 — composite pass (overlay fallback when post is off) */
|
|
156
|
+
vignette: number;
|
|
157
|
+
/** the global heartbeat 0..1 — rides the per-face blood */
|
|
158
|
+
bloodPulse: number;
|
|
159
|
+
/** HDR bloom — the light-on-dark aesthetic's native glow. Art-directable. */
|
|
160
|
+
bloom: {
|
|
161
|
+
on: boolean;
|
|
162
|
+
threshold: number;
|
|
163
|
+
knee: number;
|
|
164
|
+
strength: number;
|
|
165
|
+
};
|
|
166
|
+
/** depth-based SSAO — contact shading where surfaces meet */
|
|
167
|
+
ssao: {
|
|
168
|
+
on: boolean;
|
|
169
|
+
strength: number;
|
|
170
|
+
radius: number;
|
|
171
|
+
};
|
|
172
|
+
/** FXAA on the final composite */
|
|
173
|
+
fxaa: boolean;
|
|
174
|
+
private groupIdx;
|
|
175
|
+
private groupAlpha;
|
|
176
|
+
private groupTarget;
|
|
177
|
+
private groupMorph;
|
|
178
|
+
private groupMorphT;
|
|
179
|
+
private groupMat;
|
|
180
|
+
private groupNM;
|
|
181
|
+
private idxFor;
|
|
182
|
+
/** Fade a named group toward a target alpha — eased per frame. */
|
|
183
|
+
fade(name: string, target: number): void;
|
|
184
|
+
/** Blend a named group toward its morph target (meshMorph geometry) — eased per frame. */
|
|
185
|
+
morph(name: string, target: number): void;
|
|
186
|
+
/** Set a named group's model transform — a mat4 or a {translate, rotateY, scale...} spec.
|
|
187
|
+
* Geometry in the group moves rigidly with NO CPU re-tessellation. */
|
|
188
|
+
setTransform(name: string, m: M4 | TransformSpec): void;
|
|
189
|
+
W: number;
|
|
190
|
+
H: number;
|
|
191
|
+
private mx;
|
|
192
|
+
private my;
|
|
193
|
+
private mxT;
|
|
194
|
+
private myT;
|
|
195
|
+
private yawUserT;
|
|
196
|
+
private pitchUserT;
|
|
197
|
+
private cx;
|
|
198
|
+
private rt;
|
|
199
|
+
private up;
|
|
200
|
+
private fw;
|
|
201
|
+
private focal;
|
|
202
|
+
private vp;
|
|
203
|
+
private readonly zNear;
|
|
204
|
+
private readonly zFar;
|
|
205
|
+
constructor(o: WorldOpts);
|
|
206
|
+
private wireControls;
|
|
207
|
+
private resize;
|
|
208
|
+
private col;
|
|
209
|
+
private parseCol;
|
|
210
|
+
private inkCss;
|
|
211
|
+
private themedCss;
|
|
212
|
+
private pushFace;
|
|
213
|
+
/** One static triangle. Pass per-vertex normals for smooth shading; omit for flat. */
|
|
214
|
+
face(a: V3, b: V3, c: V3, o: FaceOpts, na?: V3, nb?: V3, nc?: V3): void;
|
|
215
|
+
/** Upload a whole Mesh (geometry.ts builders) as static faces in one call. */
|
|
216
|
+
mesh(geo: Mesh, o: FaceOpts): void;
|
|
217
|
+
/** Upload a morph pair: the group's morph weight blends A -> B in the vertex shader.
|
|
218
|
+
* The two meshes MUST have identical vertex counts (build them from the same recipe). */
|
|
219
|
+
meshMorph(geoA: Mesh, geoB: Mesh, o: FaceOpts): void;
|
|
220
|
+
line(a: V3, b: V3, o: LineOpts): void;
|
|
221
|
+
glow(p: V3, o: GlowOpts): void;
|
|
222
|
+
dust(p: V3, alpha: number): void;
|
|
223
|
+
private pushRibbon;
|
|
224
|
+
/** A static ribbon stroke — real pixel width, feathered edges, depth-tested. */
|
|
225
|
+
ribbon(pts: V3[], o: RibbonOpts): void;
|
|
226
|
+
grow(fn: GrowFn): void;
|
|
227
|
+
drawLine(a: V3, b: V3, color: string, alpha: number, width?: number): void;
|
|
228
|
+
drawPath(pts: {
|
|
229
|
+
p: V3;
|
|
230
|
+
}[], color: string, alpha: number, width?: number): void;
|
|
231
|
+
drawGlow(p: V3, hue: number | null, size: number, alpha: number): void;
|
|
232
|
+
drawLabel(p: V3, text: string, color: string, alpha: number, dy?: number): void;
|
|
233
|
+
drawFace(a: V3, b: V3, c: V3, o: FaceOpts, na?: V3, nb?: V3, nc?: V3): void;
|
|
234
|
+
/** A per-frame ribbon stroke — the animated counterpart of ribbon(). */
|
|
235
|
+
drawRibbon(pts: V3[], o: RibbonOpts): void;
|
|
236
|
+
/** Screen-space overlay (the 2D label canvas — never occluded). */
|
|
237
|
+
overlay2d(cb: (g: CanvasRenderingContext2D, w: World) => void): void;
|
|
238
|
+
private setupCamera;
|
|
239
|
+
project(p: V3): Projected | null;
|
|
240
|
+
fog(z: number): number;
|
|
241
|
+
pick(sx: number, sy: number, planeY?: number): V3 | null;
|
|
242
|
+
get surface(): HTMLCanvasElement;
|
|
243
|
+
private setGroups;
|
|
244
|
+
private setVP;
|
|
245
|
+
private setFog;
|
|
246
|
+
private setLights;
|
|
247
|
+
private attrib;
|
|
248
|
+
private depthDraw;
|
|
249
|
+
private drawFaces;
|
|
250
|
+
private drawLines;
|
|
251
|
+
private drawPts;
|
|
252
|
+
private drawRibbons;
|
|
253
|
+
private renderFrame;
|
|
254
|
+
start(): void;
|
|
255
|
+
/** Render one deterministic frame at time t (no loop) — stills, tests, screenshots. */
|
|
256
|
+
settle(t: number): void;
|
|
257
|
+
/** Stop the world. `releaseContext: true` also LOSES the GL context immediately —
|
|
258
|
+
* browsers cap live contexts per page and reclaim them only at GC, so many-canvas
|
|
259
|
+
* pages must release on teardown. A lost context is permanently dead on its canvas:
|
|
260
|
+
* a releasing caller must mount a FRESH canvas to build again (React: key it). */
|
|
261
|
+
dispose(releaseContext?: boolean): void;
|
|
262
|
+
}
|
|
263
|
+
export declare function createWorld(o: WorldOpts): World;
|