three-realtime-rt 0.3.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/src/index.d.ts ADDED
@@ -0,0 +1,289 @@
1
+ import type {
2
+ WebGLRenderer,
3
+ Scene,
4
+ Camera,
5
+ Color,
6
+ Vector3,
7
+ Object3D,
8
+ } from "three";
9
+
10
+ /** Capability tier used to pick sensible defaults. */
11
+ export type Tier = "none" | "mid" | "high";
12
+
13
+ /** Procedural-sky configuration (background + ambient light for escaping GI rays). */
14
+ export interface SkyOptions {
15
+ /** Enable the procedural sky as background and ambient GI source. */
16
+ enabled?: boolean;
17
+ /** Direction pointing toward the sun; keep in sync with your DirectionalLight. */
18
+ sunDir?: Vector3;
19
+ /** Sun disc / directional colour. */
20
+ sunColor?: Color;
21
+ /** Sky colour at the zenith (straight up). */
22
+ zenith?: Color;
23
+ /** Sky colour at the horizon. */
24
+ horizon?: Color;
25
+ /** Overall sky brightness multiplier. */
26
+ intensity?: number;
27
+ }
28
+
29
+ /** Distance-fog configuration (composited in linear space before tonemap). */
30
+ export interface FogOptions {
31
+ /** Enable distance fog. */
32
+ enabled?: boolean;
33
+ /** Fog colour. */
34
+ color?: Color;
35
+ /** Fog density. */
36
+ density?: number;
37
+ }
38
+
39
+ /** Volumetric single-scatter ("god rays") configuration. */
40
+ export interface VolumetricOptions {
41
+ /** Enable volumetric single-scatter lighting. */
42
+ enabled?: boolean;
43
+ /** Scattering/fog density along the primary ray. */
44
+ density?: number;
45
+ /** Maximum distance the volumetric integration marches. */
46
+ maxDist?: number;
47
+ }
48
+
49
+ /** Constructor options for {@link RealtimeRaytracer}. All optional. */
50
+ export interface RealtimeRaytracerOptions {
51
+ /**
52
+ * Resolution scale for the ray traced lighting (G-buffer and final image
53
+ * stay full res). 0.5 traces 4x fewer rays; the bilateral upsample +
54
+ * denoiser reconstruct the difference. Set 1.0 for maximum quality.
55
+ */
56
+ renderScale?: number;
57
+ /** À-trous denoise iterations (steps 1, 2, 4, ...). */
58
+ denoiseIterations?: number;
59
+ /**
60
+ * One stochastic direct shadow ray per pixel per frame (source picked at
61
+ * random) instead of one per light — the biggest ray-count lever for
62
+ * many-light scenes and mobile GPUs. Slightly noisier moving shadows.
63
+ */
64
+ stochasticLights?: boolean;
65
+ /**
66
+ * Adaptive quality governor: watches real frame time and steers renderScale,
67
+ * denoiseIterations and stochasticLights toward targetFps. Setting those
68
+ * manually while enabled will be overridden.
69
+ */
70
+ adaptiveQuality?: boolean;
71
+ /** Frame-rate target for the adaptive governor. */
72
+ targetFps?: number;
73
+ /**
74
+ * Emergency crash guard, ON by default: clamps oversized first buffers and
75
+ * cuts quality after consecutive >400ms frames (weak GPUs fed high settings
76
+ * can hang the whole machine). Set false to opt out.
77
+ */
78
+ overloadProtection?: boolean;
79
+ /**
80
+ * App-owned canvas-scale setter, driven by the governor as its deepest lever
81
+ * once renderScale bottoms out. The app owns the canvas + CSS stretch, so it
82
+ * applies the buffer resize itself; null disables this level.
83
+ */
84
+ canvasScaleHook?: ((scale: number) => void) | null;
85
+ /** 1-bounce global illumination (traced indirect). Toggle for a direct-only look. */
86
+ gi?: boolean;
87
+ /**
88
+ * Sample static emissive meshes as area lights (next-event estimation).
89
+ * Dramatically less noise than waiting for GI rays to hit the emitter.
90
+ */
91
+ emissiveNEE?: boolean;
92
+ /** Traced mirror/glossy reflections on metallic surfaces. */
93
+ reflections?: boolean;
94
+ /** Traced refraction for transmissive (MeshPhysicalMaterial.transmission) surfaces. */
95
+ refraction?: boolean;
96
+ /**
97
+ * ReSTIR direct lighting: per-pixel reservoirs converge onto the light that
98
+ * matters most to each pixel. Cost is flat in light count.
99
+ */
100
+ restir?: boolean;
101
+ /** Index of refraction used for transmissive surfaces. */
102
+ ior?: number;
103
+ /** History length cap: higher = smoother but slower to react. */
104
+ maxHistory?: number;
105
+ /** Clamp on indirect luminance to suppress fireflies. 0 disables. */
106
+ fireflyClamp?: number;
107
+ /** Reproject accumulated lighting through camera motion. */
108
+ temporalReprojection?: boolean;
109
+ /**
110
+ * Temporal anti-aliasing: sub-pixel projection jitter + a full-res history
111
+ * resolve with neighbourhood clamp.
112
+ */
113
+ taa?: boolean;
114
+ /** Fresh-sample weight in the TAA blend (lower = smoother/more AA, more lag). */
115
+ taaBlend?: number;
116
+ /** Edge-aware à-trous denoise on the irradiance buffer. */
117
+ denoise?: boolean;
118
+ /**
119
+ * Ray offset epsilon. When unset it is auto-scaled from the scene's size at
120
+ * compile time. Raise if you see acne; lower if light leaks through thin walls.
121
+ */
122
+ eps?: number;
123
+ /** Environment (sky) color used for GI rays that miss + composite background. */
124
+ envColor?: Color;
125
+ /** Environment intensity multiplier. */
126
+ envIntensity?: number;
127
+ /** Procedural sky configuration. */
128
+ sky?: SkyOptions;
129
+ /** Distance fog configuration. */
130
+ fog?: FogOptions;
131
+ /** Volumetric single-scatter configuration. */
132
+ volumetric?: VolumetricOptions;
133
+ }
134
+
135
+ /** Resolved sky state on a {@link RealtimeRaytracer} instance. */
136
+ export interface SkyState {
137
+ enabled: boolean;
138
+ sunDir: Vector3;
139
+ sunColor: Color;
140
+ zenith: Color;
141
+ horizon: Color;
142
+ intensity: number;
143
+ }
144
+
145
+ /** Resolved fog state on a {@link RealtimeRaytracer} instance. */
146
+ export interface FogState {
147
+ enabled: boolean;
148
+ color: Color;
149
+ density: number;
150
+ }
151
+
152
+ /** Resolved volumetric state on a {@link RealtimeRaytracer} instance. */
153
+ export interface VolumetricState {
154
+ enabled: boolean;
155
+ density: number;
156
+ maxDist: number;
157
+ }
158
+
159
+ /** Options accepted by {@link RealtimeRaytracer.compileScene} and {@link compileScene}. */
160
+ export interface CompileSceneOptions {
161
+ /** Meshes whose transforms change every frame; drive them with updateDynamic(). */
162
+ dynamicMeshes?: Object3D[];
163
+ }
164
+
165
+ /**
166
+ * A two-level BVH scene produced by {@link compileScene}. Static geometry is
167
+ * uploaded once; dynamic meshes are re-baked each frame via {@link updateDynamic}.
168
+ */
169
+ export class CompiledScene {
170
+ /** Total triangle count across the static and dynamic levels. */
171
+ triangleCount: number;
172
+ /** Number of lights scanned into the compiled light tables. */
173
+ lightCount: number;
174
+ /** Number of emissive triangles registered as NEE area lights. */
175
+ emissiveTriCount: number;
176
+ /** World-space diagonal of the static level (used to auto-scale ray epsilon). */
177
+ sceneDiagonal: number;
178
+ /** Re-bake moving meshes' current world transforms and refit the dynamic BVH. */
179
+ updateDynamic(): void;
180
+ /** Release GPU resources held by this compiled scene. */
181
+ dispose(): void;
182
+ }
183
+
184
+ /**
185
+ * Drop-in ray traced renderer for three.js scenes. Rasterizes a G-buffer for
186
+ * primary visibility, then traces BVH shadow rays + 1-bounce GI for lighting
187
+ * with progressive temporal accumulation.
188
+ */
189
+ export class RealtimeRaytracer {
190
+ /** Canvas-scale ladder used by the adaptive governor's deepest lever. */
191
+ static CANVAS_LEVELS: number[];
192
+
193
+ /** Can this renderer run the ray tracing pipeline at all (WebGL2 + float RTs on hardware GPU)? */
194
+ static isSupported(renderer: WebGLRenderer): boolean;
195
+ /** Rough capability tier for choosing defaults. */
196
+ static detectTier(renderer?: WebGLRenderer): Tier;
197
+ /** Sensible constructor options for a tier (spread them, then override). */
198
+ static recommendedOptions(tier: Tier): RealtimeRaytracerOptions;
199
+
200
+ constructor(renderer: WebGLRenderer, options?: RealtimeRaytracerOptions);
201
+
202
+ /** The three.js renderer this instance drives. */
203
+ renderer: WebGLRenderer;
204
+ /** False when the platform can't run the tracer; render() then forwards to renderer.render. */
205
+ supported: boolean;
206
+ /** The current compiled scene, or null before the first compile / when unsupported. */
207
+ compiled: CompiledScene | null;
208
+ /** Accumulated frame counter. */
209
+ frame: number;
210
+ /** Debug view: 0 composite, 1 albedo, 2 normal, 3 irradiance, 4 worldPos, 5 emissive. */
211
+ outputMode: number;
212
+
213
+ /** Resolution scale for the ray traced lighting; assigning reallocates targets. */
214
+ get renderScale(): number;
215
+ set renderScale(v: number);
216
+
217
+ /** Environment (sky) color for GI rays that miss + composite background. */
218
+ envColor: Color;
219
+ /** Environment intensity multiplier. */
220
+ envIntensity: number;
221
+ /** Ray offset epsilon (auto-scaled from scene size unless set explicitly). */
222
+ eps: number;
223
+ /** Reproject accumulated lighting through camera motion. */
224
+ temporalReprojection: boolean;
225
+ /** History length cap. */
226
+ maxHistory: number;
227
+ /** Clamp on indirect luminance to suppress fireflies. 0 disables. */
228
+ fireflyClamp: number;
229
+ /** 1-bounce global illumination. */
230
+ gi: boolean;
231
+ /** Sample static emissive meshes as area lights (NEE). */
232
+ emissiveNEE: boolean;
233
+ /** Traced mirror/glossy reflections on metallic surfaces. */
234
+ reflections: boolean;
235
+ /** Traced refraction for transmissive surfaces. */
236
+ refraction: boolean;
237
+ /** Index of refraction used for transmissive surfaces. */
238
+ ior: number;
239
+ /** One stochastic direct shadow ray per pixel per frame instead of one per light. */
240
+ stochasticLights: boolean;
241
+ /** Adaptive quality governor toggle. */
242
+ adaptiveQuality: boolean;
243
+ /** Frame-rate target for the adaptive governor. */
244
+ targetFps: number;
245
+ /** Emergency crash guard (see RealtimeRaytracerOptions.overloadProtection). */
246
+ overloadProtection: boolean;
247
+ /** App-owned canvas-scale setter driven by the governor; null disables it. */
248
+ canvasScaleHook: ((scale: number) => void) | null;
249
+ /** Edge-aware à-trous denoise on the irradiance buffer. */
250
+ denoise: boolean;
251
+ /** À-trous iterations (steps 1, 2, 4, ...). */
252
+ denoiseIterations: number;
253
+ /** Temporal anti-aliasing toggle. */
254
+ taa: boolean;
255
+ /** Fresh-sample weight in the TAA blend. */
256
+ taaBlend: number;
257
+ /** ReSTIR direct lighting toggle. */
258
+ restir: boolean;
259
+ /** Procedural-sky state. */
260
+ sky: SkyState;
261
+ /** Distance-fog state. */
262
+ fog: FogState;
263
+ /** Volumetric single-scatter state. */
264
+ volumetric: VolumetricState;
265
+
266
+ /**
267
+ * Build/rebuild BVH + material and light tables from the scene. Call after
268
+ * structural scene changes. Returns null when the platform is unsupported.
269
+ */
270
+ compileScene(scene: Scene, options?: CompileSceneOptions): CompiledScene | null;
271
+ /** Re-bake moving (dynamic) meshes into the dynamic BVH level. Call each frame after moving them. */
272
+ updateDynamic(): void;
273
+ /** Refresh light positions/colors from the scene without a full recompile. */
274
+ updateLights(scene: Scene): void;
275
+ /** Discard temporal history and restart accumulation. */
276
+ resetAccumulation(): void;
277
+ /** Resize all internal render targets. */
278
+ setSize(width: number, height: number): void;
279
+ /** Render one frame (call instead of renderer.render). */
280
+ render(scene: Scene, camera: Camera): void;
281
+ /** Release all GPU resources held by this instance. */
282
+ dispose(): void;
283
+ }
284
+
285
+ /** Stage-1 cap on the number of lights scanned into the compiled light tables. */
286
+ export const MAX_LIGHTS: number;
287
+
288
+ /** Build a {@link CompiledScene} (BVH + material/light tables) from a scene. */
289
+ export function compileScene(scene: Scene, options?: CompileSceneOptions): CompiledScene;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { RealtimeRaytracer } from "./RealtimeRaytracer.js";
2
+ export { compileScene, CompiledScene, MAX_LIGHTS } from "./SceneCompiler.js";
@@ -0,0 +1,23 @@
1
+ // Shared procedural sky, injected into both the lighting pass (GI rays that
2
+ // miss geometry sample it, so the sky becomes a soft area light) and the
3
+ // composite pass (background pixels show it). A cheap analytic model: a
4
+ // horizon->zenith gradient, a dim ground hemisphere, and a sun disk + halo.
5
+ // `dir` and `sunDir` are world-space unit vectors; `sunDir` points TOWARD the
6
+ // sun. The returned radiance already includes `intensity`.
7
+ export const SKY_GLSL = /* glsl */ `
8
+ vec3 skyColor(vec3 dir, vec3 sunDir, vec3 sunColor, vec3 zenith, vec3 horizon, float intensity) {
9
+ float up = clamp(dir.y, -1.0, 1.0);
10
+ // Gradient sky: biased so the horizon band stays fairly tall.
11
+ float t = pow(clamp(up, 0.0, 1.0), 0.42);
12
+ vec3 col = mix(horizon, zenith, t);
13
+ // Below the horizon settle gently toward a soft haze — kept close to the
14
+ // horizon colour so the ground plane's far edge blends in without a hard band.
15
+ if (up < 0.0) {
16
+ col = mix(horizon, horizon * 0.72, clamp(-up * 1.6, 0.0, 1.0));
17
+ }
18
+ // Sun: a tight disk plus a broad warm halo bleeding into the sky.
19
+ float s = max(dot(dir, sunDir), 0.0);
20
+ vec3 sun = sunColor * (pow(s, 3000.0) * 55.0 + pow(s, 12.0) * 0.30);
21
+ return (col + sun) * intensity;
22
+ }
23
+ `;