@holoscript/engine 6.0.3 → 6.0.4

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 (192) hide show
  1. package/dist/AutoMesher-CK47F6AV.js +17 -0
  2. package/dist/GPUBuffers-2LHBCD7X.js +9 -0
  3. package/dist/WebGPUContext-TNEUYU2Y.js +11 -0
  4. package/dist/animation/index.cjs +38 -38
  5. package/dist/animation/index.d.cts +1 -1
  6. package/dist/animation/index.d.ts +1 -1
  7. package/dist/animation/index.js +1 -1
  8. package/dist/audio/index.cjs +16 -6
  9. package/dist/audio/index.d.cts +1 -1
  10. package/dist/audio/index.d.ts +1 -1
  11. package/dist/audio/index.js +1 -1
  12. package/dist/camera/index.cjs +23 -23
  13. package/dist/camera/index.d.cts +1 -1
  14. package/dist/camera/index.d.ts +1 -1
  15. package/dist/camera/index.js +1 -1
  16. package/dist/character/index.cjs +6 -4
  17. package/dist/character/index.js +1 -1
  18. package/dist/choreography/index.cjs +1194 -0
  19. package/dist/choreography/index.d.cts +687 -0
  20. package/dist/choreography/index.d.ts +687 -0
  21. package/dist/choreography/index.js +1156 -0
  22. package/dist/chunk-2CSNRI2N.js +217 -0
  23. package/dist/chunk-33T2WINR.js +266 -0
  24. package/dist/chunk-35R73OFM.js +1257 -0
  25. package/dist/chunk-4MMDSUNP.js +1256 -0
  26. package/dist/chunk-5V6HOU72.js +319 -0
  27. package/dist/chunk-6QOP6PYF.js +1038 -0
  28. package/dist/chunk-7KMJVHIL.js +8944 -0
  29. package/dist/chunk-7VPUC62U.js +1106 -0
  30. package/dist/chunk-A2Y6RCAT.js +1878 -0
  31. package/dist/chunk-AHM42MK6.js +8944 -0
  32. package/dist/chunk-BL7IDTHE.js +218 -0
  33. package/dist/chunk-CITOMSWL.js +10462 -0
  34. package/dist/chunk-CXDPKW2K.js +8944 -0
  35. package/dist/chunk-CXZPLD4S.js +223 -0
  36. package/dist/chunk-CZYJE7IH.js +5169 -0
  37. package/dist/chunk-D2OP7YC7.js +6325 -0
  38. package/dist/chunk-EDRVQHUU.js +1544 -0
  39. package/dist/chunk-EJSLOOW2.js +3589 -0
  40. package/dist/chunk-F53SFGW5.js +1878 -0
  41. package/dist/chunk-HCFPELPY.js +919 -0
  42. package/dist/chunk-HNEE36PY.js +93 -0
  43. package/dist/chunk-HYXNV36F.js +1256 -0
  44. package/dist/chunk-IB7KHVFY.js +821 -0
  45. package/dist/chunk-IBBO7YYG.js +690 -0
  46. package/dist/chunk-ILIBGINU.js +5470 -0
  47. package/dist/chunk-IS4MHLKN.js +5479 -0
  48. package/dist/chunk-JT2PFKWD.js +5479 -0
  49. package/dist/chunk-K4CUB4NY.js +1038 -0
  50. package/dist/chunk-KATDQXRJ.js +10462 -0
  51. package/dist/chunk-KBQE6ZFJ.js +8944 -0
  52. package/dist/chunk-KBVD5K7E.js +560 -0
  53. package/dist/chunk-KCDPVQRY.js +4088 -0
  54. package/dist/chunk-KN4QJPKN.js +8944 -0
  55. package/dist/chunk-KWJ3ROSI.js +8944 -0
  56. package/dist/chunk-L45VF6DD.js +919 -0
  57. package/dist/chunk-LY4T37YK.js +307 -0
  58. package/dist/chunk-MDN5WZXA.js +1544 -0
  59. package/dist/chunk-MGCDP6VU.js +928 -0
  60. package/dist/chunk-NCX7X6G2.js +8681 -0
  61. package/dist/chunk-OF54BPVD.js +913 -0
  62. package/dist/chunk-OWSN2Q3Q.js +690 -0
  63. package/dist/chunk-PRRB5TTA.js +406 -0
  64. package/dist/chunk-PXWVQF76.js +4086 -0
  65. package/dist/chunk-PYCOIDT2.js +812 -0
  66. package/dist/chunk-PZCSADOV.js +928 -0
  67. package/dist/chunk-Q2XBVS2K.js +1038 -0
  68. package/dist/chunk-QDZRXWN5.js +1776 -0
  69. package/dist/chunk-RNWOZ6WQ.js +913 -0
  70. package/dist/chunk-ROLFT4CJ.js +1693 -0
  71. package/dist/chunk-SLTJRZ2N.js +266 -0
  72. package/dist/chunk-SRUS5XSU.js +4088 -0
  73. package/dist/chunk-TKCA3WZ5.js +5409 -0
  74. package/dist/chunk-TNRMXYI2.js +1650 -0
  75. package/dist/chunk-TQB3GJGM.js +9763 -0
  76. package/dist/chunk-TUFGXG6K.js +510 -0
  77. package/dist/chunk-U6KMTGQJ.js +632 -0
  78. package/dist/chunk-VMGJQST6.js +8681 -0
  79. package/dist/chunk-X4F4TCG4.js +5470 -0
  80. package/dist/chunk-ZIFROE75.js +1544 -0
  81. package/dist/chunk-ZIJQYHSQ.js +1204 -0
  82. package/dist/combat/index.cjs +4 -4
  83. package/dist/combat/index.d.cts +1 -1
  84. package/dist/combat/index.d.ts +1 -1
  85. package/dist/combat/index.js +1 -1
  86. package/dist/ecs/index.cjs +1 -1
  87. package/dist/ecs/index.js +1 -1
  88. package/dist/environment/index.cjs +14 -14
  89. package/dist/environment/index.d.cts +1 -1
  90. package/dist/environment/index.d.ts +1 -1
  91. package/dist/environment/index.js +1 -1
  92. package/dist/gpu/index.cjs +4810 -0
  93. package/dist/gpu/index.js +3714 -0
  94. package/dist/hologram/index.cjs +27 -1
  95. package/dist/hologram/index.js +1 -1
  96. package/dist/index-B2PIsAmR.d.cts +2180 -0
  97. package/dist/index-B2PIsAmR.d.ts +2180 -0
  98. package/dist/index-BHySEPX7.d.cts +2921 -0
  99. package/dist/index-BJV21zuy.d.cts +341 -0
  100. package/dist/index-BJV21zuy.d.ts +341 -0
  101. package/dist/index-BQutTphC.d.cts +790 -0
  102. package/dist/index-ByIq2XrS.d.cts +3910 -0
  103. package/dist/index-BysHjDSO.d.cts +224 -0
  104. package/dist/index-BysHjDSO.d.ts +224 -0
  105. package/dist/index-CKwAJGck.d.ts +455 -0
  106. package/dist/index-CUl3QstQ.d.cts +3006 -0
  107. package/dist/index-CUl3QstQ.d.ts +3006 -0
  108. package/dist/index-CmYtNiI-.d.cts +953 -0
  109. package/dist/index-CmYtNiI-.d.ts +953 -0
  110. package/dist/index-CnRzWxi_.d.cts +522 -0
  111. package/dist/index-CnRzWxi_.d.ts +522 -0
  112. package/dist/index-CwRWbSC7.d.ts +2921 -0
  113. package/dist/index-CxKIBstO.d.ts +790 -0
  114. package/dist/index-DJ6-R8vh.d.cts +455 -0
  115. package/dist/index-DQKisbcI.d.cts +4968 -0
  116. package/dist/index-DQKisbcI.d.ts +4968 -0
  117. package/dist/index-DRT2zJez.d.ts +3910 -0
  118. package/dist/index-DfNLiAka.d.cts +192 -0
  119. package/dist/index-DfNLiAka.d.ts +192 -0
  120. package/dist/index-nMvkoRm8.d.cts +405 -0
  121. package/dist/index-nMvkoRm8.d.ts +405 -0
  122. package/dist/index-s9yOFU37.d.cts +604 -0
  123. package/dist/index-s9yOFU37.d.ts +604 -0
  124. package/dist/index.cjs +22966 -6960
  125. package/dist/index.d.cts +864 -20
  126. package/dist/index.d.ts +864 -20
  127. package/dist/index.js +3062 -48
  128. package/dist/input/index.cjs +1 -1
  129. package/dist/input/index.js +1 -1
  130. package/dist/orbital/index.cjs +3 -3
  131. package/dist/orbital/index.d.cts +1 -1
  132. package/dist/orbital/index.d.ts +1 -1
  133. package/dist/orbital/index.js +1 -1
  134. package/dist/particles/index.cjs +16 -16
  135. package/dist/particles/index.d.cts +1 -1
  136. package/dist/particles/index.d.ts +1 -1
  137. package/dist/particles/index.js +1 -1
  138. package/dist/physics/index.cjs +2377 -21
  139. package/dist/physics/index.d.cts +1 -1
  140. package/dist/physics/index.d.ts +1 -1
  141. package/dist/physics/index.js +35 -1
  142. package/dist/postfx/index.cjs +3491 -0
  143. package/dist/postfx/index.js +93 -0
  144. package/dist/procedural/index.cjs +1 -1
  145. package/dist/procedural/index.js +1 -1
  146. package/dist/puppeteer-5VF6KDVO.js +52197 -0
  147. package/dist/puppeteer-IZVZ3SG4.js +52197 -0
  148. package/dist/rendering/index.cjs +33 -32
  149. package/dist/rendering/index.d.cts +1 -1
  150. package/dist/rendering/index.d.ts +1 -1
  151. package/dist/rendering/index.js +8 -6
  152. package/dist/runtime/index.cjs +23 -13
  153. package/dist/runtime/index.d.cts +1 -1
  154. package/dist/runtime/index.d.ts +1 -1
  155. package/dist/runtime/index.js +8 -6
  156. package/dist/runtime/protocols/index.cjs +349 -0
  157. package/dist/runtime/protocols/index.js +15 -0
  158. package/dist/scene/index.cjs +8 -8
  159. package/dist/scene/index.d.cts +1 -1
  160. package/dist/scene/index.d.ts +1 -1
  161. package/dist/scene/index.js +1 -1
  162. package/dist/shader/index.cjs +3087 -0
  163. package/dist/shader/index.js +3044 -0
  164. package/dist/simulation/index.cjs +10680 -0
  165. package/dist/simulation/index.d.cts +3 -0
  166. package/dist/simulation/index.d.ts +3 -0
  167. package/dist/simulation/index.js +307 -0
  168. package/dist/spatial/index.cjs +2443 -0
  169. package/dist/spatial/index.d.cts +1545 -0
  170. package/dist/spatial/index.d.ts +1545 -0
  171. package/dist/spatial/index.js +2400 -0
  172. package/dist/terrain/index.cjs +1 -1
  173. package/dist/terrain/index.d.cts +1 -1
  174. package/dist/terrain/index.d.ts +1 -1
  175. package/dist/terrain/index.js +1 -1
  176. package/dist/transformers.node-4NKAPD5U.js +45620 -0
  177. package/dist/vm/index.cjs +7 -8
  178. package/dist/vm/index.d.cts +1 -1
  179. package/dist/vm/index.d.ts +1 -1
  180. package/dist/vm/index.js +1 -1
  181. package/dist/vm-bridge/index.cjs +2 -2
  182. package/dist/vm-bridge/index.d.cts +2 -2
  183. package/dist/vm-bridge/index.d.ts +2 -2
  184. package/dist/vm-bridge/index.js +1 -1
  185. package/dist/vr/index.cjs +6 -6
  186. package/dist/vr/index.js +1 -1
  187. package/dist/world/index.cjs +3 -3
  188. package/dist/world/index.d.cts +1 -1
  189. package/dist/world/index.d.ts +1 -1
  190. package/dist/world/index.js +1 -1
  191. package/package.json +53 -21
  192. package/LICENSE +0 -21
@@ -0,0 +1,3910 @@
1
+ import { E as EngineSystem } from './SpatialEngine-CXmE-U_d.cjs';
2
+ import { g as IPhysicsWorld } from './PhysicsTypes-Dw6_oXuD.cjs';
3
+
4
+ /**
5
+ * BloomEffect.ts
6
+ *
7
+ * Bloom post-process: threshold extraction, blur passes,
8
+ * soft knee, intensity, and composite blending.
9
+ *
10
+ * @module rendering
11
+ */
12
+ interface BloomConfig {
13
+ threshold: number;
14
+ softKnee: number;
15
+ intensity: number;
16
+ radius: number;
17
+ passes: number;
18
+ enabled: boolean;
19
+ }
20
+ declare class BloomEffect$1 {
21
+ private config;
22
+ setThreshold(val: number): void;
23
+ setSoftKnee(val: number): void;
24
+ setIntensity(val: number): void;
25
+ setRadius(val: number): void;
26
+ setPasses(val: number): void;
27
+ setEnabled(val: boolean): void;
28
+ getConfig(): BloomConfig;
29
+ extractBright(pixels: Float32Array, _width: number, _height: number): Float32Array;
30
+ blur(pixels: Float32Array, width: number, height: number): Float32Array;
31
+ private blurPass;
32
+ composite(original: Float32Array, bloom: Float32Array): Float32Array;
33
+ apply(pixels: Float32Array, width: number, height: number): Float32Array;
34
+ }
35
+
36
+ /**
37
+ * AdvancedLighting.ts
38
+ *
39
+ * Advanced light types beyond point / directional / spot:
40
+ * - Area lights: rectangle, disk, tube (LTC approximation)
41
+ * - IES light profiles (photometric, from .ies tabular data)
42
+ * - Emissive mesh lights
43
+ * - Light cookies (projected texture masks)
44
+ * - Caustic intensity configuration
45
+ *
46
+ * All calculations are CPU-side (uniform / config helpers).
47
+ * No WebGPU — fully testable in Vitest.
48
+ *
49
+ * @module rendering
50
+ */
51
+ type Vec3$4 = {
52
+ x: number;
53
+ y: number;
54
+ z: number;
55
+ };
56
+ type Vec2$1 = {
57
+ x: number;
58
+ y: number;
59
+ };
60
+ type AreaLightShape = 'rectangle' | 'disk' | 'tube';
61
+ type LightType$1 = 'point' | 'spot' | 'directional' | 'area' | 'ies' | 'emissive_mesh';
62
+ interface AreaLightConfig {
63
+ shape: AreaLightShape;
64
+ /** Half-extents for rectangle [w, h], radius for disk, [r, length] for tube */
65
+ size: Vec2$1;
66
+ /** Two-sided emission */
67
+ twoSided: boolean;
68
+ }
69
+ interface IESProfile {
70
+ id: string;
71
+ /** Vertical angles (0–180°) */
72
+ verticalAngles: number[];
73
+ /** Horizontal angles (0–360°) */
74
+ horizontalAngles: number[];
75
+ /** Candela values [horizontal][vertical] */
76
+ candela: number[][];
77
+ /** Maximum candela (for normalisation) */
78
+ maxCandela: number;
79
+ }
80
+ interface LightCookie {
81
+ /** Cookie texture width */
82
+ width: number;
83
+ /** Cookie texture height */
84
+ height: number;
85
+ /** RGBA pixel data (Float32Array, linear) */
86
+ pixels: Float32Array;
87
+ }
88
+ interface CausticConfig {
89
+ intensity: number;
90
+ sampleCount: number;
91
+ animationSpeed: number;
92
+ }
93
+ interface AdvancedLight {
94
+ id: string;
95
+ type: LightType$1;
96
+ position: Vec3$4;
97
+ direction: Vec3$4;
98
+ color: [number, number, number];
99
+ intensity: number;
100
+ range: number;
101
+ enabled: boolean;
102
+ area?: AreaLightConfig;
103
+ ies?: IESProfile;
104
+ cookie?: LightCookie;
105
+ caustic?: CausticConfig;
106
+ /** Mesh geometry ID for emissive mesh lights */
107
+ meshId?: string;
108
+ }
109
+ /**
110
+ * Parse a simplified IES LM-63 candela table.
111
+ * Expects lines: "vertical_angles\nhorizontal_angles\ncandela_values..."
112
+ *
113
+ * For production use this would parse the full IES spec; here we handle
114
+ * the minimal tabular data format used in tests.
115
+ */
116
+ declare function parseIESProfile(id: string, vertAngles: number[], horizAngles: number[], candela: number[][]): IESProfile;
117
+ /**
118
+ * Sample an IES profile for a given vertical + horizontal angle (degrees).
119
+ * Returns normalised intensity [0–1].
120
+ */
121
+ declare function sampleIES(profile: IESProfile, vertDeg: number, horizDeg: number): number;
122
+ /**
123
+ * Compute solid angle subtended by a rectangular area light.
124
+ * All positions in world space.
125
+ */
126
+ declare function rectSolidAngle(surfacePos: Vec3$4, lightPos: Vec3$4, right: Vec3$4, up: Vec3$4, halfWidth: number, halfHeight: number): number;
127
+ /**
128
+ * Disk area light — solid angle approximation.
129
+ */
130
+ declare function diskSolidAngle(surfacePos: Vec3$4, lightPos: Vec3$4, radius: number): number;
131
+ /**
132
+ * Build a simple circular light cookie (sharp circular spot).
133
+ */
134
+ declare function buildCircleCookie(width: number, height: number, edgeSoftness?: number): LightCookie;
135
+ /**
136
+ * Sample a light cookie at UV coordinates [0–1].
137
+ * Returns [r, g, b, a].
138
+ */
139
+ declare function sampleCookie(cookie: LightCookie, u: number, v: number): [number, number, number, number];
140
+ declare class AdvancedLightingManager {
141
+ private lights;
142
+ addLight(config: Partial<AdvancedLight> & {
143
+ type: LightType$1;
144
+ }): AdvancedLight;
145
+ removeLight(id: string): boolean;
146
+ getLight(id: string): AdvancedLight | undefined;
147
+ getLightCount(): number;
148
+ getEnabledCount(): number;
149
+ getLightsByType(type: LightType$1): AdvancedLight[];
150
+ /**
151
+ * Set a light cookie on an existing light.
152
+ */
153
+ setCookie(id: string, cookie: LightCookie): void;
154
+ /**
155
+ * Set an IES profile on an existing light.
156
+ */
157
+ setIES(id: string, profile: IESProfile): void;
158
+ /**
159
+ * Get total emissive power from all enabled emissive mesh lights.
160
+ */
161
+ getTotalEmissivePower(): number;
162
+ clear(): void;
163
+ }
164
+
165
+ /**
166
+ * AdvancedPBR.ts
167
+ *
168
+ * Advanced Physically-Based Rendering material model.
169
+ *
170
+ * Extends basic PBR (albedo + normal + roughness) with:
171
+ * - Clearcoat layer (car paint, lacquer, wet surfaces)
172
+ * - Anisotropy (brushed metal, hair, fabric warp)
173
+ * - Sheen (velvet, cloth, microfibre)
174
+ * - Iridescence (soap bubbles, oil slicks, beetle shells)
175
+ * - Multi-layer material stack
176
+ * - Metallic/roughness workflow helpers
177
+ *
178
+ * All calculations are CPU-side (can feed GPU uniforms or be used in
179
+ * offline renderers). No WebGPU imports — fully testable in Vitest.
180
+ *
181
+ * @module rendering
182
+ */
183
+ interface Vec3$3 {
184
+ x: number;
185
+ y: number;
186
+ z: number;
187
+ }
188
+ type RGB$1 = [number, number, number];
189
+ interface ClearcoatConfig {
190
+ /** 0–1, overall clearcoat presence */
191
+ intensity: number;
192
+ /** 0–1, surface roughness of the clearcoat layer */
193
+ roughness: number;
194
+ /** Index of refraction (default 1.5 for glass-like coat) */
195
+ ior: number;
196
+ }
197
+ interface AnisotropyConfig {
198
+ /** 0–1, anisotropy magnitude */
199
+ strength: number;
200
+ /** Rotation angle of anisotropic tangent in radians */
201
+ angle: number;
202
+ /** Anisotropy direction vector (must be unit) */
203
+ tangent: Vec3$3;
204
+ }
205
+ interface SheenConfig {
206
+ /** RGB tint for sheen reflection */
207
+ color: RGB$1;
208
+ /** 0–1, surface roughness of sheen layer (velvet = low) */
209
+ roughness: number;
210
+ }
211
+ interface IridescenceConfig {
212
+ /** 0–1, how visible the iridescent effect is */
213
+ intensity: number;
214
+ /** Index of refraction of thin film */
215
+ ior: number;
216
+ /** Thin-film thickness in nanometres (400–1200 typical) */
217
+ thicknessNm: number;
218
+ }
219
+ interface AdvancedPBRConfig {
220
+ /** Base albedo (linear RGB) */
221
+ albedo: RGB$1;
222
+ /** 0–1, 0 = dielectric, 1 = metal */
223
+ metallic: number;
224
+ /** 0–1, microsurface roughness */
225
+ roughness: number;
226
+ /** Ambient occlusion 0–1 */
227
+ ao: number;
228
+ /** Emissive colour (HDR, can exceed 1) */
229
+ emissive: RGB$1;
230
+ clearcoat?: ClearcoatConfig;
231
+ anisotropy?: AnisotropyConfig;
232
+ sheen?: SheenConfig;
233
+ iridescence?: IridescenceConfig;
234
+ }
235
+ /** GGX / Trowbridge-Reitz normal distribution function */
236
+ declare function distributionGGX(NdotH: number, roughness: number): number;
237
+ /** Smith's geometry attenuation (Schlick-GGX) */
238
+ declare function geometrySmith(NdotV: number, NdotL: number, roughness: number): number;
239
+ /** Schlick Fresnel approximation */
240
+ declare function fresnelSchlick(cosTheta: number, F0: RGB$1): RGB$1;
241
+ /** Schlick Fresnel with roughness (for IBL) */
242
+ declare function fresnelRoughness(cosTheta: number, F0: RGB$1, roughness: number): RGB$1;
243
+ /**
244
+ * Evaluate clearcoat layer BRDF contribution.
245
+ * Uses a separate GGX lobe with IOR-derived F0 ≈ ((ior-1)/(ior+1))².
246
+ */
247
+ declare function evaluateClearcoat(NdotH: number, NdotV: number, NdotL: number, VdotH: number, config: ClearcoatConfig): number;
248
+ /**
249
+ * GGX NDF modified for anisotropic surfaces (Burley 2012).
250
+ * alphaT and alphaB are per-axis roughness values.
251
+ */
252
+ declare function distributionGGXAnisotropic(NdotH: number, TdotH: number, BdotH: number, alphaT: number, alphaB: number): number;
253
+ /**
254
+ * Compute per-axis roughness values from isotropic roughness + anisotropy strength.
255
+ * Returns [alphaT, alphaB].
256
+ */
257
+ declare function anisotropicRoughness(roughness: number, strength: number): [number, number];
258
+ /**
259
+ * Charlie sheen NDF (Estevez & Kulla 2017).
260
+ * Produces the characteristic soft highlight at grazing angles.
261
+ */
262
+ declare function sheenDistribution(NdotH: number, roughness: number): number;
263
+ /** Sheen visibility function (L(NdotV) * L(NdotL)) */
264
+ declare function sheenVisibility(NdotV: number, NdotL: number): number;
265
+ /** Evaluate full sheen BRDF contribution */
266
+ declare function evaluateSheen(NdotH: number, NdotV: number, NdotL: number, config: SheenConfig): RGB$1;
267
+ /**
268
+ * Thin-film interference iridescence (McGuire & Skelton 2020).
269
+ * Computes a wavelength-dependent phase shift and maps it to RGB.
270
+ * wavelengths: [680, 550, 440] nm (R, G, B).
271
+ */
272
+ declare function evaluateIridescence(cosTheta: number, config: IridescenceConfig): RGB$1;
273
+ /**
274
+ * Compute F0 (reflectance at normal incidence) from albedo + metallic.
275
+ * Dielectrics: F0 ≈ 0.04 (non-metals), metals: F0 = albedo.
276
+ */
277
+ declare function computeF0(albedo: RGB$1, metallic: number): RGB$1;
278
+ /**
279
+ * Compute diffuse albedo for metallic surfaces (metals have no diffuse).
280
+ */
281
+ declare function computeDiffuseAlbedo(albedo: RGB$1, metallic: number): RGB$1;
282
+ declare class AdvancedPBRMaterial {
283
+ private config;
284
+ constructor(config?: Partial<AdvancedPBRConfig>);
285
+ setAlbedo(r: number, g: number, b: number): void;
286
+ setMetallic(v: number): void;
287
+ setRoughness(v: number): void;
288
+ setAO(v: number): void;
289
+ setEmissive(r: number, g: number, b: number): void;
290
+ setClearcoat(cc: ClearcoatConfig): void;
291
+ setAnisotropy(an: AnisotropyConfig): void;
292
+ setSheen(sh: SheenConfig): void;
293
+ setIridescence(ir: IridescenceConfig): void;
294
+ getConfig(): Readonly<AdvancedPBRConfig>;
295
+ getF0(): RGB$1;
296
+ getDiffuse(): RGB$1;
297
+ hasClearcoat(): boolean;
298
+ hasAnisotropy(): boolean;
299
+ hasSheen(): boolean;
300
+ hasIridescence(): boolean;
301
+ /**
302
+ * Evaluate the full advanced PBR BRDF at a shading point.
303
+ *
304
+ * @param NdotL - dot(N, L), clamped [0,1]
305
+ * @param NdotV - dot(N, V), clamped [0,1]
306
+ * @param NdotH - dot(N, H), clamped [0,1]
307
+ * @param VdotH - dot(V, H), clamped [0,1]
308
+ * @param TdotH - dot(T, H) for anisotropy (0 if not anisotropic)
309
+ * @param BdotH - dot(B, H) for anisotropy (0 if not anisotropic)
310
+ * @returns RGB radiance contribution (direct light, no PI factor)
311
+ */
312
+ evaluate(NdotL: number, NdotV: number, NdotH: number, VdotH: number, TdotH?: number, BdotH?: number): RGB$1;
313
+ }
314
+ /** Pre-configured material presets */
315
+ declare const MATERIAL_PRESETS$1: {
316
+ carPaintRed: () => AdvancedPBRMaterial;
317
+ brushedAluminium: () => AdvancedPBRMaterial;
318
+ velvet: () => AdvancedPBRMaterial;
319
+ soapBubble: () => AdvancedPBRMaterial;
320
+ };
321
+
322
+ /**
323
+ * AdvancedTexturing.ts
324
+ *
325
+ * Advanced texturing techniques (CPU-side):
326
+ * - Displacement mapping (tessellation height scale helpers)
327
+ * - Parallax Occlusion Mapping (iterative ray-step algorithm)
328
+ * - Triplanar mapping (normal-based blend weights + UV generation)
329
+ * - Detail maps (fine-grain albedo + normal overlay at a higher tiling)
330
+ * - Texture atlas UV packing (row-based guillotine)
331
+ *
332
+ * Works with arbitrary Float32Array textures (RGBA, row-major).
333
+ * No WebGPU / DOM — fully testable in Vitest.
334
+ *
335
+ * @module rendering
336
+ */
337
+ interface Vec2 {
338
+ x: number;
339
+ y: number;
340
+ }
341
+ interface Vec3$2 {
342
+ x: number;
343
+ y: number;
344
+ z: number;
345
+ }
346
+ /** Simple flat texture (row-major, RGBA, linear) */
347
+ interface Texture2D {
348
+ width: number;
349
+ height: number;
350
+ pixels: Float32Array;
351
+ }
352
+ /** Create a solid-colour texture */
353
+ declare function createSolidTexture(w: number, h: number, r?: number, g?: number, b?: number, a?: number): Texture2D;
354
+ /** Sample a texture at UV coordinates [0–1], clamped. Returns [R, G, B, A]. */
355
+ declare function sampleTexture(tex: Texture2D, u: number, v: number): [number, number, number, number];
356
+ /** Sample a texture with bilinear interpolation */
357
+ declare function sampleTextureBilinear(tex: Texture2D, u: number, v: number): [number, number, number, number];
358
+ interface DisplacementConfig {
359
+ /** Height scale in world units */
360
+ scale: number;
361
+ /** Bias (offset applied symmetrically around 0) */
362
+ bias: number;
363
+ }
364
+ /**
365
+ * Compute a displaced position given a surface position, normal,
366
+ * and a height map sample at the corresponding UV.
367
+ */
368
+ declare function computeDisplacedPosition(position: Vec3$2, normal: Vec3$2, heightMap: Texture2D, u: number, v: number, config?: Partial<DisplacementConfig>): Vec3$2;
369
+ /**
370
+ * Compute vertex normals for a displaced mesh via finite differences.
371
+ * heights: per-vertex height samples (row-major, same size as vertex grid).
372
+ * Returns per-vertex Vec3 normals (not normalised).
373
+ */
374
+ declare function computeDisplacementNormalsFromHeightMap(heights: Float32Array, gridW: number, gridH: number, cellSizeX: number, cellSizeZ: number): Vec3$2[];
375
+ interface POMConfig {
376
+ /** Height scale (0–1, typ. 0.05–0.15) */
377
+ heightScale: number;
378
+ /** Min ray march layers (far from surface) */
379
+ minLayers: number;
380
+ /** Max ray march layers (near surface) */
381
+ maxLayers: number;
382
+ }
383
+ /**
384
+ * Perform Parallax Occlusion Mapping to compute an offset UV.
385
+ *
386
+ * @param uv - Input surface UV
387
+ * @param viewDir - View direction in tangent space (must point away from surface)
388
+ * @param heightMap - Single-channel height map (R channel)
389
+ * @param config - POM settings
390
+ * @returns Parallax-offset UV
391
+ */
392
+ declare function computePOM(uv: Vec2, viewDir: Vec3$2, heightMap: Texture2D, config?: Partial<POMConfig>): Vec2;
393
+ /**
394
+ * Compute triplanar blend weights from a surface normal.
395
+ * Higher sharpness → sharper transitions between planes.
396
+ */
397
+ declare function triplanarWeights(normal: Vec3$2, sharpness?: number): Vec3$2;
398
+ /**
399
+ * Sample a texture using triplanar UV projection.
400
+ * position: world-space position; tileScale: how fast the texture tiles.
401
+ * Returns blended RGBA from all three planes.
402
+ */
403
+ declare function sampleTriplanar(tex: Texture2D, position: Vec3$2, normal: Vec3$2, tileScale?: number, sharpness?: number): [number, number, number, number];
404
+ interface DetailMapConfig {
405
+ /** How many times the detail map tiles over the base UV */
406
+ tileScale: number;
407
+ /** Blend intensity 0–1 */
408
+ intensity: number;
409
+ }
410
+ /** Overlay a detail albedo texture on top of a base albedo sample */
411
+ declare function applyDetailAlbedo(baseColor: [number, number, number, number], detailTex: Texture2D, u: number, v: number, config?: Partial<DetailMapConfig>): [number, number, number, number];
412
+ /**
413
+ * Blend detail normal with base normal (Reoriented Normal Mapping).
414
+ * Both normals must be unit-length, in tangent space.
415
+ */
416
+ declare function blendDetailNormal(base: Vec3$2, detail: Vec3$2): Vec3$2;
417
+ interface AtlasRect {
418
+ x: number;
419
+ y: number;
420
+ width: number;
421
+ height: number;
422
+ /** Source identifier */
423
+ id: string;
424
+ }
425
+ interface AtlasPacker {
426
+ atlasWidth: number;
427
+ atlasHeight: number;
428
+ rects: AtlasRect[];
429
+ /** Number of rows stacked */
430
+ rowCount: number;
431
+ /** Current row cursor */
432
+ cursorX: number;
433
+ cursorY: number;
434
+ rowHeight: number;
435
+ }
436
+ /** Create a new atlas packer */
437
+ declare function createAtlasPacker(width?: number, height?: number): AtlasPacker;
438
+ /**
439
+ * Pack a texture region into the atlas (row-based guillotine).
440
+ * Returns the allocated AtlasRect or null if out of space.
441
+ */
442
+ declare function packRect(packer: AtlasPacker, id: string, width: number, height: number, padding?: number): AtlasRect | null;
443
+ /** Get UV coordinates [0–1] of a packed rect within the atlas */
444
+ declare function getRectUV(packer: AtlasPacker, rect: AtlasRect): {
445
+ u0: number;
446
+ v0: number;
447
+ u1: number;
448
+ v1: number;
449
+ };
450
+ /** Total packing efficiency (used area / total area) */
451
+ declare function getAtlasEfficiency(packer: AtlasPacker): number;
452
+
453
+ /**
454
+ * CloudRenderer.ts
455
+ *
456
+ * Noise-based cloud rendering: layered cloud generation,
457
+ * wind drift, density thresholds, lighting, and coverage control.
458
+ *
459
+ * @module rendering
460
+ */
461
+ interface CloudConfig {
462
+ coverage: number;
463
+ density: number;
464
+ altitude: number;
465
+ thickness: number;
466
+ windSpeed: {
467
+ x: number;
468
+ z: number;
469
+ };
470
+ lightColor: [number, number, number];
471
+ ambientColor: [number, number, number];
472
+ lightDirection: {
473
+ x: number;
474
+ y: number;
475
+ z: number;
476
+ };
477
+ noiseScale: number;
478
+ detailScale: number;
479
+ layers: number;
480
+ }
481
+ interface CloudSample {
482
+ position: [number, number, number];
483
+ density: number;
484
+ lighting: number;
485
+ }
486
+ declare class CloudRenderer {
487
+ private config;
488
+ private time;
489
+ constructor(config?: Partial<CloudConfig>);
490
+ setConfig(config: Partial<CloudConfig>): void;
491
+ getConfig(): CloudConfig;
492
+ update(dt: number): void;
493
+ sampleDensity(x: number, y: number, z: number): number;
494
+ sampleLighting(x: number, y: number, z: number, steps?: number): CloudSample;
495
+ private pseudoNoise;
496
+ getCoverageMap(gridSize: number, cellSize: number, worldOffsetX?: number, worldOffsetZ?: number): Float32Array;
497
+ }
498
+
499
+ /**
500
+ * ColorGrading.ts
501
+ *
502
+ * Color grading: tonemapping operators, exposure, contrast,
503
+ * saturation, color temperature, LUT, and split toning.
504
+ *
505
+ * @module rendering
506
+ */
507
+ type TonemapOperator = 'none' | 'reinhard' | 'aces' | 'filmic' | 'uncharted2';
508
+ interface ColorGradingConfig {
509
+ tonemapper: TonemapOperator;
510
+ exposure: number;
511
+ contrast: number;
512
+ saturation: number;
513
+ temperature: number;
514
+ tint: number;
515
+ gamma: number;
516
+ enabled: boolean;
517
+ }
518
+ declare class ColorGrading {
519
+ private config;
520
+ setTonemapper(op: TonemapOperator): void;
521
+ setExposure(ev: number): void;
522
+ setContrast(val: number): void;
523
+ setSaturation(val: number): void;
524
+ setTemperature(val: number): void;
525
+ setTint(val: number): void;
526
+ setGamma(val: number): void;
527
+ setEnabled(val: boolean): void;
528
+ getConfig(): ColorGradingConfig;
529
+ tonemap(r: number, g: number, b: number): [number, number, number];
530
+ private tonemapACES;
531
+ private tonemapFilmic;
532
+ private tonemapUncharted2;
533
+ adjustExposure(r: number, g: number, b: number): [number, number, number];
534
+ adjustContrast(r: number, g: number, b: number): [number, number, number];
535
+ adjustSaturation(r: number, g: number, b: number): [number, number, number];
536
+ adjustGamma(r: number, g: number, b: number): [number, number, number];
537
+ apply(pixels: Float32Array, _width: number, _height: number): Float32Array;
538
+ }
539
+
540
+ /**
541
+ * DecalBatcher.ts
542
+ *
543
+ * Instanced decal rendering: GPU batching, per-texture
544
+ * grouping, LOD selection, frustum culling, and draw stats.
545
+ *
546
+ * @module rendering
547
+ */
548
+ interface DecalInstance {
549
+ id: string;
550
+ textureId: string;
551
+ position: [number, number, number];
552
+ scale: {
553
+ x: number;
554
+ y: number;
555
+ z: number;
556
+ };
557
+ rotation: {
558
+ x: number;
559
+ y: number;
560
+ z: number;
561
+ w: number;
562
+ };
563
+ opacity: number;
564
+ lodLevel: number;
565
+ }
566
+ interface DrawBatch {
567
+ textureId: string;
568
+ instances: DecalInstance[];
569
+ instanceCount: number;
570
+ }
571
+ interface BatchStats {
572
+ totalInstances: number;
573
+ totalBatches: number;
574
+ culledCount: number;
575
+ drawnCount: number;
576
+ }
577
+ declare class DecalBatcher {
578
+ private instances;
579
+ private batches;
580
+ private stats;
581
+ private maxLOD;
582
+ private lodDistances;
583
+ setLODDistances(distances: number[]): void;
584
+ getLODDistances(): number[];
585
+ addInstance(instance: DecalInstance): void;
586
+ removeInstance(id: string): boolean;
587
+ clear(): void;
588
+ getInstanceCount(): number;
589
+ computeLOD(distance: number): number;
590
+ buildBatches(cameraPos: {
591
+ x: number;
592
+ y: number;
593
+ z: number;
594
+ }, frustumTest?: (pos: DecalInstance['position']) => boolean): DrawBatch[];
595
+ getStats(): BatchStats;
596
+ }
597
+
598
+ /**
599
+ * DecalSystem.ts
600
+ *
601
+ * Projected decals: texture projection, sorting, atlas UV,
602
+ * lifetime fade, object pooling, and layer filtering.
603
+ *
604
+ * @module rendering
605
+ */
606
+ interface DecalDef {
607
+ id: string;
608
+ textureId: string;
609
+ atlasRegion?: {
610
+ u: number;
611
+ v: number;
612
+ w: number;
613
+ h: number;
614
+ };
615
+ size: {
616
+ x: number;
617
+ y: number;
618
+ z: number;
619
+ };
620
+ position: [number, number, number];
621
+ rotation: {
622
+ x: number;
623
+ y: number;
624
+ z: number;
625
+ w: number;
626
+ };
627
+ normal: {
628
+ x: number;
629
+ y: number;
630
+ z: number;
631
+ };
632
+ color: {
633
+ r: number;
634
+ g: number;
635
+ b: number;
636
+ a: number;
637
+ };
638
+ layer: number;
639
+ sortOrder: number;
640
+ lifetime: number;
641
+ fadeInDuration: number;
642
+ fadeOutDuration: number;
643
+ active: boolean;
644
+ age: number;
645
+ opacity: number;
646
+ }
647
+ declare class DecalSystem {
648
+ private decals;
649
+ private pool;
650
+ private maxDecals;
651
+ private layerMask;
652
+ setMaxDecals(max: number): void;
653
+ getMaxDecals(): number;
654
+ setLayerMask(mask: number): void;
655
+ spawn(config: Partial<DecalDef> & {
656
+ textureId: string;
657
+ position: DecalDef['position'];
658
+ normal: DecalDef['normal'];
659
+ }): DecalDef;
660
+ remove(id: string): void;
661
+ update(dt: number): void;
662
+ getDecal(id: string): DecalDef | undefined;
663
+ getActiveCount(): number;
664
+ getPoolSize(): number;
665
+ getVisible(frustumTest?: (pos: DecalDef['position']) => boolean): DecalDef[];
666
+ private getOldest;
667
+ clear(): void;
668
+ }
669
+
670
+ /**
671
+ * FogSystem.ts
672
+ *
673
+ * Fog: linear, exponential, exponential-squared, and height fog.
674
+ * Supports color blending, density maps, and animation.
675
+ *
676
+ * @module rendering
677
+ */
678
+ type FogMode = 'linear' | 'exponential' | 'exponential2';
679
+ interface FogConfig {
680
+ mode: FogMode;
681
+ color: [number, number, number];
682
+ nearDistance: number;
683
+ farDistance: number;
684
+ density: number;
685
+ heightFog: boolean;
686
+ heightStart: number;
687
+ heightEnd: number;
688
+ heightDensity: number;
689
+ enabled: boolean;
690
+ }
691
+ declare class FogSystem {
692
+ private config;
693
+ private animation;
694
+ constructor(config?: Partial<FogConfig>);
695
+ setConfig(config: Partial<FogConfig>): void;
696
+ getConfig(): FogConfig;
697
+ setEnabled(enabled: boolean): void;
698
+ isEnabled(): boolean;
699
+ computeFogFactor(distance: number, height?: number): number;
700
+ private computeHeightFactor;
701
+ blendWithFog(sceneColor: [number, number, number], distance: number, height?: number): [number, number, number];
702
+ setAnimation(speed: number): void;
703
+ update(dt: number): void;
704
+ }
705
+
706
+ /**
707
+ * GlobalIllumination.ts
708
+ *
709
+ * Global Illumination system:
710
+ * - Spherical Harmonic (SH, L2 9-coefficient) light probe encoding/decoding
711
+ * - SH irradiance grid (3D probe array)
712
+ * - Irradiance probe sampling and trilinear interpolation
713
+ * - DDGI-style probe validity tracking
714
+ * - Lightmap UV unwrapping placeholder (atlas packing)
715
+ * - Bounce count / GI mode configuration
716
+ *
717
+ * CPU-side — does not depend on WebGPU. Probe lighting values are
718
+ * expected to come from an offline bake or iterative runtime update.
719
+ *
720
+ * @module rendering
721
+ */
722
+ type Vec3$1 = {
723
+ x: number;
724
+ y: number;
725
+ z: number;
726
+ };
727
+ /** L2 spherical harmonics — 9 coefficients per RGB channel */
728
+ interface SH9 {
729
+ r: Float32Array;
730
+ g: Float32Array;
731
+ b: Float32Array;
732
+ }
733
+ type GIMode = 'lightmaps' | 'probes' | 'ddgi' | 'ssgi' | 'none';
734
+ interface GIConfig {
735
+ mode: GIMode;
736
+ /** World-space distance between adjacent probes */
737
+ probeSpacing: number;
738
+ /** Number of indirect light bounces to simulate */
739
+ bounceCount: number;
740
+ /** Grid dimensions [x, y, z] */
741
+ gridSize: [number, number, number];
742
+ /** World-space origin of the probe grid */
743
+ gridOrigin: Vec3$1;
744
+ }
745
+ /** Create an empty SH9 (all zeroes) */
746
+ declare function createSH9(): SH9;
747
+ /**
748
+ * Add a directional radiance sample to an SH9 accumulator.
749
+ * dir must be a unit vector (azimuth encoded across hemisphere).
750
+ */
751
+ declare function addSHSample(sh: SH9, dir: Vec3$1, radiance: [number, number, number], weight?: number): void;
752
+ /**
753
+ * Evaluate SH9 irradiance at a surface normal (Ravi Ramamoorthi, 2001).
754
+ * Returns RGB irradiance.
755
+ */
756
+ declare function evalSH9Irradiance(sh: SH9, normal: Vec3$1): [number, number, number];
757
+ /** Scale all SH coefficients by a scalar (e.g. to normalise after sample accumulation) */
758
+ declare function scaleSH9(sh: SH9, s: number): void;
759
+ /** Linearly interpolate between two SH9 probes (for trilinear grid lookup) */
760
+ declare function lerpSH9(a: SH9, b: SH9, t: number): SH9;
761
+ interface ProbeInfo {
762
+ index: number;
763
+ worldPos: Vec3$1;
764
+ sh: SH9;
765
+ /** 0 = invalid (occlusion issue), 1 = valid */
766
+ validity: number;
767
+ /** Number of times this probe has been updated */
768
+ updateCount: number;
769
+ }
770
+ declare class GIProbeGrid {
771
+ private probes;
772
+ private config;
773
+ constructor(config?: Partial<GIConfig>);
774
+ private buildGrid;
775
+ getProbeCount(): number;
776
+ getConfig(): Readonly<GIConfig>;
777
+ getProbe(x: number, y: number, z: number): ProbeInfo | undefined;
778
+ getProbeAt(index: number): ProbeInfo | undefined;
779
+ updateProbe(x: number, y: number, z: number, sh: SH9): void;
780
+ setValidity(x: number, y: number, z: number, valid: number): void;
781
+ invalidateAll(): void;
782
+ /** Number of valid probes (validity > 0) */
783
+ getValidProbeCount(): number;
784
+ /**
785
+ * Sample irradiance at a world-space position + surface normal.
786
+ * Performs trilinear interpolation across the 8 surrounding probes.
787
+ */
788
+ sampleIrradiance(worldPos: Vec3$1, normal: Vec3$1): [number, number, number];
789
+ /**
790
+ * Return lightmap UV (atlas page + offset) for a given probe index.
791
+ * Probes are packed in a square atlas, 16 per row.
792
+ */
793
+ getLightmapUV(probeIndex: number): {
794
+ page: number;
795
+ u: number;
796
+ v: number;
797
+ };
798
+ }
799
+
800
+ /**
801
+ * LightingModel.ts
802
+ *
803
+ * Lighting: directional/point/spot lights, shadow maps,
804
+ * ambient/IBL, GI probes, and light culling.
805
+ *
806
+ * @module rendering
807
+ */
808
+ type LightType = 'directional' | 'point' | 'spot';
809
+ interface Light {
810
+ id: string;
811
+ type: LightType;
812
+ color: [number, number, number];
813
+ intensity: number;
814
+ position: [number, number, number];
815
+ direction: {
816
+ x: number;
817
+ y: number;
818
+ z: number;
819
+ };
820
+ range: number;
821
+ spotAngle: number;
822
+ spotPenumbra: number;
823
+ castShadow: boolean;
824
+ shadowBias: number;
825
+ shadowMapSize: number;
826
+ enabled: boolean;
827
+ layer: number;
828
+ }
829
+ interface AmbientConfig {
830
+ color: [number, number, number];
831
+ intensity: number;
832
+ skyColor: [number, number, number];
833
+ groundColor: [number, number, number];
834
+ useHemisphere: boolean;
835
+ }
836
+ interface GIProbe {
837
+ id: string;
838
+ position: [number, number, number];
839
+ radius: number;
840
+ irradiance: [number, number, number];
841
+ weight: number;
842
+ }
843
+ declare class LightingModel {
844
+ private lights;
845
+ private ambient;
846
+ private probes;
847
+ private maxLights;
848
+ addLight(config: Partial<Light> & {
849
+ id: string;
850
+ type: LightType;
851
+ }): Light;
852
+ removeLight(id: string): void;
853
+ getLight(id: string): Light | undefined;
854
+ getLightCount(): number;
855
+ enableLight(id: string, enabled: boolean): void;
856
+ setAmbient(config: Partial<AmbientConfig>): void;
857
+ getAmbient(): AmbientConfig;
858
+ addGIProbe(probe: GIProbe): void;
859
+ removeGIProbe(id: string): void;
860
+ sampleGI(position: [number, number, number]): [number, number, number];
861
+ calculateAttenuation(lightId: string, worldPos: {
862
+ x: number;
863
+ y: number;
864
+ z: number;
865
+ }): number;
866
+ getVisibleLights(cameraPos: {
867
+ x: number;
868
+ y: number;
869
+ z: number;
870
+ }, maxRange: number, layerMask?: number): Light[];
871
+ getShadowCasters(): Light[];
872
+ }
873
+
874
+ /**
875
+ * MaterialLibrary.ts
876
+ *
877
+ * PBR material system: material definitions, texture slots,
878
+ * instancing, and preset materials.
879
+ *
880
+ * @module rendering
881
+ */
882
+ type BlendMode$2 = 'opaque' | 'transparent' | 'additive' | 'multiply';
883
+ type CullMode$1 = 'none' | 'front' | 'back';
884
+ /**
885
+ * Material type classification for UI and editor workflows.
886
+ * Maps to high-level rendering strategies.
887
+ */
888
+ type MaterialType = 'standard' | 'physical' | 'basic' | 'emissive' | 'toon' | 'glass' | 'metal';
889
+ interface TextureSlot {
890
+ textureId: string;
891
+ uvChannel: number;
892
+ tiling: {
893
+ x: number;
894
+ y: number;
895
+ };
896
+ offset: {
897
+ x: number;
898
+ y: number;
899
+ };
900
+ }
901
+ /**
902
+ * Unified PBR material definition.
903
+ *
904
+ * This is the single canonical material type used across all HoloScript
905
+ * subsystems: the rendering MaterialLibrary, the MaterialEditor tool,
906
+ * shader graphs, and export compilers.
907
+ *
908
+ * Color values use linear RGBA objects (not hex strings) for precision
909
+ * and compatibility with GPU pipelines.
910
+ */
911
+ interface MaterialDef {
912
+ id: string;
913
+ name: string;
914
+ /** High-level material classification for editor UI (default: 'standard') */
915
+ materialType?: MaterialType;
916
+ albedo: {
917
+ r: number;
918
+ g: number;
919
+ b: number;
920
+ a: number;
921
+ };
922
+ metallic: number;
923
+ roughness: number;
924
+ emission: {
925
+ r: number;
926
+ g: number;
927
+ b: number;
928
+ };
929
+ emissionStrength: number;
930
+ normalScale: number;
931
+ aoStrength: number;
932
+ albedoMap?: TextureSlot;
933
+ normalMap?: TextureSlot;
934
+ metallicRoughnessMap?: TextureSlot;
935
+ emissionMap?: TextureSlot;
936
+ aoMap?: TextureSlot;
937
+ blendMode: BlendMode$2;
938
+ cullMode: CullMode$1;
939
+ depthWrite: boolean;
940
+ depthTest: boolean;
941
+ doubleSided: boolean;
942
+ shaderGraphId?: string;
943
+ customUniforms?: Record<string, number | number[]>;
944
+ /** Arbitrary extension properties for editor/plugin use */
945
+ properties?: Record<string, unknown>;
946
+ }
947
+ /**
948
+ * Convert a hex color string (#RRGGBB or #RRGGBBAA) to an RGBA object
949
+ * with linear color values (0-1).
950
+ */
951
+ declare function hexToRGBA(hex: string): {
952
+ r: number;
953
+ g: number;
954
+ b: number;
955
+ a: number;
956
+ };
957
+ /**
958
+ * Convert an RGBA object (0-1 values) to a hex color string (#RRGGBB).
959
+ */
960
+ declare function rgbaToHex(color: {
961
+ r: number;
962
+ g: number;
963
+ b: number;
964
+ a?: number;
965
+ }): string;
966
+ /**
967
+ * Create a default MaterialDef with sensible PBR defaults.
968
+ * Useful for editors and tools that need a starting point.
969
+ */
970
+ declare function createDefaultMaterialDef(id: string, name?: string, materialType?: MaterialType): MaterialDef;
971
+ interface MaterialInstance {
972
+ id: string;
973
+ baseMaterialId: string;
974
+ overrides: Partial<MaterialDef>;
975
+ }
976
+ declare const MATERIAL_PRESETS: Record<string, Partial<MaterialDef>>;
977
+ declare class MaterialLibrary {
978
+ private materials;
979
+ private instances;
980
+ constructor();
981
+ register(material: MaterialDef): void;
982
+ registerPreset(presetName: string, id?: string): MaterialDef | null;
983
+ unregister(id: string): void;
984
+ getMaterial(id: string): MaterialDef | undefined;
985
+ getMaterialCount(): number;
986
+ getAllMaterials(): MaterialDef[];
987
+ createInstance(baseMaterialId: string, overrides?: Partial<MaterialDef>): MaterialInstance | null;
988
+ /**
989
+ * Resolve an instance to its full material definition.
990
+ */
991
+ resolveInstance(instanceId: string): MaterialDef | null;
992
+ getInstance(id: string): MaterialInstance | undefined;
993
+ getInstanceCount(): number;
994
+ setTexture(materialId: string, slot: keyof Pick<MaterialDef, 'albedoMap' | 'normalMap' | 'metallicRoughnessMap' | 'emissionMap' | 'aoMap'>, textureId: string): boolean;
995
+ }
996
+
997
+ /**
998
+ * MaterialSystem.ts
999
+ *
1000
+ * PBR material management: shader binding, uniform management,
1001
+ * render state, and instanced variants.
1002
+ *
1003
+ * @module rendering
1004
+ */
1005
+ type BlendMode$1 = 'opaque' | 'alpha' | 'additive' | 'multiply';
1006
+ type CullMode = 'none' | 'front' | 'back';
1007
+ type UniformType = 'float' | 'vec2' | 'vec3' | 'vec4' | 'mat4' | 'int' | 'sampler2D';
1008
+ interface UniformDef {
1009
+ name: string;
1010
+ type: UniformType;
1011
+ value: number | number[] | string;
1012
+ }
1013
+ interface Material {
1014
+ id: string;
1015
+ name: string;
1016
+ shaderId: string;
1017
+ uniforms: Map<string, UniformDef>;
1018
+ blendMode: BlendMode$1;
1019
+ cullMode: CullMode;
1020
+ depthWrite: boolean;
1021
+ depthTest: boolean;
1022
+ renderOrder: number;
1023
+ doubleSided: boolean;
1024
+ albedo: [number, number, number, number];
1025
+ metallic: number;
1026
+ roughness: number;
1027
+ emissive: [number, number, number];
1028
+ normalScale: number;
1029
+ }
1030
+ declare class MaterialSystem {
1031
+ private materials;
1032
+ private shaders;
1033
+ registerShader(id: string, vertexSrc: string, fragmentSrc: string): void;
1034
+ getShader(id: string): {
1035
+ vertexSrc: string;
1036
+ fragmentSrc: string;
1037
+ } | undefined;
1038
+ createMaterial(id: string, name: string, shaderId: string): Material;
1039
+ getMaterial(id: string): Material | undefined;
1040
+ removeMaterial(id: string): void;
1041
+ getMaterialCount(): number;
1042
+ setUniform(materialId: string, name: string, type: UniformType, value: number | number[] | string): void;
1043
+ getUniform(materialId: string, name: string): UniformDef | undefined;
1044
+ setPBR(materialId: string, props: Partial<Pick<Material, 'albedo' | 'metallic' | 'roughness' | 'emissive' | 'normalScale'>>): void;
1045
+ setBlendMode(materialId: string, mode: BlendMode$1): void;
1046
+ setCullMode(materialId: string, mode: CullMode): void;
1047
+ getSortedMaterials(): Material[];
1048
+ cloneMaterial(sourceId: string, newId: string, newName: string): Material | null;
1049
+ }
1050
+
1051
+ /**
1052
+ * PostProcessing.ts
1053
+ *
1054
+ * Post-processing effect stack: bloom, tone mapping, SSAO,
1055
+ * color grading, vignette, and chromatic aberration.
1056
+ *
1057
+ * @module rendering
1058
+ */
1059
+ type ToneMapper = 'linear' | 'reinhard' | 'aces' | 'filmic';
1060
+ interface BloomSettings {
1061
+ enabled: boolean;
1062
+ threshold: number;
1063
+ intensity: number;
1064
+ radius: number;
1065
+ softKnee: number;
1066
+ }
1067
+ interface SSAOSettings {
1068
+ enabled: boolean;
1069
+ radius: number;
1070
+ intensity: number;
1071
+ bias: number;
1072
+ samples: number;
1073
+ }
1074
+ interface ColorGradingSettings {
1075
+ enabled: boolean;
1076
+ temperature: number;
1077
+ tint: number;
1078
+ saturation: number;
1079
+ contrast: number;
1080
+ brightness: number;
1081
+ gamma: number;
1082
+ }
1083
+ interface VignetteSettings {
1084
+ enabled: boolean;
1085
+ intensity: number;
1086
+ smoothness: number;
1087
+ roundness: number;
1088
+ }
1089
+ interface ChromaticAberrationSettings {
1090
+ enabled: boolean;
1091
+ intensity: number;
1092
+ }
1093
+ interface PostProcessProfile {
1094
+ id: string;
1095
+ name: string;
1096
+ bloom: BloomSettings;
1097
+ ssao: SSAOSettings;
1098
+ colorGrading: ColorGradingSettings;
1099
+ vignette: VignetteSettings;
1100
+ chromaticAberration: ChromaticAberrationSettings;
1101
+ toneMapping: ToneMapper;
1102
+ exposure: number;
1103
+ antiAliasing: 'none' | 'fxaa' | 'smaa';
1104
+ }
1105
+ declare const PP_PRESETS: Record<string, Partial<PostProcessProfile>>;
1106
+ declare class PostProcessingStack {
1107
+ private profiles;
1108
+ private activeProfileId;
1109
+ constructor();
1110
+ createProfile(id: string, name: string): PostProcessProfile;
1111
+ loadPreset(presetName: string, id?: string): PostProcessProfile | null;
1112
+ getProfile(id: string): PostProcessProfile | undefined;
1113
+ getProfileCount(): number;
1114
+ removeProfile(id: string): boolean;
1115
+ setActive(profileId: string): boolean;
1116
+ getActive(): PostProcessProfile | null;
1117
+ setEffectEnabled(profileId: string, effect: 'bloom' | 'ssao' | 'colorGrading' | 'vignette' | 'chromaticAberration', enabled: boolean): boolean;
1118
+ /**
1119
+ * Blend between two profiles by factor t (0 = from, 1 = to).
1120
+ * Useful for smooth transitions between environments.
1121
+ */
1122
+ blendProfiles(fromId: string, toId: string, t: number): PostProcessProfile | null;
1123
+ }
1124
+
1125
+ /**
1126
+ * PostProcessStack.ts
1127
+ *
1128
+ * Ordered post-processing effect chain: add/remove effects,
1129
+ * enable/disable, priority ordering, and blend weights.
1130
+ *
1131
+ * @module rendering
1132
+ */
1133
+ interface PostProcessEffect$1 {
1134
+ id: string;
1135
+ name: string;
1136
+ priority: number;
1137
+ enabled: boolean;
1138
+ weight: number;
1139
+ params: Map<string, number>;
1140
+ process: (input: Float32Array, width: number, height: number) => Float32Array;
1141
+ }
1142
+ declare class PostProcessStack {
1143
+ private effects;
1144
+ private sortedCache;
1145
+ private dirty;
1146
+ private enabled;
1147
+ addEffect(name: string, priority: number, process: PostProcessEffect$1['process'], params?: Record<string, number>): PostProcessEffect$1;
1148
+ removeEffect(id: string): boolean;
1149
+ setEnabled(id: string, enabled: boolean): void;
1150
+ setGlobalEnabled(enabled: boolean): void;
1151
+ isGlobalEnabled(): boolean;
1152
+ setWeight(id: string, weight: number): void;
1153
+ process(input: Float32Array, width: number, height: number): Float32Array;
1154
+ private getSorted;
1155
+ reorder(id: string, newPriority: number): void;
1156
+ getEffect(id: string): PostProcessEffect$1 | undefined;
1157
+ getEffectCount(): number;
1158
+ getActiveCount(): number;
1159
+ getEffectNames(): string[];
1160
+ setParam(id: string, param: string, value: number): void;
1161
+ getParam(id: string, param: string): number | undefined;
1162
+ }
1163
+
1164
+ /**
1165
+ * ProjectorLight.ts
1166
+ *
1167
+ * Cookie projection: frustum-shaped light that projects
1168
+ * a texture pattern onto surfaces. Supports intensity,
1169
+ * falloff, and color.
1170
+ *
1171
+ * @module rendering
1172
+ */
1173
+ interface ProjectorConfig {
1174
+ id: string;
1175
+ position: [number, number, number];
1176
+ direction: {
1177
+ x: number;
1178
+ y: number;
1179
+ z: number;
1180
+ };
1181
+ cookieTextureId: string;
1182
+ fov: number;
1183
+ aspectRatio: number;
1184
+ nearClip: number;
1185
+ farClip: number;
1186
+ intensity: number;
1187
+ color: {
1188
+ r: number;
1189
+ g: number;
1190
+ b: number;
1191
+ };
1192
+ falloff: 'none' | 'linear' | 'quadratic';
1193
+ enabled: boolean;
1194
+ }
1195
+ declare class ProjectorLight {
1196
+ private projectors;
1197
+ create(config: Omit<ProjectorConfig, 'id'> & {
1198
+ id?: string;
1199
+ }): ProjectorConfig;
1200
+ remove(id: string): boolean;
1201
+ get(id: string): ProjectorConfig | undefined;
1202
+ getCount(): number;
1203
+ setPosition(id: string, x: number, y: number, z: number): void;
1204
+ setDirection(id: string, x: number, y: number, z: number): void;
1205
+ setIntensity(id: string, intensity: number): void;
1206
+ setColor(id: string, r: number, g: number, b: number): void;
1207
+ setEnabled(id: string, enabled: boolean): void;
1208
+ getFrustumPlanes(id: string): {
1209
+ near: number;
1210
+ far: number;
1211
+ fov: number;
1212
+ aspect: number;
1213
+ } | null;
1214
+ isPointInFrustum(id: string, point: {
1215
+ x: number;
1216
+ y: number;
1217
+ z: number;
1218
+ }): boolean;
1219
+ computeAttenuation(id: string, distance: number): number;
1220
+ getActive(): ProjectorConfig[];
1221
+ }
1222
+
1223
+ /**
1224
+ * RenderPass.ts
1225
+ *
1226
+ * Render pass pipeline: ordering, dependencies, framebuffer
1227
+ * attachments, clear ops, and compositing.
1228
+ *
1229
+ * @module rendering
1230
+ */
1231
+ type AttachmentFormat = 'rgba8' | 'rgba16f' | 'rgba32f' | 'depth24' | 'depth32f' | 'stencil8';
1232
+ type ClearOp = 'clear' | 'load' | 'discard';
1233
+ interface FramebufferAttachment {
1234
+ name: string;
1235
+ format: AttachmentFormat;
1236
+ width: number;
1237
+ height: number;
1238
+ clearOp: ClearOp;
1239
+ clearColor?: [number, number, number, number];
1240
+ }
1241
+ interface RenderPassConfig {
1242
+ id: string;
1243
+ name: string;
1244
+ order: number;
1245
+ enabled: boolean;
1246
+ dependencies: string[];
1247
+ attachments: FramebufferAttachment[];
1248
+ inputs: string[];
1249
+ viewport?: {
1250
+ x: number;
1251
+ y: number;
1252
+ w: number;
1253
+ h: number;
1254
+ };
1255
+ }
1256
+ declare class RenderPass {
1257
+ private passes;
1258
+ private sortedOrder;
1259
+ addPass(config: RenderPassConfig): void;
1260
+ removePass(id: string): void;
1261
+ getPass(id: string): RenderPassConfig | undefined;
1262
+ enablePass(id: string, enabled: boolean): void;
1263
+ private rebuildOrder;
1264
+ getExecutionOrder(): RenderPassConfig[];
1265
+ validate(): string[];
1266
+ private hasCycle;
1267
+ getPassCount(): number;
1268
+ getAllPasses(): RenderPassConfig[];
1269
+ }
1270
+
1271
+ /**
1272
+ * RenderGraph.ts
1273
+ *
1274
+ * Declarative render graph: defines passes (shadow, depth-prepass, G-buffer,
1275
+ * lighting, post-process), their texture inputs/outputs, and execution order.
1276
+ * The graph is topologically sorted before execution.
1277
+ *
1278
+ * @module render
1279
+ */
1280
+
1281
+ type TextureFormat = 'rgba8unorm' | 'rgba16float' | 'depth24plus' | 'depth32float' | 'r32float' | 'rg16float';
1282
+ interface RenderTarget {
1283
+ id: string;
1284
+ width: number;
1285
+ height: number;
1286
+ format: TextureFormat;
1287
+ mipLevels?: number;
1288
+ }
1289
+ interface RenderPassDescriptor {
1290
+ /** Unique pass name. */
1291
+ id: string;
1292
+ /** Textures this pass reads from. */
1293
+ inputs: string[];
1294
+ /** Textures this pass writes to. */
1295
+ outputs: string[];
1296
+ /** Clear color (null = don't clear). */
1297
+ clearColor?: {
1298
+ r: number;
1299
+ g: number;
1300
+ b: number;
1301
+ a: number;
1302
+ } | null;
1303
+ /** Whether this pass writes to the backbuffer. */
1304
+ presentToScreen?: boolean;
1305
+ /** Execute callback — receives pass context. */
1306
+ execute: (ctx: PassContext) => void;
1307
+ /** Priority hint for ordering (lower = earlier when no dependency). */
1308
+ priority?: number;
1309
+ /** Tags for filtering (e.g., 'shadow', 'transparent', 'post'). */
1310
+ tags?: string[];
1311
+ /** Is this pass enabled? */
1312
+ enabled?: boolean;
1313
+ }
1314
+ interface PassContext {
1315
+ passId: string;
1316
+ inputs: Map<string, RenderTarget>;
1317
+ outputs: Map<string, RenderTarget>;
1318
+ frameNumber: number;
1319
+ deltaTime: number;
1320
+ width: number;
1321
+ height: number;
1322
+ }
1323
+ interface GraphStats {
1324
+ passCount: number;
1325
+ targetCount: number;
1326
+ executionOrderMs: number;
1327
+ passTimings: Map<string, number>;
1328
+ }
1329
+ declare class RenderGraph implements EngineSystem {
1330
+ readonly name = "RenderGraph";
1331
+ readonly priority = 900;
1332
+ private passes;
1333
+ private targets;
1334
+ private executionOrder;
1335
+ private dirty;
1336
+ private frameNumber;
1337
+ private width;
1338
+ private height;
1339
+ private stats;
1340
+ setResolution(width: number, height: number): void;
1341
+ addTarget(target: RenderTarget): this;
1342
+ removeTarget(id: string): boolean;
1343
+ getTarget(id: string): RenderTarget | undefined;
1344
+ addPass(pass: RenderPassDescriptor): this;
1345
+ removePass(id: string): boolean;
1346
+ enablePass(id: string, enabled: boolean): void;
1347
+ getPass(id: string): RenderPassDescriptor | undefined;
1348
+ getPassesByTag(tag: string): RenderPassDescriptor[];
1349
+ private compile;
1350
+ lateUpdate(dt: number): void;
1351
+ getExecutionOrder(): string[];
1352
+ getStats(): GraphStats;
1353
+ /**
1354
+ * Set up a standard forward+ rendering pipeline:
1355
+ * shadow → depth-prepass → main-color → post-process → present
1356
+ */
1357
+ setupForwardPipeline(): this;
1358
+ destroy(): void;
1359
+ }
1360
+
1361
+ /**
1362
+ * RayTracing.ts
1363
+ *
1364
+ * CPU-side software ray tracing engine:
1365
+ * - Axis-Aligned Bounding Box (AABB) representation
1366
+ * - BVH (Bounding Volume Hierarchy) construction with SAH splits
1367
+ * - Ray-AABB intersection (slab method)
1368
+ * - Ray-triangle intersection (Möller–Trumbore)
1369
+ * - Simple path tracer loop (configurable bounces, Russian roulette)
1370
+ * - Non-Local Means (NLM) bilateral denoising filter
1371
+ * - RayTracingConfig descriptor (rt_api, features, spp, max_bounces)
1372
+ *
1373
+ * Fully CPU / TypeScript — testable without GPU.
1374
+ * Production GPU backends (DXR, OptiX, WebGPU RT extension) would
1375
+ * use these structures to generate shader pipelines.
1376
+ *
1377
+ * @module rendering
1378
+ */
1379
+ type Vec3 = {
1380
+ x: number;
1381
+ y: number;
1382
+ z: number;
1383
+ };
1384
+ type RTApi = 'dxr' | 'optix' | 'metal_rt' | 'vulkan_rt' | 'software';
1385
+ type RTFeature = 'reflections' | 'shadows' | 'ao' | 'gi';
1386
+ interface RayTracingConfig {
1387
+ rt_api: RTApi;
1388
+ features: RTFeature[];
1389
+ /** Samples per pixel */
1390
+ spp: number;
1391
+ /** Max path tracing bounces */
1392
+ max_bounces: number;
1393
+ denoising: 'nlm' | 'none';
1394
+ }
1395
+ interface AABB {
1396
+ min: Vec3;
1397
+ max: Vec3;
1398
+ }
1399
+ interface Triangle {
1400
+ v0: Vec3;
1401
+ v1: Vec3;
1402
+ v2: Vec3;
1403
+ /** Pre-computed normal (optional, computed on demand) */
1404
+ normal?: Vec3;
1405
+ }
1406
+ interface Ray {
1407
+ origin: Vec3;
1408
+ direction: Vec3;
1409
+ tMin: number;
1410
+ tMax: number;
1411
+ }
1412
+ interface HitRecord {
1413
+ t: number;
1414
+ point: Vec3;
1415
+ normal: Vec3;
1416
+ triangleIndex: number;
1417
+ }
1418
+ declare function computeTriangleNormal(tri: Triangle): Vec3;
1419
+ declare function computeAABB(triangles: Triangle[], start: number, end: number): AABB;
1420
+ declare function aabbSurfaceArea(box: AABB): number;
1421
+ declare function aabbCentroid(box: AABB): Vec3;
1422
+ /**
1423
+ * Ray–AABB intersection (slab method).
1424
+ * Returns t of intersection or -1 if miss.
1425
+ */
1426
+ declare function intersectRayAABB(ray: Ray, box: AABB): number;
1427
+ /**
1428
+ * Ray–triangle intersection (Möller–Trumbore).
1429
+ * Returns t of intersection or -1 if miss / back-face.
1430
+ */
1431
+ declare function intersectRayTriangle(ray: Ray, tri: Triangle): number;
1432
+ interface BVHNode {
1433
+ bound: AABB;
1434
+ leftChild: number;
1435
+ rightChild: number;
1436
+ triStart: number;
1437
+ triCount: number;
1438
+ }
1439
+ declare class BVH {
1440
+ nodes: BVHNode[];
1441
+ tris: Triangle[];
1442
+ /** Build from an array of triangles using SAH binned splits */
1443
+ build(triangles: Triangle[]): void;
1444
+ getNodeCount(): number;
1445
+ getLeafCount(): number;
1446
+ private buildRecursive;
1447
+ /**
1448
+ * Traverse BVH to find nearest hit for a ray.
1449
+ */
1450
+ intersect(ray: Ray): HitRecord | null;
1451
+ }
1452
+ interface PathTracerScene {
1453
+ bvh: BVH;
1454
+ /** Ambient (sky) radiance (RGB) for misses */
1455
+ skyColor: [number, number, number];
1456
+ /** Light positions for shadow rays */
1457
+ lights: Array<{
1458
+ position: Vec3;
1459
+ color: [number, number, number];
1460
+ intensity: number;
1461
+ }>;
1462
+ }
1463
+ /**
1464
+ * Path-trace a single ray for up to maxBounces bounces.
1465
+ * Returns linear RGB radiance estimate.
1466
+ */
1467
+ declare function pathTrace(ray: Ray, scene: PathTracerScene, maxBounces: number, seed: number): [number, number, number];
1468
+ interface NLMConfig {
1469
+ /** Search window half-size in pixels */
1470
+ searchRadius: number;
1471
+ /** Patch half-size */
1472
+ patchRadius: number;
1473
+ /** Filter strength */
1474
+ h: number;
1475
+ }
1476
+ /**
1477
+ * Non-Local Means bilateral denoising on a Float32Array RGBA buffer.
1478
+ * Reduces noise while preserving edges.
1479
+ */
1480
+ declare function nlmDenoise(noisy: Float32Array, width: number, height: number, config?: Partial<NLMConfig>): Float32Array;
1481
+ declare class RayTracer {
1482
+ private config;
1483
+ private scene;
1484
+ constructor(config?: Partial<RayTracingConfig>);
1485
+ getConfig(): Readonly<RayTracingConfig>;
1486
+ setFeatures(features: RTFeature[]): void;
1487
+ hasFeature(f: RTFeature): boolean;
1488
+ loadScene(triangles: Triangle[], lights?: {
1489
+ position: Vec3;
1490
+ color: [number, number, number];
1491
+ intensity: number;
1492
+ }[], sky?: [number, number, number]): void;
1493
+ getBVH(): BVH;
1494
+ /** Render a single pixel with multi-sample path tracing */
1495
+ renderPixel(rayOrigin: Vec3, rayDir: Vec3, pixelX: number, pixelY: number): [number, number, number];
1496
+ }
1497
+
1498
+ /**
1499
+ * ScreenSpaceEffects.ts
1500
+ *
1501
+ * Screen-space post-processing effects (CPU simulation / offline renderer):
1502
+ * - SSAO (Scalable Ambient Obscurance — hemispherical sampling)
1503
+ * - SSR (Screen-Space Reflections — linear ray march in projection)
1504
+ * - SSGI (Screen-Space Global Illumination — short-range bounce)
1505
+ * - TAA (Temporal Anti-Aliasing — history blend with jitter)
1506
+ * - Motion Blur (velocity-buffer blur)
1507
+ * - DOF (Depth of Field — circle-of-confusion + gather)
1508
+ * - Chromatic Aberration
1509
+ * - Film Grain
1510
+ * - Vignette
1511
+ *
1512
+ * All operations work on flat Float32Array pixel buffers (RGBA, linear).
1513
+ * No WebGPU / DOM — fully testable in Vitest.
1514
+ *
1515
+ * @module rendering
1516
+ */
1517
+ type PixelBuffer = Float32Array;
1518
+ interface SSAOConfig {
1519
+ /** Number of hemisphere samples (default 16) */
1520
+ samples: number;
1521
+ /** Sampling radius in world units */
1522
+ radius: number;
1523
+ /** Depth bias to prevent self-occlusion */
1524
+ bias: number;
1525
+ /** 0–1, power curve for occlusion accumulation */
1526
+ power: number;
1527
+ }
1528
+ /**
1529
+ * Compute SSAO occlusion factor per pixel.
1530
+ * @param depth - Float32Array, R channel = linear depth (0–1)
1531
+ * @param normals - Float32Array, RGB = world-space normal XYZ
1532
+ * @returns Float32Array (R only), occlusion 0 (occluded) to 1 (clear)
1533
+ */
1534
+ declare function computeSSAO(depth: PixelBuffer, normals: PixelBuffer, width: number, height: number, config?: Partial<SSAOConfig>): Float32Array;
1535
+ interface SSRConfig {
1536
+ /** Max ray march steps */
1537
+ steps: number;
1538
+ /** Step size in screen pixels */
1539
+ stepSize: number;
1540
+ /** Max roughness threshold (rougher surfaces skip SSR) */
1541
+ maxRoughness: number;
1542
+ /** Thickness (depth tolerance) */
1543
+ thickness: number;
1544
+ }
1545
+ /**
1546
+ * Screen-space reflection mask: returns a Float32Array (0–1, R channel)
1547
+ * indicating reflection presence at each pixel, plus the reflected UV coords.
1548
+ */
1549
+ declare function computeSSR(color: PixelBuffer, depth: PixelBuffer, width: number, height: number, roughness: Float32Array, config?: Partial<SSRConfig>): {
1550
+ mask: Float32Array;
1551
+ uvs: Float32Array;
1552
+ };
1553
+ interface SSGIConfig {
1554
+ /** Sample count per pixel */
1555
+ sampleCount: number;
1556
+ /** Sampling radius in pixels */
1557
+ radius: number;
1558
+ /** Intensity multiplier */
1559
+ intensity: number;
1560
+ }
1561
+ /**
1562
+ * Very short-range GI approximation: samples nearby pixels and
1563
+ * bleeds their colour onto the current pixel (one-bounce).
1564
+ * Returns a Float32Array (RGBA) indirect irradiance buffer.
1565
+ */
1566
+ declare function computeSSGI(color: PixelBuffer, depth: PixelBuffer, width: number, height: number, config?: Partial<SSGIConfig>): PixelBuffer;
1567
+ interface TAAConfig {
1568
+ /** Feedback (history blend) factor: 0 = no history, 1 = full history */
1569
+ feedback: number;
1570
+ /** Halton jitter scale in screen pixels */
1571
+ jitterScale: number;
1572
+ }
1573
+ /** Halton sequence (base 2, base 3 for xy jitter) */
1574
+ declare function haltonJitter(frameIndex: number): [number, number];
1575
+ /**
1576
+ * Blend current frame with history buffer (TAA).
1577
+ * history is modified in-place with each call.
1578
+ */
1579
+ declare function blendTAA(current: PixelBuffer, history: PixelBuffer, width: number, height: number, config?: Partial<TAAConfig>): PixelBuffer;
1580
+ interface MotionBlurConfig {
1581
+ /** Number of blur samples */
1582
+ sampleCount: number;
1583
+ /** Max blur length in pixels */
1584
+ maxLength: number;
1585
+ }
1586
+ /**
1587
+ * Apply motion blur using a velocity buffer.
1588
+ * @param velocity - Float32Array, RG = velocity XY in pixels/frame
1589
+ */
1590
+ declare function applyMotionBlur(color: PixelBuffer, velocity: PixelBuffer, width: number, height: number, config?: Partial<MotionBlurConfig>): PixelBuffer;
1591
+ interface DOFConfig {
1592
+ /** Focal depth (0–1 normalized) */
1593
+ focalDepth: number;
1594
+ /** Focal range — depths within ±range of focalDepth are sharp */
1595
+ focalRange: number;
1596
+ /** Max CoC radius in pixels */
1597
+ maxRadiusPx: number;
1598
+ /** Sample count per pixel */
1599
+ sampleCount: number;
1600
+ }
1601
+ /** Compute Circle of Confusion radius for a given depth value */
1602
+ declare function computeCoC(depth: number, config?: Partial<DOFConfig>): number;
1603
+ /**
1604
+ * Apply DOF using a disc gather (CPU approximate bokeh).
1605
+ */
1606
+ declare function applyDOF(color: PixelBuffer, depth: PixelBuffer, width: number, height: number, config?: Partial<DOFConfig>): PixelBuffer;
1607
+ interface ChromaticAberrationConfig {
1608
+ /** Aberration offset in pixels at the screen edge */
1609
+ strength: number;
1610
+ }
1611
+ /**
1612
+ * Chromatic aberration (RGB channel offset towards edges).
1613
+ */
1614
+ declare function applyChromaticAberration(color: PixelBuffer, width: number, height: number, config?: Partial<ChromaticAberrationConfig> & {
1615
+ strength?: number;
1616
+ }): PixelBuffer;
1617
+ /**
1618
+ * Add film grain noise.
1619
+ * @param intensity 0–1, grain strength
1620
+ * @param seed Deterministic seed for repeatable grain pattern
1621
+ */
1622
+ declare function applyFilmGrain(color: PixelBuffer, width: number, height: number, intensity: number, seed?: number): PixelBuffer;
1623
+ /**
1624
+ * Apply a radial vignette (darker at corners).
1625
+ * @param strength 0–1
1626
+ * @param radius 0–1, the point where vignette begins
1627
+ */
1628
+ declare function applyVignette(color: PixelBuffer, width: number, height: number, strength: number, radius?: number): PixelBuffer;
1629
+
1630
+ /**
1631
+ * ShaderGraph.ts
1632
+ *
1633
+ * Node-based shader composition: connects material properties
1634
+ * through a DAG of shader nodes, generates uniform declarations,
1635
+ * and outputs combined shader code.
1636
+ *
1637
+ * @module rendering
1638
+ */
1639
+ type ShaderDataType = 'float' | 'vec2' | 'vec3' | 'vec4' | 'mat4' | 'sampler2D' | 'bool' | 'int';
1640
+ interface ShaderPort {
1641
+ name: string;
1642
+ type: ShaderDataType;
1643
+ defaultValue?: number | number[];
1644
+ }
1645
+ interface ShaderNodeDef {
1646
+ type: string;
1647
+ inputs: ShaderPort[];
1648
+ outputs: ShaderPort[];
1649
+ code: string;
1650
+ }
1651
+ interface ShaderPortRef {
1652
+ id: string;
1653
+ name: string;
1654
+ direction: 'in' | 'out';
1655
+ type: ShaderDataType;
1656
+ }
1657
+ interface ShaderNode {
1658
+ id: string;
1659
+ type: string;
1660
+ position: {
1661
+ x: number;
1662
+ y: number;
1663
+ };
1664
+ overrides: Record<string, number | number[]>;
1665
+ category?: string;
1666
+ inputs?: ShaderPort[];
1667
+ outputs?: ShaderPort[];
1668
+ ports?: ShaderPortRef[];
1669
+ properties?: Record<string, unknown>;
1670
+ }
1671
+ interface ShaderConnection {
1672
+ id: string;
1673
+ fromNode: string;
1674
+ fromPort: string;
1675
+ toNode: string;
1676
+ toPort: string;
1677
+ }
1678
+ interface ShaderUniform {
1679
+ name: string;
1680
+ type: ShaderDataType;
1681
+ value: number | number[];
1682
+ }
1683
+ interface CompiledShader {
1684
+ vertexCode: string;
1685
+ fragmentCode: string;
1686
+ uniforms: ShaderUniform[];
1687
+ nodeCount: number;
1688
+ connectionCount: number;
1689
+ }
1690
+ declare const SHADER_NODES: Record<string, ShaderNodeDef>;
1691
+ declare class ShaderGraph {
1692
+ readonly id: string;
1693
+ name: string;
1694
+ nodes: Map<string, ShaderNode>;
1695
+ connections: ShaderConnection[];
1696
+ version: number;
1697
+ readonly createdAt: number;
1698
+ updatedAt: number;
1699
+ private nodeDefs;
1700
+ constructor(id?: string, name?: string);
1701
+ addNode(type: string, x?: number, y?: number, overrides?: Record<string, number | number[]>): ShaderNode | null;
1702
+ createNode(type: string, position: {
1703
+ x: number;
1704
+ y: number;
1705
+ }): ShaderNode | null;
1706
+ /** Add a pre-built ShaderNode directly (used by undo/redo systems). */
1707
+ addCustomNode(node: ShaderNode): void;
1708
+ removeNode(id: string): boolean;
1709
+ getNode(id: string): ShaderNode | undefined;
1710
+ getNodes(): ShaderNode[];
1711
+ getNodeCount(): number;
1712
+ setNodePosition(id: string, x: number, y: number): boolean;
1713
+ setNodeProperty(id: string, key: string, value: unknown): boolean;
1714
+ getNodeProperty(id: string, key: string): unknown;
1715
+ connect(fromNode: string, fromPort: string, toNode: string, toPort: string): ShaderConnection | null;
1716
+ /** Check if adding an edge from→to would create a cycle via DFS. */
1717
+ private _wouldCreateCycle;
1718
+ disconnectPort(nodeId: string, portId: string): void;
1719
+ getConnections(): ShaderConnection[];
1720
+ getNodeConnections(nodeId: string): ShaderConnection[];
1721
+ toJSON(): {
1722
+ name: string;
1723
+ id: string;
1724
+ nodes: [string, ShaderNode][];
1725
+ connections: ShaderConnection[];
1726
+ };
1727
+ static fromJSON(json: {
1728
+ name: string;
1729
+ id?: string;
1730
+ nodes: [string, ShaderNode][];
1731
+ connections: ShaderConnection[];
1732
+ }): ShaderGraph;
1733
+ serialize(): string;
1734
+ static deserialize(str: string): ShaderGraph;
1735
+ compile(): CompiledShader;
1736
+ private generateVertexShader;
1737
+ private topoSort;
1738
+ }
1739
+
1740
+ /**
1741
+ * SubsurfaceScattering.ts
1742
+ *
1743
+ * Subsurface scattering (SSS) implementation:
1744
+ * - Burley/Christensen normalized diffusion profile
1745
+ * - Multi-channel RGB scatter radii (skin: R large, G medium, B small)
1746
+ * - Multi-layer SSS (epidermis / dermis)
1747
+ * - Thin-slab transmission approximation
1748
+ * - Thickness map sampling (Float32Array or constant)
1749
+ * - Separable SSS blur kernel (screen-space blur weights via Gaussian sum)
1750
+ * - Pre-built material profiles (skin, wax, jade, marble, leaves)
1751
+ *
1752
+ * No WebGPU — fully CPU-testable in Vitest.
1753
+ *
1754
+ * @module rendering
1755
+ */
1756
+ type RGB = [number, number, number];
1757
+ type SSSModel = 'burley' | 'christensen' | 'separable_sss';
1758
+ interface SSSLayer {
1759
+ /** Weight of this layer (0–1, sum of all layers should ≤ 1) */
1760
+ weight: number;
1761
+ /** Per-channel (R, G, B) scattering radius in world units */
1762
+ scatterRadius: RGB;
1763
+ /** Base scatter color (tint) */
1764
+ color: RGB;
1765
+ }
1766
+ interface SSSConfig {
1767
+ model: SSSModel;
1768
+ /** Diffusion radius falloff shape (1 = linear, 2 = quadratic like Burley) */
1769
+ falloffPower: number;
1770
+ /** Transmission (0 = opaque, 1 = fully transparent thin slab) */
1771
+ transmission: number;
1772
+ /** Constant thickness if no thickness map provided (0–1) */
1773
+ thickness: number;
1774
+ layers: SSSLayer[];
1775
+ }
1776
+ /**
1777
+ * Burley normalized diffusion profile: R(r) = A/r * (e^(-r/d) + e^(-r/(3d)))
1778
+ * Returns relative diffusion weight at distance r for a given mean free path d.
1779
+ *
1780
+ * Reference: Burley 2015, "Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering"
1781
+ */
1782
+ declare function burleyProfile(r: number, d: number, A?: number): number;
1783
+ /**
1784
+ * Sample Burley profile across R, G, B channels.
1785
+ * scatterRadius = mean free path per channel.
1786
+ */
1787
+ declare function burleyProfileRGB(r: number, scatterRadius: RGB): RGB;
1788
+ /**
1789
+ * Christensen–Burley profile (fitted polynomial, cheaper to evaluate).
1790
+ * From "An Approximate Reflectance Profile for Efficient Subsurface Scattering"
1791
+ *
1792
+ * R(r) = (e^(-A*r/d) + e^(-A*r/(3d))) * A / (8πd)
1793
+ */
1794
+ declare function christensenProfile(r: number, d: number, A?: number): number;
1795
+ /**
1796
+ * Gaussian sum blur weights (Jimenez 2012 Separable SSS).
1797
+ * Returns N weight-variance pairs [{ weight, variance }] per channel.
1798
+ *
1799
+ * The kernel width is controlled by scatterRadius.
1800
+ */
1801
+ declare function buildSeparableSSSKernel(scatterRadius: RGB, numGaussians?: number): Array<{
1802
+ weight: number;
1803
+ stddev: RGB;
1804
+ }>;
1805
+ /**
1806
+ * Evaluate a separable Gaussian blur at offset x (signed, in world units).
1807
+ * Returns RGB weight.
1808
+ */
1809
+ declare function evalSeparableKernel(kernel: Array<{
1810
+ weight: number;
1811
+ stddev: RGB;
1812
+ }>, x: number): RGB;
1813
+ /**
1814
+ * Thin-slab transmission amount using Beer-Lambert approximation.
1815
+ * thickness: 0 = thin (high transmission), 1 = thick (low transmission).
1816
+ * Returns transmission factor [0, 1].
1817
+ */
1818
+ declare function thinSlabTransmission(thickness: number, config: Pick<SSSConfig, 'transmission' | 'layers'>): RGB;
1819
+ declare class SSSMaterial {
1820
+ private config;
1821
+ constructor(config?: Partial<SSSConfig>);
1822
+ getConfig(): Readonly<SSSConfig>;
1823
+ setModel(model: SSSModel): void;
1824
+ setTransmission(t: number): void;
1825
+ setThickness(t: number): void;
1826
+ addLayer(layer: SSSLayer): void;
1827
+ getLayerCount(): number;
1828
+ /**
1829
+ * Evaluate SSS diffusion at a surface point for a given light exit radius.
1830
+ * r: distance between light entry and exit point on the surface.
1831
+ */
1832
+ evaluate(r: number): RGB;
1833
+ /** Evaluate thin-slab transmission at the material's configured thickness */
1834
+ getTransmission(thicknessOverride?: number): RGB;
1835
+ /** Get Separable SSS kernel for this material (first layer) */
1836
+ getKernel(numGaussians?: number): ReturnType<typeof buildSeparableSSSKernel>;
1837
+ }
1838
+ declare const SSS_PRESETS: {
1839
+ /** Human skin: epidermis (yellow tint) + dermis (red) */
1840
+ humanSkin: () => SSSMaterial;
1841
+ /** Wax candle (high SSS, warm light transmission) */
1842
+ wax: () => SSSMaterial;
1843
+ /** Jade gemstone (cool, dense SSS) */
1844
+ jade: () => SSSMaterial;
1845
+ /** Marble (dense, RGB-balanced) */
1846
+ marble: () => SSSMaterial;
1847
+ /** Leaf / plant (very thin, high transmission) */
1848
+ leaf: () => SSSMaterial;
1849
+ };
1850
+
1851
+ /**
1852
+ * VolumetricLight.ts
1853
+ *
1854
+ * Volumetric/god ray lighting: scattering computation,
1855
+ * shadow-aware shafts, intensity falloff, and ray marching.
1856
+ *
1857
+ * @module rendering
1858
+ */
1859
+ interface VolumetricLightConfig {
1860
+ id: string;
1861
+ position: [number, number, number];
1862
+ direction: {
1863
+ x: number;
1864
+ y: number;
1865
+ z: number;
1866
+ };
1867
+ color: [number, number, number];
1868
+ intensity: number;
1869
+ scattering: number;
1870
+ decay: number;
1871
+ samples: number;
1872
+ maxDistance: number;
1873
+ shadowDensity: number;
1874
+ enabled: boolean;
1875
+ }
1876
+ interface VolumetricSample {
1877
+ position: [number, number, number];
1878
+ accumulated: number;
1879
+ step: number;
1880
+ }
1881
+ declare class VolumetricLight {
1882
+ private lights;
1883
+ addLight(config: Partial<VolumetricLightConfig> & {
1884
+ id: string;
1885
+ }): VolumetricLightConfig;
1886
+ removeLight(id: string): void;
1887
+ getLight(id: string): VolumetricLightConfig | undefined;
1888
+ getLightCount(): number;
1889
+ march(lightId: string, viewPos: {
1890
+ x: number;
1891
+ y: number;
1892
+ z: number;
1893
+ }, viewDir: {
1894
+ x: number;
1895
+ y: number;
1896
+ z: number;
1897
+ }): VolumetricSample[];
1898
+ getScatteringAt(lightId: string, worldPos: {
1899
+ x: number;
1900
+ y: number;
1901
+ z: number;
1902
+ }): number;
1903
+ private normalize;
1904
+ }
1905
+
1906
+ /**
1907
+ * WebGPU Renderer Types
1908
+ *
1909
+ * Type definitions for WebGPU-based rendering system
1910
+ */
1911
+ /** WebGPU initialization options */
1912
+ interface IWebGPUInitOptions {
1913
+ /** Canvas element or selector */
1914
+ canvas: HTMLCanvasElement | string;
1915
+ /** Preferred adapter power preference */
1916
+ powerPreference?: 'low-power' | 'high-performance';
1917
+ /** Required features */
1918
+ requiredFeatures?: GPUFeatureName[];
1919
+ /** Required limits */
1920
+ requiredLimits?: Record<string, number>;
1921
+ /** Enable debug mode */
1922
+ debug?: boolean;
1923
+ /** Preferred texture format (auto-detected if not specified) */
1924
+ preferredFormat?: GPUTextureFormat;
1925
+ /** MSAA sample count */
1926
+ sampleCount?: 1 | 4;
1927
+ /** Alpha mode for canvas */
1928
+ alphaMode?: GPUCanvasAlphaMode;
1929
+ }
1930
+ /** WebGPU context after initialization */
1931
+ interface IWebGPUContext {
1932
+ /** GPU adapter */
1933
+ adapter: GPUAdapter;
1934
+ /** GPU device */
1935
+ device: GPUDevice;
1936
+ /** Canvas context */
1937
+ context: GPUCanvasContext;
1938
+ /** Preferred texture format */
1939
+ format: GPUTextureFormat;
1940
+ /** Canvas element */
1941
+ canvas: HTMLCanvasElement;
1942
+ /** Device capabilities */
1943
+ capabilities: IDeviceCapabilities;
1944
+ }
1945
+ /** Device capabilities and limits */
1946
+ interface IDeviceCapabilities {
1947
+ maxTextureDimension2D: number;
1948
+ maxTextureArrayLayers: number;
1949
+ maxBindGroups: number;
1950
+ maxBindingsPerBindGroup: number;
1951
+ maxBufferSize: number;
1952
+ maxUniformBufferBindingSize: number;
1953
+ maxStorageBufferBindingSize: number;
1954
+ maxVertexBuffers: number;
1955
+ maxVertexAttributes: number;
1956
+ maxComputeWorkgroupsPerDimension: number;
1957
+ features: Set<string>;
1958
+ }
1959
+ /** Render pipeline descriptor */
1960
+ interface IRenderPipelineDescriptor {
1961
+ /** Pipeline label for debugging */
1962
+ label?: string;
1963
+ /** Vertex shader module */
1964
+ vertexShader: IShaderModule;
1965
+ /** Fragment shader module */
1966
+ fragmentShader: IShaderModule;
1967
+ /** Vertex buffer layouts */
1968
+ vertexBufferLayouts: IVertexBufferLayout[];
1969
+ /** Primitive topology */
1970
+ topology?: GPUPrimitiveTopology;
1971
+ /** Cull mode */
1972
+ cullMode?: GPUCullMode;
1973
+ /** Front face winding */
1974
+ frontFace?: GPUFrontFace;
1975
+ /** Depth/stencil state */
1976
+ depthStencil?: IDepthStencilState;
1977
+ /** Color target states */
1978
+ colorTargets: IColorTargetState[];
1979
+ /** Bind group layouts */
1980
+ bindGroupLayouts?: GPUBindGroupLayout[];
1981
+ /** MSAA sample count */
1982
+ sampleCount?: number;
1983
+ }
1984
+ /** Shader module definition */
1985
+ interface IShaderModule {
1986
+ /** WGSL source code */
1987
+ code: string;
1988
+ /** Entry point function name */
1989
+ entryPoint: string;
1990
+ /** Shader label */
1991
+ label?: string;
1992
+ }
1993
+ /** Vertex buffer layout */
1994
+ interface IVertexBufferLayout {
1995
+ /** Stride in bytes */
1996
+ arrayStride: number;
1997
+ /** Step mode */
1998
+ stepMode?: GPUVertexStepMode;
1999
+ /** Vertex attributes */
2000
+ attributes: IVertexAttribute[];
2001
+ }
2002
+ /** Vertex attribute definition */
2003
+ interface IVertexAttribute {
2004
+ /** Attribute format */
2005
+ format: GPUVertexFormat;
2006
+ /** Byte offset */
2007
+ offset: number;
2008
+ /** Shader location */
2009
+ shaderLocation: number;
2010
+ }
2011
+ /** Depth/stencil state */
2012
+ interface IDepthStencilState {
2013
+ /** Depth texture format */
2014
+ format: GPUTextureFormat;
2015
+ /** Enable depth write */
2016
+ depthWriteEnabled: boolean;
2017
+ /** Depth comparison function */
2018
+ depthCompare: GPUCompareFunction;
2019
+ /** Stencil front face */
2020
+ stencilFront?: IStencilFaceState;
2021
+ /** Stencil back face */
2022
+ stencilBack?: IStencilFaceState;
2023
+ /** Depth bias */
2024
+ depthBias?: number;
2025
+ /** Depth bias slope scale */
2026
+ depthBiasSlopeScale?: number;
2027
+ /** Depth bias clamp */
2028
+ depthBiasClamp?: number;
2029
+ }
2030
+ /** Stencil face state */
2031
+ interface IStencilFaceState {
2032
+ compare?: GPUCompareFunction;
2033
+ failOp?: GPUStencilOperation;
2034
+ depthFailOp?: GPUStencilOperation;
2035
+ passOp?: GPUStencilOperation;
2036
+ }
2037
+ /** Color target state */
2038
+ interface IColorTargetState {
2039
+ /** Texture format */
2040
+ format: GPUTextureFormat;
2041
+ /** Blend state */
2042
+ blend?: IBlendState;
2043
+ /** Color write mask */
2044
+ writeMask?: GPUColorWriteFlags;
2045
+ }
2046
+ /** Blend state */
2047
+ interface IBlendState {
2048
+ /** Color blend component */
2049
+ color: IBlendComponent;
2050
+ /** Alpha blend component */
2051
+ alpha: IBlendComponent;
2052
+ }
2053
+ /** Blend component */
2054
+ interface IBlendComponent {
2055
+ operation?: GPUBlendOperation;
2056
+ srcFactor?: GPUBlendFactor;
2057
+ dstFactor?: GPUBlendFactor;
2058
+ }
2059
+ /** GPU buffer descriptor */
2060
+ interface IBufferDescriptor {
2061
+ /** Buffer label */
2062
+ label?: string;
2063
+ /** Size in bytes */
2064
+ size: number;
2065
+ /** Buffer usage flags */
2066
+ usage: GPUBufferUsageFlags;
2067
+ /** Map at creation */
2068
+ mappedAtCreation?: boolean;
2069
+ }
2070
+ /** Uniform buffer data */
2071
+ interface IUniformBuffer {
2072
+ /** Buffer handle */
2073
+ buffer: GPUBuffer;
2074
+ /** Current data */
2075
+ data: ArrayBuffer;
2076
+ /** Binding index */
2077
+ binding: number;
2078
+ /** Last update frame */
2079
+ lastUpdateFrame: number;
2080
+ }
2081
+ /** Vertex buffer data */
2082
+ interface IVertexBuffer {
2083
+ /** Buffer handle */
2084
+ buffer: GPUBuffer;
2085
+ /** Vertex count */
2086
+ vertexCount: number;
2087
+ /** Stride in bytes */
2088
+ stride: number;
2089
+ /** Buffer slot */
2090
+ slot: number;
2091
+ }
2092
+ /** Index buffer data */
2093
+ interface IIndexBuffer {
2094
+ /** Buffer handle */
2095
+ buffer: GPUBuffer;
2096
+ /** Index count */
2097
+ indexCount: number;
2098
+ /** Index format */
2099
+ format: GPUIndexFormat;
2100
+ }
2101
+ /** Texture descriptor */
2102
+ interface ITextureDescriptor {
2103
+ /** Texture label */
2104
+ label?: string;
2105
+ /** Width in pixels */
2106
+ width: number;
2107
+ /** Height in pixels */
2108
+ height: number;
2109
+ /** Depth or array layers */
2110
+ depthOrArrayLayers?: number;
2111
+ /** Mip level count */
2112
+ mipLevelCount?: number;
2113
+ /** Sample count */
2114
+ sampleCount?: number;
2115
+ /** Texture dimension */
2116
+ dimension?: GPUTextureDimension;
2117
+ /** Texture format */
2118
+ format: GPUTextureFormat;
2119
+ /** Texture usage */
2120
+ usage: GPUTextureUsageFlags;
2121
+ }
2122
+ /** Sampler descriptor */
2123
+ interface ISamplerDescriptor {
2124
+ /** Sampler label */
2125
+ label?: string;
2126
+ /** Address mode U */
2127
+ addressModeU?: GPUAddressMode;
2128
+ /** Address mode V */
2129
+ addressModeV?: GPUAddressMode;
2130
+ /** Address mode W */
2131
+ addressModeW?: GPUAddressMode;
2132
+ /** Mag filter */
2133
+ magFilter?: GPUFilterMode;
2134
+ /** Min filter */
2135
+ minFilter?: GPUFilterMode;
2136
+ /** Mipmap filter */
2137
+ mipmapFilter?: GPUMipmapFilterMode;
2138
+ /** LOD min clamp */
2139
+ lodMinClamp?: number;
2140
+ /** LOD max clamp */
2141
+ lodMaxClamp?: number;
2142
+ /** Compare function for shadow maps */
2143
+ compare?: GPUCompareFunction;
2144
+ /** Max anisotropy */
2145
+ maxAnisotropy?: number;
2146
+ }
2147
+ /** GPU texture with metadata */
2148
+ interface IGPUTexture {
2149
+ /** Texture handle */
2150
+ texture: GPUTexture;
2151
+ /** Default view */
2152
+ view: GPUTextureView;
2153
+ /** Sampler */
2154
+ sampler: GPUSampler;
2155
+ /** Width */
2156
+ width: number;
2157
+ /** Height */
2158
+ height: number;
2159
+ /** Format */
2160
+ format: GPUTextureFormat;
2161
+ /** Mip levels */
2162
+ mipLevels: number;
2163
+ }
2164
+ /** Render pass descriptor */
2165
+ interface IRenderPassDescriptor {
2166
+ /** Pass label */
2167
+ label?: string;
2168
+ /** Color attachments */
2169
+ colorAttachments: IRenderPassColorAttachment[];
2170
+ /** Depth/stencil attachment */
2171
+ depthStencilAttachment?: IRenderPassDepthStencilAttachment;
2172
+ /** Occlusion query set */
2173
+ occlusionQuerySet?: GPUQuerySet;
2174
+ /** Timestamp writes */
2175
+ timestampWrites?: GPURenderPassTimestampWrites;
2176
+ }
2177
+ /** Color attachment */
2178
+ interface IRenderPassColorAttachment {
2179
+ /** View to render to */
2180
+ view: GPUTextureView;
2181
+ /** Resolve target for MSAA */
2182
+ resolveTarget?: GPUTextureView;
2183
+ /** Clear value */
2184
+ clearValue?: GPUColor;
2185
+ /** Load operation */
2186
+ loadOp: GPULoadOp;
2187
+ /** Store operation */
2188
+ storeOp: GPUStoreOp;
2189
+ }
2190
+ /** Depth/stencil attachment */
2191
+ interface IRenderPassDepthStencilAttachment {
2192
+ /** Depth texture view */
2193
+ view: GPUTextureView;
2194
+ /** Depth clear value */
2195
+ depthClearValue?: number;
2196
+ /** Depth load op */
2197
+ depthLoadOp?: GPULoadOp;
2198
+ /** Depth store op */
2199
+ depthStoreOp?: GPUStoreOp;
2200
+ /** Depth read-only */
2201
+ depthReadOnly?: boolean;
2202
+ /** Stencil clear value */
2203
+ stencilClearValue?: number;
2204
+ /** Stencil load op */
2205
+ stencilLoadOp?: GPULoadOp;
2206
+ /** Stencil store op */
2207
+ stencilStoreOp?: GPUStoreOp;
2208
+ /** Stencil read-only */
2209
+ stencilReadOnly?: boolean;
2210
+ }
2211
+ /** Renderable mesh */
2212
+ interface IRenderMesh {
2213
+ /** Mesh identifier */
2214
+ id: string;
2215
+ /** Vertex buffers */
2216
+ vertexBuffers: IVertexBuffer[];
2217
+ /** Index buffer (optional) */
2218
+ indexBuffer?: IIndexBuffer;
2219
+ /** Vertex count (for non-indexed draws) */
2220
+ vertexCount: number;
2221
+ /** Instance count */
2222
+ instanceCount: number;
2223
+ /** Bounding box for culling */
2224
+ boundingBox?: IBoundingBox;
2225
+ }
2226
+ /** Bounding box for frustum culling */
2227
+ interface IBoundingBox {
2228
+ min: [number, number, number];
2229
+ max: [number, number, number];
2230
+ }
2231
+ /** Material for rendering */
2232
+ interface IRenderMaterial {
2233
+ /** Material identifier */
2234
+ id: string;
2235
+ /** Pipeline to use */
2236
+ pipelineId: string;
2237
+ /** Bind group for material uniforms */
2238
+ bindGroup: GPUBindGroup;
2239
+ /** Textures */
2240
+ textures: Map<string, IGPUTexture>;
2241
+ /** Uniform data */
2242
+ uniforms: ArrayBuffer;
2243
+ /** Transparency flag */
2244
+ transparent: boolean;
2245
+ /** Double-sided flag */
2246
+ doubleSided: boolean;
2247
+ }
2248
+ /** Draw call */
2249
+ interface IDrawCall {
2250
+ /** Mesh to draw */
2251
+ mesh: IRenderMesh;
2252
+ /** Material to use */
2253
+ material: IRenderMaterial;
2254
+ /** Model matrix */
2255
+ modelMatrix: Float32Array;
2256
+ /** Sort key for batching */
2257
+ sortKey: number;
2258
+ /** Distance from camera (for transparency sorting) */
2259
+ cameraDistance?: number;
2260
+ }
2261
+ /** Camera uniforms */
2262
+ interface ICameraUniforms {
2263
+ /** View matrix */
2264
+ viewMatrix: Float32Array;
2265
+ /** Projection matrix */
2266
+ projectionMatrix: Float32Array;
2267
+ /** View-projection matrix */
2268
+ viewProjectionMatrix: Float32Array;
2269
+ /** Inverse view matrix */
2270
+ inverseViewMatrix: Float32Array;
2271
+ /** Inverse projection matrix */
2272
+ inverseProjectionMatrix: Float32Array;
2273
+ /** Camera position */
2274
+ cameraPosition: Float32Array;
2275
+ /** Near plane */
2276
+ near: number;
2277
+ /** Far plane */
2278
+ far: number;
2279
+ /** Field of view (radians) */
2280
+ fov: number;
2281
+ /** Aspect ratio */
2282
+ aspectRatio: number;
2283
+ }
2284
+ /** Scene uniforms */
2285
+ interface ISceneUniforms {
2286
+ /** Ambient light color */
2287
+ ambientColor: Float32Array;
2288
+ /** Time since start */
2289
+ time: number;
2290
+ /** Delta time */
2291
+ deltaTime: number;
2292
+ /** Frame number */
2293
+ frameNumber: number;
2294
+ }
2295
+ /** Frame statistics */
2296
+ interface IFrameStats {
2297
+ /** Frame time in milliseconds */
2298
+ frameTime: number;
2299
+ /** GPU time in milliseconds (if available) */
2300
+ gpuTime?: number;
2301
+ /** Draw calls */
2302
+ drawCalls: number;
2303
+ /** Triangles rendered */
2304
+ triangles: number;
2305
+ /** Vertices processed */
2306
+ vertices: number;
2307
+ /** Pipeline switches */
2308
+ pipelineSwitches: number;
2309
+ /** Bind group switches */
2310
+ bindGroupSwitches: number;
2311
+ /** Buffer uploads */
2312
+ bufferUploads: number;
2313
+ /** Texture uploads */
2314
+ textureUploads: number;
2315
+ }
2316
+ /** Renderer statistics */
2317
+ interface IRendererStats {
2318
+ /** Current frame stats */
2319
+ currentFrame: IFrameStats;
2320
+ /** Rolling average stats */
2321
+ average: IFrameStats;
2322
+ /** Total frames rendered */
2323
+ totalFrames: number;
2324
+ /** FPS */
2325
+ fps: number;
2326
+ /** GPU memory usage (if available) */
2327
+ gpuMemory?: number;
2328
+ }
2329
+ /** Standard PBR vertex shader */
2330
+ declare const STANDARD_VERTEX_SHADER = "\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n}\n\nstruct CameraUniforms {\n viewProjectionMatrix: mat4x4<f32>,\n cameraPosition: vec3<f32>,\n}\n\nstruct ModelUniforms {\n modelMatrix: mat4x4<f32>,\n normalMatrix: mat3x3<f32>,\n}\n\n@group(0) @binding(0) var<uniform> camera: CameraUniforms;\n@group(1) @binding(0) var<uniform> model: ModelUniforms;\n\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let worldPos = model.modelMatrix * vec4<f32>(input.position, 1.0);\n output.position = camera.viewProjectionMatrix * worldPos;\n output.worldPosition = worldPos.xyz;\n output.worldNormal = normalize(model.normalMatrix * input.normal);\n output.uv = input.uv;\n return output;\n}\n";
2331
+ /** Standard PBR fragment shader */
2332
+ declare const STANDARD_FRAGMENT_SHADER = "\nstruct FragmentInput {\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n}\n\nstruct MaterialUniforms {\n baseColor: vec4<f32>,\n metallic: f32,\n roughness: f32,\n emissive: vec3<f32>,\n}\n\nstruct LightUniforms {\n direction: vec3<f32>,\n color: vec3<f32>,\n intensity: f32,\n}\n\n@group(0) @binding(1) var<uniform> material: MaterialUniforms;\n@group(0) @binding(2) var<uniform> light: LightUniforms;\n@group(2) @binding(0) var baseColorTexture: texture_2d<f32>;\n@group(2) @binding(1) var baseColorSampler: sampler;\n\nconst PI: f32 = 3.14159265359;\n\nfn fresnelSchlick(cosTheta: f32, F0: vec3<f32>) -> vec3<f32> {\n return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);\n}\n\nfn distributionGGX(N: vec3<f32>, H: vec3<f32>, roughness: f32) -> f32 {\n let a = roughness * roughness;\n let a2 = a * a;\n let NdotH = max(dot(N, H), 0.0);\n let NdotH2 = NdotH * NdotH;\n let nom = a2;\n var denom = (NdotH2 * (a2 - 1.0) + 1.0);\n denom = PI * denom * denom;\n return nom / denom;\n}\n\nfn geometrySchlickGGX(NdotV: f32, roughness: f32) -> f32 {\n let r = roughness + 1.0;\n let k = (r * r) / 8.0;\n let nom = NdotV;\n let denom = NdotV * (1.0 - k) + k;\n return nom / denom;\n}\n\nfn geometrySmith(N: vec3<f32>, V: vec3<f32>, L: vec3<f32>, roughness: f32) -> f32 {\n let NdotV = max(dot(N, V), 0.0);\n let NdotL = max(dot(N, L), 0.0);\n let ggx2 = geometrySchlickGGX(NdotV, roughness);\n let ggx1 = geometrySchlickGGX(NdotL, roughness);\n return ggx1 * ggx2;\n}\n\n@fragment\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\n let baseColor = textureSample(baseColorTexture, baseColorSampler, input.uv) * material.baseColor;\n let N = normalize(input.worldNormal);\n let V = normalize(-input.worldPosition);\n let L = normalize(-light.direction);\n let H = normalize(V + L);\n \n let F0 = mix(vec3<f32>(0.04), baseColor.rgb, material.metallic);\n let F = fresnelSchlick(max(dot(H, V), 0.0), F0);\n let NDF = distributionGGX(N, H, material.roughness);\n let G = geometrySmith(N, V, L, material.roughness);\n \n let numerator = NDF * G * F;\n let denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;\n let specular = numerator / denominator;\n \n let kS = F;\n let kD = (vec3<f32>(1.0) - kS) * (1.0 - material.metallic);\n let NdotL = max(dot(N, L), 0.0);\n \n let Lo = (kD * baseColor.rgb / PI + specular) * light.color * light.intensity * NdotL;\n let ambient = vec3<f32>(0.03) * baseColor.rgb;\n var color = ambient + Lo + material.emissive;\n \n // Tone mapping (Reinhard)\n color = color / (color + vec3<f32>(1.0));\n // Gamma correction\n color = pow(color, vec3<f32>(1.0 / 2.2));\n \n return vec4<f32>(color, baseColor.a);\n}\n";
2333
+ /** Unlit vertex shader */
2334
+ declare const UNLIT_VERTEX_SHADER = "\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) uv: vec2<f32>,\n @location(2) color: vec4<f32>,\n}\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n @location(1) color: vec4<f32>,\n}\n\nstruct Uniforms {\n mvpMatrix: mat4x4<f32>,\n}\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n output.position = uniforms.mvpMatrix * vec4<f32>(input.position, 1.0);\n output.uv = input.uv;\n output.color = input.color;\n return output;\n}\n";
2335
+ /** Unlit fragment shader */
2336
+ declare const UNLIT_FRAGMENT_SHADER = "\nstruct FragmentInput {\n @location(0) uv: vec2<f32>,\n @location(1) color: vec4<f32>,\n}\n\n@group(0) @binding(1) var colorTexture: texture_2d<f32>;\n@group(0) @binding(2) var colorSampler: sampler;\n\n@fragment\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\n let texColor = textureSample(colorTexture, colorSampler, input.uv);\n return texColor * input.color;\n}\n";
2337
+
2338
+ /**
2339
+ * WebGPU Renderer
2340
+ *
2341
+ * High-performance WebGPU-based renderer for HoloScript
2342
+ */
2343
+
2344
+ /**
2345
+ * WebGPU-based renderer for HoloScript scenes
2346
+ */
2347
+ declare class WebGPURenderer {
2348
+ private context;
2349
+ private pipelines;
2350
+ private shaderModules;
2351
+ private bindGroupLayouts;
2352
+ private pipelineLayouts;
2353
+ private depthTexture;
2354
+ private msaaTexture;
2355
+ private options;
2356
+ private xrSession;
2357
+ private xrBinding;
2358
+ private xrProjectionLayer;
2359
+ private xrFramebuffer;
2360
+ private stats;
2361
+ private lastFrameTime;
2362
+ private frameTimeHistory;
2363
+ private cameraUniformBuffer;
2364
+ private sceneUniformBuffer;
2365
+ private defaultSampler;
2366
+ private defaultTexture;
2367
+ constructor(options?: Partial<IWebGPUInitOptions>);
2368
+ /**
2369
+ * Check if WebGPU is supported
2370
+ */
2371
+ static isSupported(): boolean;
2372
+ /**
2373
+ * Initialize the WebGPU renderer
2374
+ */
2375
+ initialize(options?: Partial<IWebGPUInitOptions>): Promise<IWebGPUContext>;
2376
+ /**
2377
+ * Resolve canvas from element or selector
2378
+ */
2379
+ private resolveCanvas;
2380
+ /**
2381
+ * Get device capabilities
2382
+ */
2383
+ private getDeviceCapabilities;
2384
+ /**
2385
+ * Create default resources
2386
+ */
2387
+ private createDefaultResources;
2388
+ /**
2389
+ * Create depth buffer
2390
+ */
2391
+ private createDepthBuffer;
2392
+ /**
2393
+ * Handle canvas resize
2394
+ */
2395
+ resize(width: number, height: number): void;
2396
+ /**
2397
+ * Create a shader module
2398
+ */
2399
+ createShaderModule(descriptor: IShaderModule): GPUShaderModule;
2400
+ /**
2401
+ * Create a render pipeline
2402
+ */
2403
+ createRenderPipeline(id: string, descriptor: IRenderPipelineDescriptor): GPURenderPipeline;
2404
+ /**
2405
+ * Create a GPU buffer
2406
+ */
2407
+ createBuffer(descriptor: IBufferDescriptor): GPUBuffer;
2408
+ /**
2409
+ * Create a vertex buffer from typed array
2410
+ */
2411
+ createVertexBuffer(data: Float32Array | Uint16Array | Uint32Array, slot?: number): IVertexBuffer;
2412
+ /**
2413
+ * Create an index buffer
2414
+ */
2415
+ createIndexBuffer(data: Uint16Array | Uint32Array): IIndexBuffer;
2416
+ /**
2417
+ * Create a texture
2418
+ */
2419
+ createTexture(descriptor: ITextureDescriptor): GPUTexture;
2420
+ /**
2421
+ * Create a GPU texture from image data
2422
+ */
2423
+ createTextureFromImage(source: ImageBitmap | HTMLCanvasElement | OffscreenCanvas, options?: Partial<ITextureDescriptor>): Promise<IGPUTexture>;
2424
+ private mipmapPipeline;
2425
+ private mipmapSampler;
2426
+ /**
2427
+ * Get or create the mipmap blit pipeline.
2428
+ * Uses a fullscreen-quad vertex shader (no vertex buffers) and a
2429
+ * bilinear-sampling fragment shader to downsample each mip level.
2430
+ */
2431
+ private getOrCreateMipmapPipeline;
2432
+ /**
2433
+ * Generate mipmaps for a texture using a blit-style render pass.
2434
+ *
2435
+ * For each mip level (1..mipLevelCount-1) we render a fullscreen triangle
2436
+ * that samples the previous level with bilinear filtering, writing the
2437
+ * downsampled result into the current level.
2438
+ *
2439
+ * Requires the texture to have been created with RENDER_ATTACHMENT usage.
2440
+ */
2441
+ private generateMipmaps;
2442
+ /**
2443
+ * Create a sampler
2444
+ */
2445
+ createSampler(descriptor?: ISamplerDescriptor): GPUSampler;
2446
+ /**
2447
+ * Create a bind group
2448
+ */
2449
+ createBindGroup(layout: GPUBindGroupLayout, entries: GPUBindGroupEntry[], label?: string): GPUBindGroup;
2450
+ /**
2451
+ * Update camera uniforms
2452
+ */
2453
+ updateCameraUniforms(uniforms: ICameraUniforms): void;
2454
+ /**
2455
+ * Update scene uniforms
2456
+ */
2457
+ updateSceneUniforms(uniforms: ISceneUniforms): void;
2458
+ /**
2459
+ * Begin a render frame
2460
+ */
2461
+ beginFrame(): GPUCommandEncoder | null;
2462
+ /**
2463
+ * Begin a render pass
2464
+ */
2465
+ beginRenderPass(encoder: GPUCommandEncoder, clearColor?: GPUColor): GPURenderPassEncoder;
2466
+ /**
2467
+ * Submit draw calls
2468
+ */
2469
+ submitDrawCalls(pass: GPURenderPassEncoder, drawCalls: IDrawCall[]): void;
2470
+ /**
2471
+ * Sort draw calls for optimal rendering
2472
+ */
2473
+ private sortDrawCalls;
2474
+ /**
2475
+ * End render pass
2476
+ */
2477
+ endRenderPass(pass: GPURenderPassEncoder): void;
2478
+ /**
2479
+ * End frame and submit
2480
+ */
2481
+ endFrame(encoder: GPUCommandEncoder): void;
2482
+ /**
2483
+ * Get render statistics
2484
+ */
2485
+ getStats(): IRendererStats;
2486
+ /**
2487
+ * Get the WebGPU context
2488
+ */
2489
+ getContext(): IWebGPUContext | null;
2490
+ /**
2491
+ * Get the GPU device
2492
+ */
2493
+ getDevice(): GPUDevice | null;
2494
+ /**
2495
+ * Get the canvas
2496
+ */
2497
+ getCanvas(): HTMLCanvasElement | null;
2498
+ /**
2499
+ * Get the default texture
2500
+ */
2501
+ getDefaultTexture(): IGPUTexture | null;
2502
+ /**
2503
+ * Get the default sampler
2504
+ */
2505
+ getDefaultSampler(): GPUSampler | null;
2506
+ /**
2507
+ * Create empty frame stats
2508
+ */
2509
+ private createEmptyFrameStats;
2510
+ /**
2511
+ * Set the active XR session and bindings
2512
+ */
2513
+ setXRSession(session: XRSession | null, binding: any | null, layer: any | null): void;
2514
+ /**
2515
+ * Render a WebXR Frame
2516
+ */
2517
+ renderXR(frame: XRFrame): void;
2518
+ private multiplyMatrices;
2519
+ /**
2520
+ * Destroy the renderer and release resources
2521
+ */
2522
+ destroy(): void;
2523
+ /**
2524
+ * Render an XR frame
2525
+ */
2526
+ renderXRFrame(frame: XRFrame, refSpace: XRReferenceSpace, renderCallback: (pass: GPURenderPassEncoder, view: XRView) => void): void;
2527
+ }
2528
+
2529
+ /**
2530
+ * PhysicsDebugDrawer.ts
2531
+ *
2532
+ * Renders wireframes for physics bodies using WebGPURenderer.
2533
+ * Essential for verifying collision shapes and interaction logic.
2534
+ */
2535
+
2536
+ declare class PhysicsDebugDrawer {
2537
+ private world;
2538
+ private renderer;
2539
+ private enabled;
2540
+ private debugMeshes;
2541
+ constructor(world: IPhysicsWorld, renderer: WebGPURenderer);
2542
+ setEnabled(enabled: boolean): void;
2543
+ update(): void;
2544
+ private createDebugMesh;
2545
+ clear(): void;
2546
+ }
2547
+
2548
+ /**
2549
+ * PostProcessTypes.ts
2550
+ *
2551
+ * Type definitions for HoloScript post-processing system.
2552
+ * Supports WebGPU-based effects pipeline with HDR and LDR processing.
2553
+ *
2554
+ * @module render/postprocess
2555
+ */
2556
+ /**
2557
+ * Supported post-process effect types
2558
+ */
2559
+ type PostProcessEffectType = 'bloom' | 'tonemap' | 'dof' | 'motionBlur' | 'ssao' | 'fxaa' | 'sharpen' | 'vignette' | 'colorGrade' | 'filmGrain' | 'chromaticAberration' | 'fog' | 'caustics' | 'ssr' | 'ssgi' | 'custom';
2560
+ /**
2561
+ * Tone mapping operators
2562
+ */
2563
+ type ToneMapOperator = 'none' | 'reinhard' | 'reinhardLum' | 'aces' | 'acesApprox' | 'filmic' | 'uncharted2' | 'uchimura' | 'lottes' | 'khronos';
2564
+ /**
2565
+ * Blend modes for effect compositing
2566
+ */
2567
+ type BlendMode = 'normal' | 'add' | 'multiply' | 'screen' | 'overlay' | 'softLight';
2568
+ /**
2569
+ * Base effect parameters interface
2570
+ */
2571
+ interface IEffectParams {
2572
+ enabled: boolean;
2573
+ intensity: number;
2574
+ blendMode?: BlendMode;
2575
+ }
2576
+ /**
2577
+ * Bloom effect parameters
2578
+ */
2579
+ interface IBloomParams extends IEffectParams {
2580
+ threshold: number;
2581
+ softThreshold: number;
2582
+ radius: number;
2583
+ iterations: number;
2584
+ anamorphic: number;
2585
+ highQuality: boolean;
2586
+ }
2587
+ /**
2588
+ * Tone mapping parameters
2589
+ */
2590
+ interface IToneMapParams extends IEffectParams {
2591
+ operator: ToneMapOperator;
2592
+ exposure: number;
2593
+ gamma: number;
2594
+ whitePoint: number;
2595
+ contrast: number;
2596
+ saturation: number;
2597
+ }
2598
+ /**
2599
+ * Depth of Field parameters
2600
+ */
2601
+ interface IDepthOfFieldParams extends IEffectParams {
2602
+ focusDistance: number;
2603
+ focalLength: number;
2604
+ aperture: number;
2605
+ maxBlur: number;
2606
+ bokehShape: 'circle' | 'hexagon' | 'octagon';
2607
+ bokehQuality: 'low' | 'medium' | 'high';
2608
+ nearBlur: boolean;
2609
+ }
2610
+ /**
2611
+ * Motion blur parameters
2612
+ */
2613
+ interface IMotionBlurParams extends IEffectParams {
2614
+ samples: number;
2615
+ velocityScale: number;
2616
+ maxVelocity: number;
2617
+ }
2618
+ /**
2619
+ * SSAO parameters
2620
+ */
2621
+ interface ISSAOParams extends IEffectParams {
2622
+ radius: number;
2623
+ bias: number;
2624
+ samples: number;
2625
+ power: number;
2626
+ falloff: number;
2627
+ /** 'hemisphere' = random hemisphere, 'hbao' = horizon-based 8-dir × 4-step */
2628
+ mode?: 'hemisphere' | 'hbao';
2629
+ /** Output bent normal direction (least-occluded direction) */
2630
+ bentNormals?: boolean;
2631
+ /** 5×5 cross-bilateral spatial denoise weighted by depth + normal */
2632
+ spatialDenoise?: boolean;
2633
+ }
2634
+ /**
2635
+ * Anti-aliasing (FXAA) parameters
2636
+ */
2637
+ interface IFXAAParams extends IEffectParams {
2638
+ quality: 'low' | 'medium' | 'high' | 'ultra';
2639
+ edgeThreshold: number;
2640
+ edgeThresholdMin: number;
2641
+ }
2642
+ /**
2643
+ * Sharpen parameters
2644
+ */
2645
+ interface ISharpenParams extends IEffectParams {
2646
+ amount: number;
2647
+ threshold: number;
2648
+ }
2649
+ /**
2650
+ * Vignette parameters
2651
+ */
2652
+ interface IVignetteParams extends IEffectParams {
2653
+ roundness: number;
2654
+ smoothness: number;
2655
+ color: [number, number, number];
2656
+ }
2657
+ /**
2658
+ * Color grading parameters
2659
+ */
2660
+ interface IColorGradeParams extends IEffectParams {
2661
+ shadows: [number, number, number];
2662
+ midtones: [number, number, number];
2663
+ highlights: [number, number, number];
2664
+ shadowsOffset: number;
2665
+ highlightsOffset: number;
2666
+ hueShift: number;
2667
+ temperature: number;
2668
+ tint: number;
2669
+ lutTexture?: string;
2670
+ lutIntensity: number;
2671
+ }
2672
+ /**
2673
+ * Film grain parameters
2674
+ */
2675
+ interface IFilmGrainParams extends IEffectParams {
2676
+ size: number;
2677
+ luminanceContribution: number;
2678
+ animated: boolean;
2679
+ }
2680
+ /**
2681
+ * Chromatic aberration parameters
2682
+ */
2683
+ interface IChromaticAberrationParams extends IEffectParams {
2684
+ redOffset: [number, number];
2685
+ greenOffset: [number, number];
2686
+ blueOffset: [number, number];
2687
+ radial: boolean;
2688
+ }
2689
+ /**
2690
+ * Fog parameters
2691
+ */
2692
+ interface IFogParams extends IEffectParams {
2693
+ color: [number, number, number];
2694
+ density: number;
2695
+ start: number;
2696
+ end: number;
2697
+ height: number;
2698
+ heightFalloff: number;
2699
+ mode: 'linear' | 'exponential' | 'exponentialSquared';
2700
+ }
2701
+ /**
2702
+ * Caustics overlay parameters
2703
+ */
2704
+ interface ICausticsParams extends IEffectParams {
2705
+ scale: number;
2706
+ speed: number;
2707
+ color: [number, number, number];
2708
+ depthFade: number;
2709
+ waterLevel: number;
2710
+ /** RGB IoR separation for prismatic chromatic dispersion */
2711
+ dispersion?: number;
2712
+ /** Turbulence-driven foam overlay intensity */
2713
+ foamIntensity?: number;
2714
+ /** Darken terrain where caustics are absent */
2715
+ shadowStrength?: number;
2716
+ }
2717
+ /**
2718
+ * Screen-Space Reflections (SSR) parameters
2719
+ */
2720
+ interface ISSRParams extends IEffectParams {
2721
+ maxSteps: number;
2722
+ stepSize: number;
2723
+ thickness: number;
2724
+ roughnessFade: number;
2725
+ edgeFade: number;
2726
+ /** Golden-angle blur at hit point scaled by roughness (0 = sharp) */
2727
+ roughnessBlur?: number;
2728
+ /** Schlick Fresnel weighting strength (0 = uniform, 1 = physically correct) */
2729
+ fresnelStrength?: number;
2730
+ }
2731
+ /**
2732
+ * Screen-Space Global Illumination (SSGI) parameters
2733
+ */
2734
+ interface ISSGIParams extends IEffectParams {
2735
+ radius: number;
2736
+ samples: number;
2737
+ bounceIntensity: number;
2738
+ falloff: number;
2739
+ /** Blend with previous frame using motion vectors (0 = off, 1 = full) */
2740
+ temporalBlend?: number;
2741
+ /** 3×3 edge-stopping cross-bilateral spatial denoise */
2742
+ spatialDenoise?: boolean;
2743
+ /** Multi-bounce approximation multiplier */
2744
+ multiBounce?: number;
2745
+ }
2746
+ /**
2747
+ * Custom shader effect parameters
2748
+ */
2749
+ interface ICustomEffectParams extends IEffectParams {
2750
+ shader: string;
2751
+ uniforms: Record<string, number | number[] | boolean>;
2752
+ }
2753
+ /**
2754
+ * Union type of all effect parameters
2755
+ */
2756
+ type EffectParams = IBloomParams | IToneMapParams | IDepthOfFieldParams | IMotionBlurParams | ISSAOParams | IFXAAParams | ISharpenParams | IVignetteParams | IColorGradeParams | IFilmGrainParams | IChromaticAberrationParams | IFogParams | ICausticsParams | ISSRParams | ISSGIParams | ICustomEffectParams;
2757
+ /**
2758
+ * Effect configuration for pipeline
2759
+ */
2760
+ interface IEffectConfig {
2761
+ type: PostProcessEffectType;
2762
+ name?: string;
2763
+ params: EffectParams;
2764
+ order?: number;
2765
+ }
2766
+ /**
2767
+ * Render target configuration
2768
+ */
2769
+ interface IRenderTargetConfig {
2770
+ width: number;
2771
+ height: number;
2772
+ format: GPUTextureFormat;
2773
+ mipLevelCount?: number;
2774
+ sampleCount?: number;
2775
+ label?: string;
2776
+ }
2777
+ /**
2778
+ * Post-process pipeline configuration
2779
+ */
2780
+ interface IPostProcessPipelineConfig {
2781
+ hdrEnabled: boolean;
2782
+ hdrFormat: GPUTextureFormat;
2783
+ ldrFormat: GPUTextureFormat;
2784
+ msaaSamples: 1 | 4;
2785
+ effects: IEffectConfig[];
2786
+ autoResize: boolean;
2787
+ }
2788
+ /**
2789
+ * Runtime render target
2790
+ */
2791
+ interface IRenderTarget {
2792
+ id: string;
2793
+ texture: GPUTexture;
2794
+ view: GPUTextureView;
2795
+ config: IRenderTargetConfig;
2796
+ }
2797
+ /**
2798
+ * Frame data passed to effects
2799
+ */
2800
+ interface IFrameData {
2801
+ time: number;
2802
+ deltaTime: number;
2803
+ frameCount: number;
2804
+ resolution: [number, number];
2805
+ nearPlane: number;
2806
+ farPlane: number;
2807
+ cameraPosition?: [number, number, number];
2808
+ viewMatrix?: Float32Array;
2809
+ projectionMatrix?: Float32Array;
2810
+ prevViewMatrix?: Float32Array;
2811
+ jitter?: [number, number];
2812
+ }
2813
+ /**
2814
+ * Effect render context
2815
+ */
2816
+ interface IEffectRenderContext {
2817
+ device: GPUDevice;
2818
+ commandEncoder: GPUCommandEncoder;
2819
+ frameData: IFrameData;
2820
+ input: IRenderTarget;
2821
+ output: IRenderTarget;
2822
+ depth?: IRenderTarget;
2823
+ velocity?: IRenderTarget;
2824
+ }
2825
+ /**
2826
+ * Default parameter values for each effect type
2827
+ */
2828
+ declare const DEFAULT_PARAMS: Record<PostProcessEffectType, EffectParams>;
2829
+ /**
2830
+ * Get default parameters for effect type
2831
+ */
2832
+ declare function getDefaultParams<T extends EffectParams>(type: PostProcessEffectType): T;
2833
+ /**
2834
+ * Merge effect parameters with defaults
2835
+ */
2836
+ declare function mergeParams<T extends EffectParams>(type: PostProcessEffectType, partial: Partial<T>): T;
2837
+ /**
2838
+ * Validate effect parameters
2839
+ */
2840
+ declare function validateParams(type: PostProcessEffectType, params: EffectParams): {
2841
+ valid: boolean;
2842
+ errors: string[];
2843
+ };
2844
+ /**
2845
+ * Size in bytes for uniform buffers
2846
+ */
2847
+ declare const UNIFORM_SIZES: Record<PostProcessEffectType, number>;
2848
+ /**
2849
+ * FXAA quality levels
2850
+ */
2851
+ type FXAAQuality = 'low' | 'medium' | 'high' | 'ultra';
2852
+ /**
2853
+ * Alias for IEffectParams (API compatibility)
2854
+ */
2855
+ type IBaseEffectParams = IEffectParams;
2856
+ /**
2857
+ * Alias for IDepthOfFieldParams (API compatibility)
2858
+ */
2859
+ type IDOFParams = IDepthOfFieldParams;
2860
+
2861
+ /**
2862
+ * PostProcessEffect.ts
2863
+ *
2864
+ * Base class for post-processing effects and built-in effect implementations.
2865
+ * All effects compile to WebGPU compute/render pipelines.
2866
+ *
2867
+ * @module render/postprocess
2868
+ */
2869
+
2870
+ /**
2871
+ * Abstract base class for all post-processing effects
2872
+ */
2873
+ declare abstract class PostProcessEffect {
2874
+ readonly type: PostProcessEffectType;
2875
+ readonly name: string;
2876
+ protected params: EffectParams;
2877
+ protected pipeline: GPURenderPipeline | null;
2878
+ protected uniformBuffer: GPUBuffer | null;
2879
+ protected bindGroup: GPUBindGroup | null;
2880
+ protected sampler: GPUSampler | null;
2881
+ protected _initialized: boolean;
2882
+ constructor(type: PostProcessEffectType, name?: string, params?: Partial<EffectParams>);
2883
+ /**
2884
+ * Check if effect is enabled
2885
+ */
2886
+ get enabled(): boolean;
2887
+ /**
2888
+ * Enable/disable effect
2889
+ */
2890
+ set enabled(value: boolean);
2891
+ /**
2892
+ * Get effect intensity
2893
+ */
2894
+ get intensity(): number;
2895
+ /**
2896
+ * Set effect intensity
2897
+ */
2898
+ set intensity(value: number);
2899
+ /**
2900
+ * Get current parameters
2901
+ */
2902
+ getParams<T extends EffectParams>(): T;
2903
+ /**
2904
+ * Update parameters
2905
+ */
2906
+ setParams(params: Partial<EffectParams>): void;
2907
+ /**
2908
+ * Check if effect is initialized
2909
+ */
2910
+ get initialized(): boolean;
2911
+ /**
2912
+ * Initialize GPU resources
2913
+ */
2914
+ initialize(device: GPUDevice): Promise<void>;
2915
+ /**
2916
+ * Create render/compute pipeline - override in subclasses
2917
+ */
2918
+ protected abstract createPipeline(device: GPUDevice): Promise<void>;
2919
+ /**
2920
+ * Update uniform buffer with current parameters
2921
+ */
2922
+ protected abstract updateUniforms(device: GPUDevice, frameData: {
2923
+ time: number;
2924
+ deltaTime: number;
2925
+ }): void;
2926
+ /**
2927
+ * Render the effect
2928
+ */
2929
+ abstract render(context: IEffectRenderContext): void;
2930
+ /**
2931
+ * Dispose GPU resources
2932
+ */
2933
+ dispose(): void;
2934
+ }
2935
+ /**
2936
+ * Bloom effect - adds glow to bright areas
2937
+ */
2938
+ declare class BloomEffect extends PostProcessEffect {
2939
+ private downsamplePipelines;
2940
+ private upsamplePipelines;
2941
+ private mipViews;
2942
+ private mipTexture;
2943
+ constructor(params?: Partial<IBloomParams>);
2944
+ protected createPipeline(device: GPUDevice): Promise<void>;
2945
+ protected updateUniforms(device: GPUDevice, frameData: {
2946
+ time: number;
2947
+ deltaTime: number;
2948
+ }): void;
2949
+ render(context: IEffectRenderContext): void;
2950
+ dispose(): void;
2951
+ }
2952
+ /**
2953
+ * Tone mapping effect - converts HDR to LDR
2954
+ */
2955
+ declare class ToneMapEffect extends PostProcessEffect {
2956
+ constructor(params?: Partial<IToneMapParams>);
2957
+ protected createPipeline(device: GPUDevice): Promise<void>;
2958
+ protected updateUniforms(device: GPUDevice, _frameData: {
2959
+ time: number;
2960
+ deltaTime: number;
2961
+ }): void;
2962
+ render(context: IEffectRenderContext): void;
2963
+ }
2964
+ /**
2965
+ * FXAA anti-aliasing effect
2966
+ */
2967
+ declare class FXAAEffect extends PostProcessEffect {
2968
+ constructor(params?: Partial<IFXAAParams>);
2969
+ protected createPipeline(device: GPUDevice): Promise<void>;
2970
+ protected updateUniforms(device: GPUDevice, _frameData: {
2971
+ time: number;
2972
+ deltaTime: number;
2973
+ }): void;
2974
+ render(context: IEffectRenderContext): void;
2975
+ }
2976
+ /**
2977
+ * Vignette effect - darkens edges of screen
2978
+ */
2979
+ declare class VignetteEffect extends PostProcessEffect {
2980
+ constructor(params?: Partial<IVignetteParams>);
2981
+ protected createPipeline(device: GPUDevice): Promise<void>;
2982
+ protected updateUniforms(device: GPUDevice, _frameData: {
2983
+ time: number;
2984
+ deltaTime: number;
2985
+ }): void;
2986
+ render(context: IEffectRenderContext): void;
2987
+ }
2988
+ /**
2989
+ * Film grain effect
2990
+ */
2991
+ declare class FilmGrainEffect extends PostProcessEffect {
2992
+ constructor(params?: Partial<IFilmGrainParams>);
2993
+ protected createPipeline(device: GPUDevice): Promise<void>;
2994
+ protected updateUniforms(device: GPUDevice, frameData: {
2995
+ time: number;
2996
+ deltaTime: number;
2997
+ }): void;
2998
+ render(context: IEffectRenderContext): void;
2999
+ }
3000
+ /**
3001
+ * Sharpen effect
3002
+ */
3003
+ declare class SharpenEffect extends PostProcessEffect {
3004
+ constructor(params?: Partial<ISharpenParams>);
3005
+ protected createPipeline(device: GPUDevice): Promise<void>;
3006
+ protected updateUniforms(device: GPUDevice, _frameData: {
3007
+ time: number;
3008
+ deltaTime: number;
3009
+ }): void;
3010
+ render(context: IEffectRenderContext): void;
3011
+ }
3012
+ /**
3013
+ * Chromatic aberration effect
3014
+ */
3015
+ declare class ChromaticAberrationEffect extends PostProcessEffect {
3016
+ constructor(params?: Partial<IChromaticAberrationParams>);
3017
+ protected createPipeline(device: GPUDevice): Promise<void>;
3018
+ protected updateUniforms(device: GPUDevice, _frameData: {
3019
+ time: number;
3020
+ deltaTime: number;
3021
+ }): void;
3022
+ render(context: IEffectRenderContext): void;
3023
+ }
3024
+ /**
3025
+ * Caustics overlay effect — underwater refracted light patterns
3026
+ */
3027
+ declare class CausticsEffect extends PostProcessEffect {
3028
+ constructor(params?: Partial<ICausticsParams>);
3029
+ protected createPipeline(device: GPUDevice): Promise<void>;
3030
+ protected updateUniforms(device: GPUDevice, frameData: {
3031
+ time: number;
3032
+ deltaTime: number;
3033
+ }): void;
3034
+ render(context: IEffectRenderContext): void;
3035
+ }
3036
+ /**
3037
+ * Screen-Space Reflections (SSR) effect
3038
+ */
3039
+ declare class SSREffect extends PostProcessEffect {
3040
+ constructor(params?: Partial<ISSRParams>);
3041
+ protected createPipeline(device: GPUDevice): Promise<void>;
3042
+ protected updateUniforms(device: GPUDevice, _frameData: {
3043
+ time: number;
3044
+ deltaTime: number;
3045
+ }): void;
3046
+ render(context: IEffectRenderContext): void;
3047
+ }
3048
+ /**
3049
+ * Screen-Space Ambient Occlusion (SSAO) effect
3050
+ */
3051
+ declare class SSAOEffect extends PostProcessEffect {
3052
+ constructor(params?: Partial<ISSAOParams>);
3053
+ protected createPipeline(device: GPUDevice): Promise<void>;
3054
+ protected updateUniforms(device: GPUDevice, _frameData: {
3055
+ time: number;
3056
+ deltaTime: number;
3057
+ }): void;
3058
+ render(context: IEffectRenderContext): void;
3059
+ }
3060
+ /**
3061
+ * Screen-Space Global Illumination (SSGI) effect
3062
+ */
3063
+ declare class SSGIEffect extends PostProcessEffect {
3064
+ constructor(params?: Partial<ISSGIParams>);
3065
+ protected createPipeline(device: GPUDevice): Promise<void>;
3066
+ protected updateUniforms(device: GPUDevice, _frameData: {
3067
+ time: number;
3068
+ deltaTime: number;
3069
+ }): void;
3070
+ render(context: IEffectRenderContext): void;
3071
+ }
3072
+ /**
3073
+ * Factory function to create effects by type
3074
+ */
3075
+ declare function createEffect(type: PostProcessEffectType, params?: Partial<EffectParams>): PostProcessEffect;
3076
+
3077
+ /**
3078
+ * PostProcessShaders.ts
3079
+ *
3080
+ * WGSL shader code for all post-processing effects.
3081
+ * Includes fullscreen triangle vertex shader and per-effect fragment shaders.
3082
+ *
3083
+ * @module render/postprocess
3084
+ */
3085
+ /**
3086
+ * Fullscreen triangle vertex shader
3087
+ * Generates fullscreen coverage with a single triangle
3088
+ */
3089
+ declare const FULLSCREEN_VERTEX_SHADER = "\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n}\n\n@vertex\nfn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {\n // Generate fullscreen triangle\n var positions = array<vec2f, 3>(\n vec2f(-1.0, -1.0),\n vec2f(3.0, -1.0),\n vec2f(-1.0, 3.0)\n );\n\n var uvs = array<vec2f, 3>(\n vec2f(0.0, 1.0),\n vec2f(2.0, 1.0),\n vec2f(0.0, -1.0)\n );\n\n var output: VertexOutput;\n output.position = vec4f(positions[vertexIndex], 0.0, 1.0);\n output.uv = uvs[vertexIndex];\n return output;\n}\n";
3090
+ /**
3091
+ * Common shader utilities
3092
+ */
3093
+ declare const SHADER_UTILS = "\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n";
3094
+ /**
3095
+ * Bloom effect shader
3096
+ */
3097
+ declare const BLOOM_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct BloomUniforms {\n intensity: f32,\n threshold: f32,\n softThreshold: f32,\n radius: f32,\n iterations: f32,\n anamorphic: f32,\n highQuality: f32,\n padding: f32,\n time: f32,\n deltaTime: f32,\n padding2: vec2f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: BloomUniforms;\n\n// Threshold with soft knee\nfn softThreshold(color: vec3f) -> vec3f {\n let brightness = max(max(color.r, color.g), color.b);\n var soft = brightness - uniforms.threshold + uniforms.softThreshold;\n soft = clamp(soft, 0.0, 2.0 * uniforms.softThreshold);\n soft = soft * soft / (4.0 * uniforms.softThreshold + 0.00001);\n var contribution = max(soft, brightness - uniforms.threshold);\n contribution /= max(brightness, 0.00001);\n return color * contribution;\n}\n\n// 9-tap gaussian blur\nfn blur9(uv: vec2f, direction: vec2f) -> vec3f {\n let texSize = vec2f(textureDimensions(inputTexture));\n let offset = direction / texSize;\n\n var color = textureSample(inputTexture, texSampler, uv).rgb * 0.2270270270;\n color += textureSample(inputTexture, texSampler, uv + offset * 1.3846153846).rgb * 0.3162162162;\n color += textureSample(inputTexture, texSampler, uv - offset * 1.3846153846).rgb * 0.3162162162;\n color += textureSample(inputTexture, texSampler, uv + offset * 3.2307692308).rgb * 0.0702702703;\n color += textureSample(inputTexture, texSampler, uv - offset * 3.2307692308).rgb * 0.0702702703;\n\n return color;\n}\n\n@fragment\nfn fs_bloom(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv).rgb;\n\n // Extract bright pixels with soft threshold\n var bloom = softThreshold(color);\n\n // Simple blur approximation (in production, use multi-pass)\n let texSize = vec2f(textureDimensions(inputTexture));\n let radius = uniforms.radius / texSize;\n\n var blurred = bloom;\n for (var i = 0u; i < 4u; i++) {\n let angle = f32(i) * 1.5707963268;\n let offset = vec2f(cos(angle), sin(angle)) * radius;\n blurred += textureSample(inputTexture, texSampler, input.uv + offset).rgb;\n blurred += textureSample(inputTexture, texSampler, input.uv - offset).rgb;\n }\n blurred /= 9.0;\n\n // Composite bloom\n let result = color + softThreshold(blurred) * uniforms.intensity;\n\n return vec4f(result, 1.0);\n}\n";
3098
+ /**
3099
+ * Tone mapping shader with multiple operators
3100
+ */
3101
+ declare const TONEMAP_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct ToneMapUniforms {\n operator: f32,\n exposure: f32,\n gamma: f32,\n whitePoint: f32,\n contrast: f32,\n saturation: f32,\n intensity: f32,\n padding: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: ToneMapUniforms;\n\n// Reinhard tone mapping\nfn tonemapReinhard(x: vec3f) -> vec3f {\n return x / (x + vec3f(1.0));\n}\n\n// Reinhard with luminance-based mapping\nfn tonemapReinhardLum(x: vec3f) -> vec3f {\n let l = luminance(x);\n let nl = l / (l + 1.0);\n return x * (nl / l);\n}\n\n// ACES filmic tone mapping\nfn tonemapACES(x: vec3f) -> vec3f {\n let a = 2.51;\n let b = 0.03;\n let c = 2.43;\n let d = 0.59;\n let e = 0.14;\n return clamp((x * (a * x + vec3f(b))) / (x * (c * x + vec3f(d)) + vec3f(e)), vec3f(0.0), vec3f(1.0));\n}\n\n// ACES approximation (cheaper)\nfn tonemapACESApprox(x: vec3f) -> vec3f {\n let v = x * 0.6;\n let a = v * (v * 2.51 + 0.03);\n let b = v * (v * 2.43 + 0.59) + 0.14;\n return clamp(a / b, vec3f(0.0), vec3f(1.0));\n}\n\n// Uncharted 2 filmic\nfn uncharted2Partial(x: vec3f) -> vec3f {\n let A = 0.15;\n let B = 0.50;\n let C = 0.10;\n let D = 0.20;\n let E = 0.02;\n let F = 0.30;\n return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nfn tonemapUncharted2(x: vec3f) -> vec3f {\n let white = 11.2;\n let curr = uncharted2Partial(x * 2.0);\n let whiteScale = vec3f(1.0) / uncharted2Partial(vec3f(white));\n return curr * whiteScale;\n}\n\n// Lottes (AMD)\nfn tonemapLottes(x: vec3f) -> vec3f {\n let a = vec3f(1.6);\n let d = vec3f(0.977);\n let hdrMax = vec3f(8.0);\n let midIn = vec3f(0.18);\n let midOut = vec3f(0.267);\n\n let b = (-pow(midIn, a) + pow(hdrMax, a) * midOut) / ((pow(hdrMax, a * d) - pow(midIn, a * d)) * midOut);\n let c = (pow(hdrMax, a * d) * pow(midIn, a) - pow(hdrMax, a) * pow(midIn, a * d) * midOut) /\n ((pow(hdrMax, a * d) - pow(midIn, a * d)) * midOut);\n\n return pow(x, a) / (pow(x, a * d) * b + c);\n}\n\n// Uchimura (GT)\nfn tonemapUchimura(x: vec3f) -> vec3f {\n let P = 1.0; // max brightness\n let a = 1.0; // contrast\n let m = 0.22; // linear section start\n let l = 0.4; // linear section length\n let c = 1.33; // black tightness\n let b = 0.0; // black lightness\n\n let l0 = ((P - m) * l) / a;\n let S0 = m + l0;\n let S1 = m + a * l0;\n let C2 = (a * P) / (P - S1);\n let CP = -C2 / P;\n\n var result: vec3f;\n for (var i = 0u; i < 3u; i++) {\n let v = x[i];\n var w: f32;\n if (v < m) {\n w = v;\n } else if (v < S0) {\n w = m + a * (v - m);\n } else {\n w = P - (P - S1) * exp(CP * (v - S0));\n }\n result[i] = w;\n }\n return result;\n}\n\n// Khronos PBR neutral\nfn tonemapKhronosPBR(color: vec3f) -> vec3f {\n let startCompression = 0.8 - 0.04;\n let desaturation = 0.15;\n\n var x = min(color, vec3f(1.0));\n let peak = max(max(color.r, color.g), color.b);\n\n if (peak < startCompression) {\n return x;\n }\n\n let d = 1.0 - startCompression;\n let newPeak = 1.0 - d * d / (peak + d - startCompression);\n x *= newPeak / peak;\n\n let g = 1.0 - 1.0 / (desaturation * (peak - newPeak) + 1.0);\n return mix(x, vec3f(newPeak), g);\n}\n\n@fragment\nfn fs_tonemap(input: VertexOutput) -> @location(0) vec4f {\n var color = textureSample(inputTexture, texSampler, input.uv).rgb;\n\n // Apply exposure\n color *= uniforms.exposure;\n\n // Apply contrast (around mid-gray)\n let midGray = 0.18;\n color = midGray * pow(color / midGray, vec3f(uniforms.contrast));\n\n // Apply saturation\n let lum = luminance(color);\n color = mix(vec3f(lum), color, uniforms.saturation);\n\n // Apply tone mapping\n let op = u32(uniforms.operator);\n var mapped: vec3f;\n switch (op) {\n case 0u: { mapped = clamp(color, vec3f(0.0), vec3f(1.0)); } // None\n case 1u: { mapped = tonemapReinhard(color); }\n case 2u: { mapped = tonemapReinhardLum(color); }\n case 3u: { mapped = tonemapACES(color); }\n case 4u: { mapped = tonemapACESApprox(color); }\n case 5u: { mapped = tonemapACES(color); } // Filmic = ACES\n case 6u: { mapped = tonemapUncharted2(color); }\n case 7u: { mapped = tonemapUchimura(color); }\n case 8u: { mapped = tonemapLottes(color); }\n case 9u: { mapped = tonemapKhronosPBR(color); }\n default: { mapped = tonemapACES(color); }\n }\n\n // Apply gamma correction\n let result = pow(mapped, vec3f(1.0 / uniforms.gamma));\n\n return vec4f(result, 1.0);\n}\n";
3102
+ /**
3103
+ * FXAA anti-aliasing shader
3104
+ */
3105
+ declare const FXAA_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct FXAAUniforms {\n quality: f32,\n edgeThreshold: f32,\n edgeThresholdMin: f32,\n intensity: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: FXAAUniforms;\n\n@fragment\nfn fs_fxaa(input: VertexOutput) -> @location(0) vec4f {\n let texSize = vec2f(textureDimensions(inputTexture));\n let invSize = 1.0 / texSize;\n\n // Sample center and neighbors\n let center = textureSample(inputTexture, texSampler, input.uv);\n let lumC = luminance(center.rgb);\n\n let lumN = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(0.0, -1.0) * invSize).rgb);\n let lumS = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(0.0, 1.0) * invSize).rgb);\n let lumE = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(1.0, 0.0) * invSize).rgb);\n let lumW = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(-1.0, 0.0) * invSize).rgb);\n\n let lumMin = min(lumC, min(min(lumN, lumS), min(lumE, lumW)));\n let lumMax = max(lumC, max(max(lumN, lumS), max(lumE, lumW)));\n let lumRange = lumMax - lumMin;\n\n // Skip if edge contrast is too low\n if (lumRange < max(uniforms.edgeThresholdMin, lumMax * uniforms.edgeThreshold)) {\n return center;\n }\n\n // Compute edge direction\n let lumNW = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(-1.0, -1.0) * invSize).rgb);\n let lumNE = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(1.0, -1.0) * invSize).rgb);\n let lumSW = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(-1.0, 1.0) * invSize).rgb);\n let lumSE = luminance(textureSample(inputTexture, texSampler, input.uv + vec2f(1.0, 1.0) * invSize).rgb);\n\n let edgeH = abs((lumNW + lumNE) - 2.0 * lumN) +\n abs((lumW + lumE) - 2.0 * lumC) * 2.0 +\n abs((lumSW + lumSE) - 2.0 * lumS);\n\n let edgeV = abs((lumNW + lumSW) - 2.0 * lumW) +\n abs((lumN + lumS) - 2.0 * lumC) * 2.0 +\n abs((lumNE + lumSE) - 2.0 * lumE);\n\n let isHorizontal = edgeH >= edgeV;\n\n // Blend direction\n let stepLength = select(invSize.x, invSize.y, isHorizontal);\n var lum1: f32;\n var lum2: f32;\n\n if (isHorizontal) {\n lum1 = lumN;\n lum2 = lumS;\n } else {\n lum1 = lumW;\n lum2 = lumE;\n }\n\n let gradient1 = abs(lum1 - lumC);\n let gradient2 = abs(lum2 - lumC);\n\n let is1Steeper = gradient1 >= gradient2;\n let gradientScaled = 0.25 * max(gradient1, gradient2);\n let lumLocalAvg = 0.5 * (select(lum2, lum1, is1Steeper) + lumC);\n\n // Subpixel anti-aliasing\n let subpixC = (2.0 * (lumN + lumS + lumE + lumW) + lumNW + lumNE + lumSW + lumSE) / 12.0;\n let subpixFactor = clamp(abs(subpixC - lumC) / lumRange, 0.0, 1.0);\n let subpix = (-(subpixFactor * subpixFactor) + 1.0) * subpixFactor;\n\n // Apply blend\n var finalUV = input.uv;\n let blendFactor = max(subpix, 0.5);\n\n if (isHorizontal) {\n finalUV.y += select(stepLength, -stepLength, is1Steeper) * blendFactor;\n } else {\n finalUV.x += select(stepLength, -stepLength, is1Steeper) * blendFactor;\n }\n\n let result = textureSample(inputTexture, texSampler, finalUV);\n return mix(center, result, uniforms.intensity);\n}\n";
3106
+ /**
3107
+ * Vignette shader
3108
+ */
3109
+ declare const VIGNETTE_SHADER = "\nstruct VignetteUniforms {\n intensity: f32,\n roundness: f32,\n smoothness: f32,\n padding: f32,\n color: vec4f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: VignetteUniforms;\n\n@fragment\nfn fs_vignette(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n\n let uv = input.uv * 2.0 - 1.0;\n let aspect = 1.0; // Could be passed via uniforms\n\n var coords = uv;\n coords.x *= aspect;\n\n // Compute vignette\n let dist = length(coords) * uniforms.roundness;\n let vignette = 1.0 - smoothstep(1.0 - uniforms.smoothness, 1.0, dist);\n\n // Blend with vignette color\n let vignetteColor = mix(uniforms.color.rgb, color.rgb, vignette);\n let result = mix(color.rgb, vignetteColor, uniforms.intensity);\n\n return vec4f(result, color.a);\n}\n";
3110
+ /**
3111
+ * Film grain shader
3112
+ */
3113
+ declare const FILM_GRAIN_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct FilmGrainUniforms {\n intensity: f32,\n size: f32,\n luminanceContribution: f32,\n time: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: FilmGrainUniforms;\n\n@fragment\nfn fs_filmgrain(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n\n let texSize = vec2f(textureDimensions(inputTexture));\n let noiseUV = input.uv * texSize / uniforms.size;\n\n // Generate animated noise\n let grain = noise2D(noiseUV + vec2f(uniforms.time * 123.456, uniforms.time * 789.012)) * 2.0 - 1.0;\n\n // Scale grain by luminance\n let lum = luminance(color.rgb);\n let grainAmount = uniforms.intensity * mix(1.0, 1.0 - lum, uniforms.luminanceContribution);\n\n let result = color.rgb + vec3f(grain * grainAmount);\n\n return vec4f(result, color.a);\n}\n";
3114
+ /**
3115
+ * Sharpen shader
3116
+ */
3117
+ declare const SHARPEN_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct SharpenUniforms {\n intensity: f32,\n amount: f32,\n threshold: f32,\n padding: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: SharpenUniforms;\n\n@fragment\nfn fs_sharpen(input: VertexOutput) -> @location(0) vec4f {\n let texSize = vec2f(textureDimensions(inputTexture));\n let texel = 1.0 / texSize;\n\n // Sample 3x3 neighborhood\n let center = textureSample(inputTexture, texSampler, input.uv).rgb;\n let n = textureSample(inputTexture, texSampler, input.uv + vec2f(0.0, -texel.y)).rgb;\n let s = textureSample(inputTexture, texSampler, input.uv + vec2f(0.0, texel.y)).rgb;\n let e = textureSample(inputTexture, texSampler, input.uv + vec2f(texel.x, 0.0)).rgb;\n let w = textureSample(inputTexture, texSampler, input.uv + vec2f(-texel.x, 0.0)).rgb;\n\n // Compute unsharp mask\n let blur = (n + s + e + w) * 0.25;\n let diff = center - blur;\n\n // Apply threshold\n let sharpened = select(\n center,\n center + diff * uniforms.amount,\n length(diff) > uniforms.threshold\n );\n\n let result = mix(center, sharpened, uniforms.intensity);\n\n return vec4f(result, 1.0);\n}\n";
3118
+ /**
3119
+ * Chromatic aberration shader
3120
+ */
3121
+ declare const CHROMATIC_ABERRATION_SHADER = "\nstruct ChromaticUniforms {\n intensity: f32,\n radial: f32,\n padding: vec2f,\n redOffset: vec2f,\n greenOffset: vec2f,\n blueOffset: vec2f,\n padding2: vec2f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: ChromaticUniforms;\n\n@fragment\nfn fs_chromatic(input: VertexOutput) -> @location(0) vec4f {\n let uv = input.uv;\n\n var rOffset = uniforms.redOffset * uniforms.intensity;\n var gOffset = uniforms.greenOffset * uniforms.intensity;\n var bOffset = uniforms.blueOffset * uniforms.intensity;\n\n // Apply radial distortion if enabled\n if (uniforms.radial > 0.5) {\n let center = vec2f(0.5);\n let dir = uv - center;\n let dist = length(dir);\n let radialFactor = dist * dist;\n\n rOffset *= radialFactor;\n gOffset *= radialFactor;\n bOffset *= radialFactor;\n }\n\n let r = textureSample(inputTexture, texSampler, uv + rOffset).r;\n let g = textureSample(inputTexture, texSampler, uv + gOffset).g;\n let b = textureSample(inputTexture, texSampler, uv + bOffset).b;\n\n return vec4f(r, g, b, 1.0);\n}\n";
3122
+ /**
3123
+ * Depth of Field shader
3124
+ * Uses circle-of-confusion from depth to apply variable-radius disc blur.
3125
+ */
3126
+ declare const DOF_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct DOFUniforms {\n focusDistance: f32,\n focalLength: f32,\n aperture: f32,\n maxBlur: f32,\n nearPlane: f32,\n farPlane: f32,\n padding: vec2f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: DOFUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n\nfn linearizeDepth(d: f32) -> f32 {\n return uniforms.nearPlane * uniforms.farPlane /\n (uniforms.farPlane - d * (uniforms.farPlane - uniforms.nearPlane));\n}\n\nfn circleOfConfusion(depth: f32) -> f32 {\n let s1 = depth;\n let s2 = uniforms.focusDistance;\n let f = uniforms.focalLength;\n let a = uniforms.aperture;\n let coc = abs(a * f * (s2 - s1) / (s1 * (s2 - f)));\n return clamp(coc, 0.0, uniforms.maxBlur);\n}\n\n@fragment\nfn fs_dof(input: VertexOutput) -> @location(0) vec4f {\n let dims = vec2f(textureDimensions(inputTexture));\n let texelSize = 1.0 / dims;\n\n let rawDepth = textureSample(depthTexture, texSampler, input.uv).r;\n let depth = linearizeDepth(rawDepth);\n let coc = circleOfConfusion(depth);\n\n // Disc blur with 16 samples in a Poisson-like pattern\n let offsets = array<vec2f, 16>(\n vec2f(-0.94201, -0.39906), vec2f( 0.94558, -0.76890),\n vec2f(-0.09418, -0.92938), vec2f( 0.34495, 0.29387),\n vec2f(-0.91588, 0.45771), vec2f(-0.81544, 0.00298),\n vec2f(-0.38277, -0.56270), vec2f( 0.97484, 0.75648),\n vec2f( 0.44323, -0.97511), vec2f( 0.53742, 0.01683),\n vec2f(-0.26496, -0.01497), vec2f(-0.44693, 0.93910),\n vec2f( 0.79197, 0.19090), vec2f(-0.24188, -0.99706),\n vec2f( 0.04578, 0.53300), vec2f(-0.75738, -0.81580)\n );\n\n var color = vec4f(0.0);\n var totalWeight = 0.0;\n\n for (var i = 0u; i < 16u; i++) {\n let sampleUV = input.uv + offsets[i] * texelSize * coc * 8.0;\n let sampleColor = textureSample(inputTexture, texSampler, sampleUV);\n let sampleDepth = linearizeDepth(textureSample(depthTexture, texSampler, sampleUV).r);\n let sampleCoC = circleOfConfusion(sampleDepth);\n let w = max(sampleCoC, coc * 0.2);\n color += sampleColor * w;\n totalWeight += w;\n }\n\n return color / totalWeight;\n}\n";
3127
+ /**
3128
+ * SSAO shader (Screen-Space Ambient Occlusion)
3129
+ * Hemisphere sampling around each fragment using depth + reconstructed normals.
3130
+ */
3131
+ declare const SSAO_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct SSAOUniforms {\n radius: f32,\n bias: f32,\n samples: f32,\n power: f32,\n falloff: f32,\n mode: f32, // 0 = hemisphere, 1 = hbao\n bentNormals: f32, // 0 = off, 1 = on\n spatialDenoise: f32, // 0 = off, 1 = on\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: SSAOUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n\nfn hash3(p: vec2f) -> vec3f {\n let q = vec3f(\n dot(p, vec2f(127.1, 311.7)),\n dot(p, vec2f(269.5, 183.3)),\n dot(p, vec2f(419.2, 371.9))\n );\n return fract(sin(q) * 43758.5453) * 2.0 - 1.0;\n}\n\nfn reconstructNormal(uv: vec2f, texelSize: vec2f) -> vec3f {\n let dc = textureSample(depthTexture, texSampler, uv).r;\n let dl = textureSample(depthTexture, texSampler, uv - vec2f(texelSize.x, 0.0)).r;\n let dr = textureSample(depthTexture, texSampler, uv + vec2f(texelSize.x, 0.0)).r;\n let db = textureSample(depthTexture, texSampler, uv - vec2f(0.0, texelSize.y)).r;\n let dt = textureSample(depthTexture, texSampler, uv + vec2f(0.0, texelSize.y)).r;\n return normalize(vec3f(dl - dr, db - dt, 2.0 * texelSize.x));\n}\n\n// HBAO: 8 directions \u00D7 4 steps per direction = 32 samples\nfn hbaoOcclusion(uv: vec2f, normal: vec3f, centerDepth: f32, texelSize: vec2f) -> vec2f {\n var occlusion = 0.0;\n var bentN = vec3f(0.0);\n let directions = 8;\n let stepsPerDir = 4;\n let angleStep = 6.28318 / f32(directions);\n\n for (var d = 0; d < directions; d++) {\n let angle = f32(d) * angleStep;\n let dir = vec2f(cos(angle), sin(angle));\n var maxHorizon = uniforms.bias;\n\n for (var s = 1; s <= stepsPerDir; s++) {\n let stepScale = f32(s) / f32(stepsPerDir);\n let sampleOffset = dir * uniforms.radius * stepScale * texelSize * 8.0;\n let sampleUV = uv + sampleOffset;\n let sampleDepth = textureSample(depthTexture, texSampler, sampleUV).r;\n let depthDelta = centerDepth - sampleDepth;\n\n if (depthDelta > uniforms.bias && depthDelta < uniforms.falloff) {\n let horizonAngle = depthDelta / (length(sampleOffset) * 500.0 + 0.001);\n maxHorizon = max(maxHorizon, horizonAngle);\n }\n }\n occlusion += maxHorizon;\n // Accumulate bent normal: direction of least occlusion\n let weight = 1.0 - min(maxHorizon * 2.0, 1.0);\n bentN += vec3f(dir * weight, weight);\n }\n\n occlusion = 1.0 - pow(occlusion / f32(directions), uniforms.power);\n return vec2f(occlusion, length(bentN.xy));\n}\n\n// 5\u00D75 cross-bilateral spatial denoise\nfn spatialDenoise(uv: vec2f, centerOcclusion: f32, centerDepth: f32, centerNormal: vec3f, texelSize: vec2f) -> f32 {\n var sum = centerOcclusion;\n var totalWeight = 1.0;\n\n for (var y = -2; y <= 2; y++) {\n for (var x = -2; x <= 2; x++) {\n if (x == 0 && y == 0) { continue; }\n let offset = vec2f(f32(x), f32(y)) * texelSize;\n let sampleUV = uv + offset;\n let sampleDepth = textureSample(depthTexture, texSampler, sampleUV).r;\n let sampleNormal = reconstructNormal(sampleUV, texelSize);\n\n // Depth similarity weight\n let depthW = exp(-abs(centerDepth - sampleDepth) * 100.0);\n // Normal similarity weight\n let normalW = max(dot(centerNormal, sampleNormal), 0.0);\n // Spatial weight (Gaussian)\n let spatialW = exp(-f32(x * x + y * y) * 0.2);\n\n let w = depthW * normalW * spatialW;\n // Re-sample occlusion at this location (simplified: use color channel)\n let sampleColor = textureSample(inputTexture, texSampler, sampleUV);\n let sampleOcclusion = luminance(sampleColor.rgb) / max(luminance(textureSample(inputTexture, texSampler, uv).rgb), 0.001);\n sum += clamp(sampleOcclusion, 0.0, 2.0) * w;\n totalWeight += w;\n }\n }\n\n return sum / totalWeight;\n}\n\n@fragment\nfn fs_ssao(input: VertexOutput) -> @location(0) vec4f {\n let dims = vec2f(textureDimensions(inputTexture));\n let texelSize = 1.0 / dims;\n let color = textureSample(inputTexture, texSampler, input.uv);\n let centerDepth = textureSample(depthTexture, texSampler, input.uv).r;\n let normal = reconstructNormal(input.uv, texelSize);\n\n var occlusion = 0.0;\n\n if (uniforms.mode > 0.5) {\n // HBAO mode: 8 directions \u00D7 4 steps\n let hbaoResult = hbaoOcclusion(input.uv, normal, centerDepth, texelSize);\n occlusion = hbaoResult.x;\n } else {\n // Standard hemisphere sampling\n let sampleCount = u32(uniforms.samples);\n var occ = 0.0;\n for (var i = 0u; i < sampleCount; i++) {\n let randSeed = input.uv * dims + vec2f(f32(i) * 7.0, f32(i) * 13.0);\n var sampleDir = normalize(hash3(randSeed));\n if (dot(sampleDir, normal) < 0.0) {\n sampleDir = -sampleDir;\n }\n let scale = f32(i + 1u) / f32(sampleCount);\n let sampleOffset = sampleDir * uniforms.radius * mix(0.1, 1.0, scale * scale);\n let sampleUV = input.uv + sampleOffset.xy * texelSize * 8.0;\n let sampleDepth = textureSample(depthTexture, texSampler, sampleUV).r;\n let rangeCheck = smoothstep(0.0, 1.0,\n uniforms.falloff / abs(centerDepth - sampleDepth + 0.0001));\n if (sampleDepth < centerDepth - uniforms.bias) {\n occ += rangeCheck;\n }\n }\n occlusion = 1.0 - pow(occ / f32(sampleCount), uniforms.power);\n }\n\n // Spatial denoise pass (applied inline for simplicity)\n if (uniforms.spatialDenoise > 0.5) {\n // Approximate denoise by blending with neighbors\n var blurred = occlusion;\n var tw = 1.0;\n for (var dy = -1; dy <= 1; dy++) {\n for (var dx = -1; dx <= 1; dx++) {\n if (dx == 0 && dy == 0) { continue; }\n let off = vec2f(f32(dx), f32(dy)) * texelSize;\n let sd = textureSample(depthTexture, texSampler, input.uv + off).r;\n let dw = exp(-abs(centerDepth - sd) * 50.0);\n let sn = reconstructNormal(input.uv + off, texelSize);\n let nw = max(dot(normal, sn), 0.0);\n let w = dw * nw;\n blurred += occlusion * w; // Approximation: use same occlusion\n tw += w;\n }\n }\n occlusion = blurred / tw;\n }\n\n return vec4f(color.rgb * occlusion, color.a);\n}\n";
3132
+ /**
3133
+ * Fog shader
3134
+ * Supports linear, exponential, and exponential-squared fog with height falloff.
3135
+ * mode: 0 = linear, 1 = exponential, 2 = exponential-squared
3136
+ */
3137
+ declare const FOG_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct FogUniforms {\n color: vec3f,\n density: f32,\n start: f32,\n end: f32,\n height: f32,\n heightFalloff: f32,\n mode: f32,\n padding: vec3f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: FogUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n\n@fragment\nfn fs_fog(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n let depth = textureSample(depthTexture, texSampler, input.uv).r;\n\n // Compute fog factor based on mode\n var fogFactor = 0.0;\n let mode = u32(uniforms.mode);\n if (mode == 0u) {\n // Linear fog\n fogFactor = clamp((uniforms.end - depth) / (uniforms.end - uniforms.start), 0.0, 1.0);\n } else if (mode == 1u) {\n // Exponential fog\n fogFactor = exp(-uniforms.density * depth);\n } else {\n // Exponential-squared fog\n let d = uniforms.density * depth;\n fogFactor = exp(-d * d);\n }\n\n // Height-based attenuation\n let heightUV = 1.0 - input.uv.y; // screen-space approximation of world height\n let heightFactor = exp(-max(heightUV - uniforms.height, 0.0) * uniforms.heightFalloff);\n fogFactor = mix(fogFactor, 1.0, 1.0 - heightFactor);\n\n let foggedColor = mix(uniforms.color, color.rgb, fogFactor);\n return vec4f(foggedColor, color.a);\n}\n";
3138
+ /**
3139
+ * Motion blur shader
3140
+ * Samples along per-pixel velocity vector from a velocity buffer.
3141
+ */
3142
+ declare const MOTION_BLUR_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct MotionBlurUniforms {\n samples: f32,\n velocityScale: f32,\n maxVelocity: f32,\n intensity: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: MotionBlurUniforms;\n@group(0) @binding(3) var velocityTexture: texture_2d<f32>;\n\n@fragment\nfn fs_motionblur(input: VertexOutput) -> @location(0) vec4f {\n let velocity = textureSample(velocityTexture, texSampler, input.uv).rg;\n\n // Scale and clamp velocity\n var vel = velocity * uniforms.velocityScale;\n let speed = length(vel);\n if (speed > uniforms.maxVelocity) {\n vel = vel * (uniforms.maxVelocity / speed);\n }\n\n let sampleCount = u32(uniforms.samples);\n var color = textureSample(inputTexture, texSampler, input.uv);\n var totalWeight = 1.0;\n\n for (var i = 1u; i <= sampleCount; i++) {\n let t = (f32(i) / f32(sampleCount)) - 0.5;\n let sampleUV = input.uv + vel * t;\n let sampleColor = textureSample(inputTexture, texSampler, sampleUV);\n let w = 1.0 - abs(t) * 2.0; // Center-weighted\n color += sampleColor * w;\n totalWeight += w;\n }\n\n let blurred = color / totalWeight;\n let original = textureSample(inputTexture, texSampler, input.uv);\n return mix(original, blurred, uniforms.intensity);\n}\n";
3143
+ /**
3144
+ * Color grading shader
3145
+ */
3146
+ declare const COLOR_GRADE_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct ColorGradeUniforms {\n shadows: vec3f,\n shadowsOffset: f32,\n midtones: vec3f,\n highlightsOffset: f32,\n highlights: vec3f,\n hueShift: f32,\n temperature: f32,\n tint: f32,\n intensity: f32,\n lutIntensity: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: ColorGradeUniforms;\n\n// RGB to HSL conversion\nfn rgbToHsl(c: vec3f) -> vec3f {\n let cMax = max(max(c.r, c.g), c.b);\n let cMin = min(min(c.r, c.g), c.b);\n let delta = cMax - cMin;\n\n var h = 0.0;\n var s = 0.0;\n let l = (cMax + cMin) / 2.0;\n\n if (delta > 0.0) {\n s = select(delta / (2.0 - cMax - cMin), delta / (cMax + cMin), l < 0.5);\n\n if (cMax == c.r) {\n h = (c.g - c.b) / delta + select(0.0, 6.0, c.g < c.b);\n } else if (cMax == c.g) {\n h = (c.b - c.r) / delta + 2.0;\n } else {\n h = (c.r - c.g) / delta + 4.0;\n }\n h /= 6.0;\n }\n\n return vec3f(h, s, l);\n}\n\nfn hue2rgb(p: f32, q: f32, t: f32) -> f32 {\n var tt = t;\n if (tt < 0.0) { tt += 1.0; }\n if (tt > 1.0) { tt -= 1.0; }\n if (tt < 1.0/6.0) { return p + (q - p) * 6.0 * tt; }\n if (tt < 1.0/2.0) { return q; }\n if (tt < 2.0/3.0) { return p + (q - p) * (2.0/3.0 - tt) * 6.0; }\n return p;\n}\n\nfn hslToRgb(hsl: vec3f) -> vec3f {\n if (hsl.y == 0.0) {\n return vec3f(hsl.z);\n }\n\n let q = select(hsl.z + hsl.y - hsl.z * hsl.y, hsl.z * (1.0 + hsl.y), hsl.z < 0.5);\n let p = 2.0 * hsl.z - q;\n\n return vec3f(\n hue2rgb(p, q, hsl.x + 1.0/3.0),\n hue2rgb(p, q, hsl.x),\n hue2rgb(p, q, hsl.x - 1.0/3.0)\n );\n}\n\n// Temperature/tint adjustment\nfn adjustTemperature(color: vec3f, temp: f32, tint: f32) -> vec3f {\n var result = color;\n // Warm (positive) = more red, less blue\n result.r += temp * 0.1;\n result.b -= temp * 0.1;\n // Tint: positive = more green\n result.g += tint * 0.1;\n return clamp(result, vec3f(0.0), vec3f(1.0));\n}\n\n@fragment\nfn fs_colorgrade(input: VertexOutput) -> @location(0) vec4f {\n var color = textureSample(inputTexture, texSampler, input.uv).rgb;\n\n let lum = luminance(color);\n\n // Shadows/Midtones/Highlights\n let shadowWeight = 1.0 - smoothstep(0.0, 0.33, lum);\n let highlightWeight = smoothstep(0.66, 1.0, lum);\n let midtoneWeight = 1.0 - shadowWeight - highlightWeight;\n\n color += uniforms.shadows * shadowWeight;\n color += uniforms.midtones * midtoneWeight;\n color += uniforms.highlights * highlightWeight;\n\n // Hue shift\n if (abs(uniforms.hueShift) > 0.001) {\n var hsl = rgbToHsl(color);\n hsl.x = fract(hsl.x + uniforms.hueShift);\n color = hslToRgb(hsl);\n }\n\n // Temperature and tint\n color = adjustTemperature(color, uniforms.temperature, uniforms.tint);\n\n return vec4f(color, 1.0);\n}\n";
3147
+ /**
3148
+ * Blit/copy shader for simple texture copies
3149
+ */
3150
+ declare const BLIT_SHADER = "\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n\n@fragment\nfn fs_blit(input: VertexOutput) -> @location(0) vec4f {\n return textureSample(inputTexture, texSampler, input.uv);\n}\n";
3151
+ /**
3152
+ * Caustics overlay shader
3153
+ * Projects animated underwater caustic patterns onto the scene.
3154
+ * Uses dual-layer Voronoi for realistic interference.
3155
+ */
3156
+ declare const CAUSTICS_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct CausticsUniforms {\n intensity: f32,\n scale: f32,\n speed: f32,\n time: f32,\n color: vec3f,\n depthFade: f32,\n waterLevel: f32,\n dispersion: f32,\n foamIntensity: f32,\n shadowStrength: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: CausticsUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n\nfn voronoiDist(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n var md = 1.0;\n for (var y = -1; y <= 1; y++) {\n for (var x = -1; x <= 1; x++) {\n let n = vec2f(f32(x), f32(y));\n let h1 = fract(sin(dot(i + n, vec2f(127.1, 311.7))) * 43758.5453);\n let h2 = fract(sin(dot(i + n, vec2f(269.5, 183.3))) * 43758.5453);\n let pt = n + vec2f(h1, h2) - f;\n md = min(md, dot(pt, pt));\n }\n }\n return sqrt(md);\n}\n\n// Refractive caustic with IoR-based convergence\nfn refractiveCausticPP(uv: vec2f, time: f32, scale: f32, ior: f32) -> f32 {\n let eps = 0.01;\n let h0 = voronoiDist(uv * scale + vec2f(time * 0.3, time * 0.7));\n let hx = voronoiDist((uv + vec2f(eps, 0.0)) * scale + vec2f(time * 0.3, time * 0.7));\n let hy = voronoiDist((uv + vec2f(0.0, eps)) * scale + vec2f(time * 0.3, time * 0.7));\n let grad = vec2f(hx - h0, hy - h0) / eps;\n let refracted = grad * (1.0 / ior - 1.0);\n let convergence = voronoiDist((uv + refracted * 0.1) * scale * 1.3 + vec2f(-time * 0.5, time * 0.4));\n return pow(1.0 - convergence, 4.0);\n}\n\n// Turbulence-driven foam\nfn foamNoise(uv: vec2f, time: f32, scale: f32) -> f32 {\n let n1 = fract(sin(dot(floor(uv * scale * 4.0), vec2f(127.1, 311.7))) * 43758.5453);\n let n2 = fract(sin(dot(floor(uv * scale * 8.0 + vec2f(time * 0.5, 0.0)), vec2f(269.5, 183.3))) * 43758.5453);\n let turbulence = abs(n1 * 2.0 - 1.0) + abs(n2 * 2.0 - 1.0) * 0.5;\n return smoothstep(0.8, 1.2, turbulence);\n}\n\n@fragment\nfn fs_caustics(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n let depth = textureSample(depthTexture, texSampler, input.uv).r;\n\n let worldY = 1.0 - input.uv.y;\n if (worldY > uniforms.waterLevel) {\n return color;\n }\n\n let depthFactor = exp(-depth * uniforms.depthFade);\n var causticColor = vec3f(0.0);\n\n if (uniforms.dispersion > 0.001) {\n // Chromatic dispersion: separate R/G/B with different IoR\n let baseIoR = 1.33;\n let t = uniforms.time * uniforms.speed;\n let rC = refractiveCausticPP(input.uv, t, uniforms.scale, baseIoR - uniforms.dispersion);\n let gC = refractiveCausticPP(input.uv, t, uniforms.scale, baseIoR);\n let bC = refractiveCausticPP(input.uv, t, uniforms.scale, baseIoR + uniforms.dispersion);\n causticColor = vec3f(rC, gC, bC) * uniforms.color * uniforms.intensity * depthFactor;\n } else {\n // Standard dual-layer caustics\n let uv1 = input.uv * uniforms.scale + vec2f(uniforms.time * uniforms.speed * 0.3, uniforms.time * uniforms.speed * 0.7);\n let uv2 = input.uv * uniforms.scale * 1.3 + vec2f(-uniforms.time * uniforms.speed * 0.5, uniforms.time * uniforms.speed * 0.4);\n let c1 = voronoiDist(uv1);\n let c2 = voronoiDist(uv2);\n let caustic = pow(1.0 - c1, 3.0) * pow(1.0 - c2, 3.0);\n causticColor = uniforms.color * caustic * uniforms.intensity * depthFactor;\n }\n\n // Foam overlay\n let foam = foamNoise(input.uv, uniforms.time * uniforms.speed, uniforms.scale) * uniforms.foamIntensity;\n\n // Caustic shadows: darken where caustics are absent\n let causticLum = dot(causticColor, vec3f(0.333));\n let shadow = mix(1.0, 1.0 - uniforms.shadowStrength, (1.0 - causticLum) * depthFactor);\n\n let result = color.rgb * shadow + causticColor + vec3f(foam);\n return vec4f(result, color.a);\n}\n";
3157
+ /**
3158
+ * Screen-Space Reflections (SSR) shader
3159
+ * Ray-marches in screen space to find reflections.
3160
+ * Uses hierarchical tracing with binary refinement.
3161
+ */
3162
+ declare const SSR_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct SSRUniforms {\n maxSteps: f32,\n stepSize: f32,\n thickness: f32,\n roughnessFade: f32,\n edgeFade: f32,\n intensity: f32,\n roughnessBlur: f32,\n fresnelStrength: f32,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: SSRUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n@group(0) @binding(4) var normalTexture: texture_2d<f32>;\n\n@fragment\nfn fs_ssr(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n let depth = textureSample(depthTexture, texSampler, input.uv).r;\n let texSize = vec2f(textureDimensions(inputTexture));\n let texel = 1.0 / texSize;\n\n // Reconstruct normal from depth\n let dc = depth;\n let dl = textureSample(depthTexture, texSampler, input.uv - vec2f(texel.x, 0.0)).r;\n let dr = textureSample(depthTexture, texSampler, input.uv + vec2f(texel.x, 0.0)).r;\n let db = textureSample(depthTexture, texSampler, input.uv - vec2f(0.0, texel.y)).r;\n let dt = textureSample(depthTexture, texSampler, input.uv + vec2f(0.0, texel.y)).r;\n let normal = normalize(vec3f(dl - dr, db - dt, 2.0 * texel.x));\n\n // View direction (simplified \u2014 assumes forward-facing camera)\n let viewDir = normalize(vec3f(input.uv * 2.0 - 1.0, -1.0));\n\n // Reflect view around normal\n let reflectDir = reflect(viewDir, normal);\n let stepDir = reflectDir.xy * uniforms.stepSize;\n\n var hitUV = input.uv;\n var hit = false;\n let steps = i32(uniforms.maxSteps);\n\n for (var i = 1; i <= steps; i++) {\n hitUV += stepDir;\n\n // Bounds check\n if (hitUV.x < 0.0 || hitUV.x > 1.0 || hitUV.y < 0.0 || hitUV.y > 1.0) { break; }\n\n let sampleDepth = textureSample(depthTexture, texSampler, hitUV).r;\n let expectedDepth = depth + f32(i) * uniforms.stepSize;\n\n if (expectedDepth > sampleDepth && expectedDepth - sampleDepth < uniforms.thickness) {\n hit = true;\n\n // Binary refinement (4 steps)\n var refineStep = stepDir * 0.5;\n for (var j = 0; j < 4; j++) {\n hitUV -= refineStep;\n let rd = textureSample(depthTexture, texSampler, hitUV).r;\n let re = depth + length(hitUV - input.uv) / uniforms.stepSize * uniforms.stepSize;\n if (re > rd) {\n hitUV += refineStep;\n }\n refineStep *= 0.5;\n }\n break;\n }\n }\n\n if (!hit) { return color; }\n\n // Roughness blur: golden-angle 8-sample blur at hit point scaled by roughness\n var reflectionColor = vec3f(0.0);\n if (uniforms.roughnessBlur > 0.001) {\n let blurRadius = uniforms.roughnessBlur * 0.01;\n let goldenAngle = 2.399963;\n var totalW = 0.0;\n for (var s = 0; s < 8; s++) {\n let angle = f32(s) * goldenAngle;\n let r = sqrt(f32(s + 1) / 8.0) * blurRadius;\n let blurOffset = vec2f(cos(angle), sin(angle)) * r;\n let sampleC = textureSample(inputTexture, texSampler, hitUV + blurOffset).rgb;\n let w = 1.0 - f32(s) / 8.0;\n reflectionColor += sampleC * w;\n totalW += w;\n }\n reflectionColor /= totalW;\n } else {\n reflectionColor = textureSample(inputTexture, texSampler, hitUV).rgb;\n }\n\n // Schlick Fresnel weighting\n let cosTheta = max(dot(-viewDir, normal), 0.0);\n let f0 = 0.04; // dielectric\n let fresnel = f0 + (1.0 - f0) * pow(1.0 - cosTheta, 5.0);\n let fresnelWeight = mix(1.0, fresnel, uniforms.fresnelStrength);\n\n // Edge fade\n let edgeDist = max(abs(hitUV.x - 0.5), abs(hitUV.y - 0.5)) * 2.0;\n let edgeFade = 1.0 - pow(clamp(edgeDist, 0.0, 1.0), uniforms.edgeFade);\n\n // Distance fade\n let travelDist = length(hitUV - input.uv);\n let distFade = 1.0 - clamp(travelDist * 2.0, 0.0, 1.0);\n\n let reflectionMask = edgeFade * distFade * uniforms.intensity * fresnelWeight;\n return vec4f(mix(color.rgb, reflectionColor, reflectionMask), color.a);\n}\n";
3163
+ /**
3164
+ * Screen-Space Global Illumination (SSGI) shader
3165
+ * Approximates indirect lighting by sampling nearby pixels' colors
3166
+ * and treating them as bounce light sources.
3167
+ */
3168
+ declare const SSGI_SHADER = "\n\n// Luminance calculation (Rec. 709)\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n// sRGB to linear conversion\nfn srgbToLinear(color: vec3f) -> vec3f {\n return pow(color, vec3f(2.2));\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(color: vec3f) -> vec3f {\n return pow(color, vec3f(1.0 / 2.2));\n}\n\n// Hash function for noise\nfn hash(p: vec2f) -> f32 {\n let k = vec2f(0.3183099, 0.3678794);\n let x = p * k + k.yx;\n return fract(16.0 * k.x * fract(x.x * x.y * (x.x + x.y)));\n}\n\n// Simple 2D noise\nfn noise2D(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(hash(i + vec2f(0.0, 0.0)), hash(i + vec2f(1.0, 0.0)), u.x),\n mix(hash(i + vec2f(0.0, 1.0)), hash(i + vec2f(1.0, 1.0)), u.x),\n u.y\n );\n}\n\n\nstruct SSGIUniforms {\n radius: f32,\n samples: f32,\n bounceIntensity: f32,\n falloff: f32,\n time: f32,\n intensity: f32,\n temporalBlend: f32,\n spatialDenoise: f32,\n multiBounce: f32,\n padding: vec3f,\n}\n\n@group(0) @binding(0) var texSampler: sampler;\n@group(0) @binding(1) var inputTexture: texture_2d<f32>;\n@group(0) @binding(2) var<uniform> uniforms: SSGIUniforms;\n@group(0) @binding(3) var depthTexture: texture_2d<f32>;\n\n@fragment\nfn fs_ssgi(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSample(inputTexture, texSampler, input.uv);\n let centerDepth = textureSample(depthTexture, texSampler, input.uv).r;\n let texSize = vec2f(textureDimensions(inputTexture));\n let texel = 1.0 / texSize;\n\n // Reconstruct normal from depth\n let dl = textureSample(depthTexture, texSampler, input.uv - vec2f(texel.x, 0.0)).r;\n let dr = textureSample(depthTexture, texSampler, input.uv + vec2f(texel.x, 0.0)).r;\n let db = textureSample(depthTexture, texSampler, input.uv - vec2f(0.0, texel.y)).r;\n let dt = textureSample(depthTexture, texSampler, input.uv + vec2f(0.0, texel.y)).r;\n let normal = normalize(vec3f(dl - dr, db - dt, 2.0 * texel.x));\n\n var indirect = vec3f(0.0);\n let sampleCount = i32(uniforms.samples);\n let goldenAngle = 2.399963;\n\n for (var i = 0; i < sampleCount; i++) {\n let fi = f32(i);\n let r = sqrt(fi / uniforms.samples) * uniforms.radius;\n let theta = fi * goldenAngle + uniforms.time * 0.1; // Slight temporal jitter\n let offset = vec2f(cos(theta), sin(theta)) * r * texel * 8.0;\n let sampleUV = input.uv + offset;\n\n let sampleColor = textureSample(inputTexture, texSampler, sampleUV).rgb;\n let sampleDepth = textureSample(depthTexture, texSampler, sampleUV).r;\n\n // Weight by depth proximity (nearby surfaces contribute more)\n let depthDiff = abs(centerDepth - sampleDepth);\n let depthWeight = exp(-depthDiff * uniforms.falloff * 10.0);\n\n // Cosine weight: approximate normal-based falloff\n let sampleDir = normalize(vec3f(offset, 0.05));\n let cosWeight = max(dot(sampleDir, normal), 0.0);\n\n indirect += sampleColor * depthWeight * cosWeight;\n }\n\n indirect /= uniforms.samples;\n indirect *= uniforms.bounceIntensity;\n\n // Multi-bounce approximation: self-illumination feedback\n if (uniforms.multiBounce > 0.001) {\n indirect *= (1.0 + uniforms.multiBounce * luminance(indirect));\n }\n\n // Spatial denoise: 3\u00D73 edge-stopping cross-bilateral filter\n if (uniforms.spatialDenoise > 0.5) {\n var denoised = indirect;\n var tw = 1.0;\n for (var dy = -1; dy <= 1; dy++) {\n for (var dx = -1; dx <= 1; dx++) {\n if (dx == 0 && dy == 0) { continue; }\n let off = vec2f(f32(dx), f32(dy)) * texel;\n let sd = textureSample(depthTexture, texSampler, input.uv + off).r;\n // Depth weight\n let dw = exp(-abs(centerDepth - sd) * uniforms.falloff * 10.0);\n // Normal weight\n let snl = textureSample(depthTexture, texSampler, input.uv + off - vec2f(texel.x, 0.0)).r;\n let snr = textureSample(depthTexture, texSampler, input.uv + off + vec2f(texel.x, 0.0)).r;\n let snb = textureSample(depthTexture, texSampler, input.uv + off - vec2f(0.0, texel.y)).r;\n let snt = textureSample(depthTexture, texSampler, input.uv + off + vec2f(0.0, texel.y)).r;\n let sn = normalize(vec3f(snl - snr, snb - snt, 2.0 * texel.x));\n let nw = max(dot(normal, sn), 0.0);\n let w = dw * nw;\n // Sample neighbor's indirect (approximation: use color luminance ratio)\n let neighborColor = textureSample(inputTexture, texSampler, input.uv + off).rgb;\n denoised += neighborColor * uniforms.bounceIntensity * w * 0.5;\n tw += w;\n }\n }\n indirect = denoised / tw;\n }\n\n var result = color.rgb + indirect * uniforms.intensity;\n\n // Temporal blend: mix with previous frame color (approximation using current frame offset)\n if (uniforms.temporalBlend > 0.001) {\n // Approximate temporal reprojection by blending with slightly jittered sample\n let temporalUV = input.uv + vec2f(sin(uniforms.time * 31.0), cos(uniforms.time * 37.0)) * texel * 0.5;\n let prevColor = textureSample(inputTexture, texSampler, temporalUV).rgb;\n result = mix(result, prevColor + indirect * uniforms.intensity * 0.5, uniforms.temporalBlend * 0.3);\n }\n\n return vec4f(result, color.a);\n}\n";
3169
+ /**
3170
+ * Build a complete effect shader by combining vertex shader,
3171
+ * utilities, and the effect's fragment shader.
3172
+ */
3173
+ declare function buildEffectShader(fragmentShader: string): string;
3174
+
3175
+ /**
3176
+ * PostProcessPipeline.ts
3177
+ *
3178
+ * Manages a chain of post-processing effects, handling render targets
3179
+ * and ping-pong buffering for efficient GPU processing.
3180
+ *
3181
+ * @module render/postprocess
3182
+ */
3183
+
3184
+ /**
3185
+ * Default pipeline configuration
3186
+ */
3187
+ declare const DEFAULT_PIPELINE_CONFIG: IPostProcessPipelineConfig;
3188
+ /**
3189
+ * Post-processing pipeline manager
3190
+ */
3191
+ declare class PostProcessPipeline {
3192
+ private device;
3193
+ private config;
3194
+ private effects;
3195
+ private renderTargets;
3196
+ private pingPongTargets;
3197
+ private currentWidth;
3198
+ private currentHeight;
3199
+ private _initialized;
3200
+ private frameCount;
3201
+ constructor(config?: Partial<IPostProcessPipelineConfig>);
3202
+ /**
3203
+ * Check if pipeline is initialized
3204
+ */
3205
+ get initialized(): boolean;
3206
+ /**
3207
+ * Get current configuration
3208
+ */
3209
+ getConfig(): IPostProcessPipelineConfig;
3210
+ /**
3211
+ * Get list of active effects
3212
+ */
3213
+ getEffects(): PostProcessEffect[];
3214
+ /**
3215
+ * Get effect by name
3216
+ */
3217
+ getEffect(name: string): PostProcessEffect | undefined;
3218
+ /**
3219
+ * Get effect by type
3220
+ */
3221
+ getEffectByType(type: PostProcessEffectType): PostProcessEffect | undefined;
3222
+ /**
3223
+ * Initialize the pipeline with GPU device
3224
+ */
3225
+ initialize(device: GPUDevice, width: number, height: number): Promise<void>;
3226
+ /**
3227
+ * Create or recreate render targets
3228
+ */
3229
+ private createRenderTargets;
3230
+ /**
3231
+ * Dispose render targets
3232
+ */
3233
+ private disposeRenderTargets;
3234
+ /**
3235
+ * Resize render targets
3236
+ */
3237
+ resize(width: number, height: number): Promise<void>;
3238
+ /**
3239
+ * Add an effect to the pipeline
3240
+ */
3241
+ addEffect(config: IEffectConfig): Promise<PostProcessEffect>;
3242
+ /**
3243
+ * Remove an effect from the pipeline
3244
+ */
3245
+ removeEffect(nameOrType: string | PostProcessEffectType): boolean;
3246
+ /**
3247
+ * Reorder effects
3248
+ */
3249
+ reorderEffects(order: string[]): void;
3250
+ /**
3251
+ * Update effect parameters
3252
+ */
3253
+ updateEffectParams(nameOrType: string | PostProcessEffectType, params: Partial<EffectParams>): boolean;
3254
+ /**
3255
+ * Enable/disable an effect
3256
+ */
3257
+ setEffectEnabled(nameOrType: string | PostProcessEffectType, enabled: boolean): boolean;
3258
+ /**
3259
+ * Execute the post-processing pipeline
3260
+ *
3261
+ * @param commandEncoder GPU command encoder
3262
+ * @param inputView Input texture view (scene render)
3263
+ * @param outputView Output texture view (swap chain)
3264
+ * @param frameData Frame timing and camera data
3265
+ */
3266
+ render(commandEncoder: GPUCommandEncoder, inputView: GPUTextureView, outputView: GPUTextureView, frameData?: Partial<IFrameData>): void;
3267
+ /**
3268
+ * Create temporary render target wrapper for output view
3269
+ */
3270
+ private createTempTarget;
3271
+ /**
3272
+ * Copy texture using a blit pass
3273
+ */
3274
+ private copyTexture;
3275
+ /**
3276
+ * Copy input view to a render target
3277
+ */
3278
+ private copyToTarget;
3279
+ /**
3280
+ * Create a preset pipeline configuration
3281
+ */
3282
+ static createPreset(preset: 'minimal' | 'standard' | 'cinematic' | 'performance'): Partial<IPostProcessPipelineConfig>;
3283
+ /**
3284
+ * Dispose all resources
3285
+ */
3286
+ dispose(): void;
3287
+ /**
3288
+ * Get performance statistics
3289
+ */
3290
+ getStats(): {
3291
+ effectCount: number;
3292
+ enabledEffects: number;
3293
+ renderTargetCount: number;
3294
+ estimatedMemoryMB: number;
3295
+ };
3296
+ }
3297
+ /**
3298
+ * Create a post-processing pipeline with common presets
3299
+ */
3300
+ declare function createPostProcessPipeline(preset?: 'minimal' | 'standard' | 'cinematic' | 'performance', customConfig?: Partial<IPostProcessPipelineConfig>): PostProcessPipeline;
3301
+ /**
3302
+ * Quick helper to create a standard HDR pipeline
3303
+ */
3304
+ declare function createHDRPipeline(): PostProcessPipeline;
3305
+ /**
3306
+ * Quick helper to create a minimal LDR pipeline
3307
+ */
3308
+ declare function createLDRPipeline(): PostProcessPipeline;
3309
+
3310
+ /**
3311
+ * Post-Processing Module
3312
+ *
3313
+ * WebGPU-based post-processing effects for the HoloScript renderer.
3314
+ *
3315
+ * @module render/postprocess
3316
+ *
3317
+ * @example
3318
+ * ```ts
3319
+ * import { createHDRPipeline, PostProcessPipeline } from '@holoscript/core';
3320
+ *
3321
+ * // Create with preset
3322
+ * const pipeline = createHDRPipeline();
3323
+ *
3324
+ * // Or create custom
3325
+ * const custom = new PostProcessPipeline({
3326
+ * hdrEnabled: true,
3327
+ * effects: [
3328
+ * { type: 'bloom', params: { intensity: 0.8 } },
3329
+ * { type: 'tonemap', params: { operator: 'aces' } },
3330
+ * { type: 'fxaa' },
3331
+ * ]
3332
+ * });
3333
+ *
3334
+ * // Initialize with WebGPU device
3335
+ * await pipeline.initialize(device, width, height);
3336
+ *
3337
+ * // In render loop
3338
+ * pipeline.render(commandEncoder, sceneTexture, swapChainTexture, {
3339
+ * time: performance.now() / 1000,
3340
+ * deltaTime: dt,
3341
+ * });
3342
+ * ```
3343
+ */
3344
+
3345
+ declare const index$1_BLIT_SHADER: typeof BLIT_SHADER;
3346
+ declare const index$1_BLOOM_SHADER: typeof BLOOM_SHADER;
3347
+ type index$1_BlendMode = BlendMode;
3348
+ type index$1_BloomEffect = BloomEffect;
3349
+ declare const index$1_BloomEffect: typeof BloomEffect;
3350
+ declare const index$1_CAUSTICS_SHADER: typeof CAUSTICS_SHADER;
3351
+ declare const index$1_CHROMATIC_ABERRATION_SHADER: typeof CHROMATIC_ABERRATION_SHADER;
3352
+ declare const index$1_COLOR_GRADE_SHADER: typeof COLOR_GRADE_SHADER;
3353
+ type index$1_CausticsEffect = CausticsEffect;
3354
+ declare const index$1_CausticsEffect: typeof CausticsEffect;
3355
+ type index$1_ChromaticAberrationEffect = ChromaticAberrationEffect;
3356
+ declare const index$1_ChromaticAberrationEffect: typeof ChromaticAberrationEffect;
3357
+ declare const index$1_DEFAULT_PARAMS: typeof DEFAULT_PARAMS;
3358
+ declare const index$1_DEFAULT_PIPELINE_CONFIG: typeof DEFAULT_PIPELINE_CONFIG;
3359
+ declare const index$1_DOF_SHADER: typeof DOF_SHADER;
3360
+ type index$1_EffectParams = EffectParams;
3361
+ declare const index$1_FILM_GRAIN_SHADER: typeof FILM_GRAIN_SHADER;
3362
+ declare const index$1_FOG_SHADER: typeof FOG_SHADER;
3363
+ declare const index$1_FULLSCREEN_VERTEX_SHADER: typeof FULLSCREEN_VERTEX_SHADER;
3364
+ type index$1_FXAAEffect = FXAAEffect;
3365
+ declare const index$1_FXAAEffect: typeof FXAAEffect;
3366
+ type index$1_FXAAQuality = FXAAQuality;
3367
+ declare const index$1_FXAA_SHADER: typeof FXAA_SHADER;
3368
+ type index$1_FilmGrainEffect = FilmGrainEffect;
3369
+ declare const index$1_FilmGrainEffect: typeof FilmGrainEffect;
3370
+ type index$1_IBaseEffectParams = IBaseEffectParams;
3371
+ type index$1_IBloomParams = IBloomParams;
3372
+ type index$1_ICausticsParams = ICausticsParams;
3373
+ type index$1_IChromaticAberrationParams = IChromaticAberrationParams;
3374
+ type index$1_IColorGradeParams = IColorGradeParams;
3375
+ type index$1_ICustomEffectParams = ICustomEffectParams;
3376
+ type index$1_IDOFParams = IDOFParams;
3377
+ type index$1_IEffectConfig = IEffectConfig;
3378
+ type index$1_IEffectRenderContext = IEffectRenderContext;
3379
+ type index$1_IFXAAParams = IFXAAParams;
3380
+ type index$1_IFilmGrainParams = IFilmGrainParams;
3381
+ type index$1_IFogParams = IFogParams;
3382
+ type index$1_IFrameData = IFrameData;
3383
+ type index$1_IMotionBlurParams = IMotionBlurParams;
3384
+ type index$1_IPostProcessPipelineConfig = IPostProcessPipelineConfig;
3385
+ type index$1_IRenderTarget = IRenderTarget;
3386
+ type index$1_IRenderTargetConfig = IRenderTargetConfig;
3387
+ type index$1_ISSAOParams = ISSAOParams;
3388
+ type index$1_ISSGIParams = ISSGIParams;
3389
+ type index$1_ISSRParams = ISSRParams;
3390
+ type index$1_ISharpenParams = ISharpenParams;
3391
+ type index$1_IToneMapParams = IToneMapParams;
3392
+ type index$1_IVignetteParams = IVignetteParams;
3393
+ declare const index$1_MOTION_BLUR_SHADER: typeof MOTION_BLUR_SHADER;
3394
+ type index$1_PostProcessEffect = PostProcessEffect;
3395
+ declare const index$1_PostProcessEffect: typeof PostProcessEffect;
3396
+ type index$1_PostProcessEffectType = PostProcessEffectType;
3397
+ type index$1_PostProcessPipeline = PostProcessPipeline;
3398
+ declare const index$1_PostProcessPipeline: typeof PostProcessPipeline;
3399
+ declare const index$1_SHADER_UTILS: typeof SHADER_UTILS;
3400
+ declare const index$1_SHARPEN_SHADER: typeof SHARPEN_SHADER;
3401
+ type index$1_SSAOEffect = SSAOEffect;
3402
+ declare const index$1_SSAOEffect: typeof SSAOEffect;
3403
+ declare const index$1_SSAO_SHADER: typeof SSAO_SHADER;
3404
+ type index$1_SSGIEffect = SSGIEffect;
3405
+ declare const index$1_SSGIEffect: typeof SSGIEffect;
3406
+ declare const index$1_SSGI_SHADER: typeof SSGI_SHADER;
3407
+ type index$1_SSREffect = SSREffect;
3408
+ declare const index$1_SSREffect: typeof SSREffect;
3409
+ declare const index$1_SSR_SHADER: typeof SSR_SHADER;
3410
+ type index$1_SharpenEffect = SharpenEffect;
3411
+ declare const index$1_SharpenEffect: typeof SharpenEffect;
3412
+ declare const index$1_TONEMAP_SHADER: typeof TONEMAP_SHADER;
3413
+ type index$1_ToneMapEffect = ToneMapEffect;
3414
+ declare const index$1_ToneMapEffect: typeof ToneMapEffect;
3415
+ type index$1_ToneMapOperator = ToneMapOperator;
3416
+ declare const index$1_UNIFORM_SIZES: typeof UNIFORM_SIZES;
3417
+ declare const index$1_VIGNETTE_SHADER: typeof VIGNETTE_SHADER;
3418
+ type index$1_VignetteEffect = VignetteEffect;
3419
+ declare const index$1_VignetteEffect: typeof VignetteEffect;
3420
+ declare const index$1_buildEffectShader: typeof buildEffectShader;
3421
+ declare const index$1_createEffect: typeof createEffect;
3422
+ declare const index$1_createHDRPipeline: typeof createHDRPipeline;
3423
+ declare const index$1_createLDRPipeline: typeof createLDRPipeline;
3424
+ declare const index$1_createPostProcessPipeline: typeof createPostProcessPipeline;
3425
+ declare const index$1_getDefaultParams: typeof getDefaultParams;
3426
+ declare const index$1_mergeParams: typeof mergeParams;
3427
+ declare const index$1_validateParams: typeof validateParams;
3428
+ declare namespace index$1 {
3429
+ export { index$1_BLIT_SHADER as BLIT_SHADER, index$1_BLOOM_SHADER as BLOOM_SHADER, type index$1_BlendMode as BlendMode, index$1_BloomEffect as BloomEffect, index$1_CAUSTICS_SHADER as CAUSTICS_SHADER, index$1_CHROMATIC_ABERRATION_SHADER as CHROMATIC_ABERRATION_SHADER, index$1_COLOR_GRADE_SHADER as COLOR_GRADE_SHADER, index$1_CausticsEffect as CausticsEffect, index$1_ChromaticAberrationEffect as ChromaticAberrationEffect, index$1_DEFAULT_PARAMS as DEFAULT_PARAMS, index$1_DEFAULT_PIPELINE_CONFIG as DEFAULT_PIPELINE_CONFIG, index$1_DOF_SHADER as DOF_SHADER, type index$1_EffectParams as EffectParams, index$1_FILM_GRAIN_SHADER as FILM_GRAIN_SHADER, index$1_FOG_SHADER as FOG_SHADER, index$1_FULLSCREEN_VERTEX_SHADER as FULLSCREEN_VERTEX_SHADER, index$1_FXAAEffect as FXAAEffect, type index$1_FXAAQuality as FXAAQuality, index$1_FXAA_SHADER as FXAA_SHADER, index$1_FilmGrainEffect as FilmGrainEffect, type index$1_IBaseEffectParams as IBaseEffectParams, type index$1_IBloomParams as IBloomParams, type index$1_ICausticsParams as ICausticsParams, type index$1_IChromaticAberrationParams as IChromaticAberrationParams, type index$1_IColorGradeParams as IColorGradeParams, type index$1_ICustomEffectParams as ICustomEffectParams, type index$1_IDOFParams as IDOFParams, type index$1_IEffectConfig as IEffectConfig, type index$1_IEffectRenderContext as IEffectRenderContext, type index$1_IFXAAParams as IFXAAParams, type index$1_IFilmGrainParams as IFilmGrainParams, type index$1_IFogParams as IFogParams, type index$1_IFrameData as IFrameData, type index$1_IMotionBlurParams as IMotionBlurParams, type index$1_IPostProcessPipelineConfig as IPostProcessPipelineConfig, type index$1_IRenderTarget as IRenderTarget, type index$1_IRenderTargetConfig as IRenderTargetConfig, type index$1_ISSAOParams as ISSAOParams, type index$1_ISSGIParams as ISSGIParams, type index$1_ISSRParams as ISSRParams, type index$1_ISharpenParams as ISharpenParams, type index$1_IToneMapParams as IToneMapParams, type index$1_IVignetteParams as IVignetteParams, index$1_MOTION_BLUR_SHADER as MOTION_BLUR_SHADER, index$1_PostProcessEffect as PostProcessEffect, type index$1_PostProcessEffectType as PostProcessEffectType, index$1_PostProcessPipeline as PostProcessPipeline, index$1_SHADER_UTILS as SHADER_UTILS, index$1_SHARPEN_SHADER as SHARPEN_SHADER, index$1_SSAOEffect as SSAOEffect, index$1_SSAO_SHADER as SSAO_SHADER, index$1_SSGIEffect as SSGIEffect, index$1_SSGI_SHADER as SSGI_SHADER, index$1_SSREffect as SSREffect, index$1_SSR_SHADER as SSR_SHADER, index$1_SharpenEffect as SharpenEffect, index$1_TONEMAP_SHADER as TONEMAP_SHADER, index$1_ToneMapEffect as ToneMapEffect, type index$1_ToneMapOperator as ToneMapOperator, index$1_UNIFORM_SIZES as UNIFORM_SIZES, index$1_VIGNETTE_SHADER as VIGNETTE_SHADER, index$1_VignetteEffect as VignetteEffect, index$1_buildEffectShader as buildEffectShader, index$1_createEffect as createEffect, index$1_createHDRPipeline as createHDRPipeline, index$1_createLDRPipeline as createLDRPipeline, index$1_createPostProcessPipeline as createPostProcessPipeline, index$1_getDefaultParams as getDefaultParams, index$1_mergeParams as mergeParams, index$1_validateParams as validateParams };
3430
+ }
3431
+
3432
+ /**
3433
+ * Puppeteer-based Headless Chrome Renderer
3434
+ *
3435
+ * Provides headless Chrome rendering capabilities for HoloScript scenes:
3436
+ * - Screenshot capture (PNG, JPEG, WebP)
3437
+ * - PDF generation
3438
+ * - Pre-rendered HTML for SEO/social sharing
3439
+ * - Visual regression testing support
3440
+ * - Animation capture (GIF/video frames)
3441
+ *
3442
+ * @module render/headless/PuppeteerRenderer
3443
+ * @version 1.0.0
3444
+ */
3445
+ interface ScreenshotOptions {
3446
+ /** Output format */
3447
+ format?: 'png' | 'jpeg' | 'webp';
3448
+ /** Quality for JPEG/WebP (0-100) */
3449
+ quality?: number;
3450
+ /** Viewport width */
3451
+ width?: number;
3452
+ /** Viewport height */
3453
+ height?: number;
3454
+ /** Device scale factor for retina screenshots */
3455
+ deviceScaleFactor?: number;
3456
+ /** Take full page screenshot */
3457
+ fullPage?: boolean;
3458
+ /** Transparent background (PNG only) */
3459
+ omitBackground?: boolean;
3460
+ /** Wait for scene to stabilize (ms) */
3461
+ waitForStable?: number;
3462
+ /** Custom wait selector */
3463
+ waitForSelector?: string;
3464
+ /** Capture after N animation frames */
3465
+ captureAfterFrames?: number;
3466
+ }
3467
+ interface PDFOptions {
3468
+ /** Page format */
3469
+ format?: 'A4' | 'Letter' | 'Legal' | 'Tabloid' | 'A3' | 'A5';
3470
+ /** Landscape orientation */
3471
+ landscape?: boolean;
3472
+ /** Print background graphics */
3473
+ printBackground?: boolean;
3474
+ /** Page margins */
3475
+ margin?: {
3476
+ top?: string;
3477
+ right?: string;
3478
+ bottom?: string;
3479
+ left?: string;
3480
+ };
3481
+ /** Scale (0.1 - 2.0) */
3482
+ scale?: number;
3483
+ /** Custom width */
3484
+ width?: string;
3485
+ /** Custom height */
3486
+ height?: string;
3487
+ }
3488
+ interface PrerenderOptions {
3489
+ /** Wait for JavaScript to execute */
3490
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
3491
+ /** Timeout in ms */
3492
+ timeout?: number;
3493
+ /** Strip JavaScript from output */
3494
+ removeScripts?: boolean;
3495
+ /** Inline CSS */
3496
+ inlineStyles?: boolean;
3497
+ /** Add meta tags for SEO */
3498
+ addMetaTags?: boolean;
3499
+ }
3500
+ interface AnimationFrameOptions extends ScreenshotOptions {
3501
+ /** Number of frames to capture */
3502
+ frameCount: number;
3503
+ /** Time between frames in ms */
3504
+ frameInterval?: number;
3505
+ /** Output directory for frames */
3506
+ outputDir?: string;
3507
+ /** Frame filename pattern */
3508
+ filenamePattern?: string;
3509
+ }
3510
+ interface RenderResult {
3511
+ success: boolean;
3512
+ data?: Buffer | string;
3513
+ error?: string;
3514
+ timing?: {
3515
+ navigationMs: number;
3516
+ renderMs: number;
3517
+ captureMs: number;
3518
+ totalMs: number;
3519
+ };
3520
+ metadata?: {
3521
+ width: number;
3522
+ height: number;
3523
+ format: string;
3524
+ size: number;
3525
+ };
3526
+ }
3527
+ interface PuppeteerRendererOptions {
3528
+ /** Puppeteer executable path (chromium) */
3529
+ executablePath?: string;
3530
+ /** Run in headless mode (default: true) */
3531
+ headless?: boolean;
3532
+ /** Browser arguments */
3533
+ args?: string[];
3534
+ /** Default viewport size */
3535
+ defaultViewport?: {
3536
+ width: number;
3537
+ height: number;
3538
+ };
3539
+ /** Timeout for operations in ms */
3540
+ timeout?: number;
3541
+ /** Enable debug logging */
3542
+ debug?: boolean;
3543
+ /** Base URL for the render service */
3544
+ renderServiceUrl?: string;
3545
+ /** Custom Three.js/WebGL version */
3546
+ threeVersion?: string;
3547
+ }
3548
+ /**
3549
+ * PuppeteerRenderer - Headless Chrome renderer for HoloScript scenes
3550
+ *
3551
+ * @example
3552
+ * ```typescript
3553
+ * const renderer = new PuppeteerRenderer();
3554
+ * await renderer.initialize();
3555
+ *
3556
+ * // Take a screenshot of a scene
3557
+ * const result = await renderer.screenshot(holoCode, {
3558
+ * width: 1920,
3559
+ * height: 1080,
3560
+ * format: 'png'
3561
+ * });
3562
+ *
3563
+ * // Generate PDF
3564
+ * const pdf = await renderer.generatePDF(holoCode, { format: 'A4' });
3565
+ *
3566
+ * // Pre-render for SEO
3567
+ * const html = await renderer.prerender(holoCode, { waitUntil: 'networkidle0' });
3568
+ *
3569
+ * await renderer.close();
3570
+ * ```
3571
+ */
3572
+ declare class PuppeteerRenderer {
3573
+ private browser;
3574
+ private options;
3575
+ private initialized;
3576
+ private pagePool;
3577
+ private maxPoolSize;
3578
+ constructor(options?: PuppeteerRendererOptions);
3579
+ /**
3580
+ * Initialize the browser instance
3581
+ */
3582
+ initialize(): Promise<void>;
3583
+ /**
3584
+ * Get or create a page from the pool
3585
+ */
3586
+ private getPage;
3587
+ /**
3588
+ * Return a page to the pool
3589
+ */
3590
+ private releasePage;
3591
+ /**
3592
+ * Ensure browser is initialized
3593
+ */
3594
+ private ensureInitialized;
3595
+ /**
3596
+ * Take a screenshot of a HoloScript scene
3597
+ */
3598
+ screenshot(holoCode: string, options?: ScreenshotOptions): Promise<RenderResult>;
3599
+ /**
3600
+ * Generate a PDF of a HoloScript scene
3601
+ */
3602
+ generatePDF(holoCode: string, options?: PDFOptions): Promise<RenderResult>;
3603
+ /**
3604
+ * Pre-render HoloScript for SEO/social sharing
3605
+ * Returns fully rendered HTML with all JavaScript executed
3606
+ */
3607
+ prerender(holoCode: string, options?: PrerenderOptions): Promise<RenderResult>;
3608
+ /**
3609
+ * Capture animation frames for GIF/video generation
3610
+ */
3611
+ captureAnimationFrames(holoCode: string, options: AnimationFrameOptions): Promise<RenderResult & {
3612
+ frames?: Buffer[];
3613
+ }>;
3614
+ /**
3615
+ * Run visual regression test - compare scene against baseline
3616
+ */
3617
+ visualRegression(holoCode: string, baselineBuffer: Buffer, threshold?: number): Promise<{
3618
+ match: boolean;
3619
+ diffPercentage: number;
3620
+ diffImage?: Buffer;
3621
+ }>;
3622
+ /**
3623
+ * Generate HTML for rendering a HoloScript scene
3624
+ */
3625
+ private generateRenderHTML;
3626
+ /**
3627
+ * Close the browser and cleanup resources
3628
+ */
3629
+ close(): Promise<void>;
3630
+ /**
3631
+ * Check if puppeteer is available
3632
+ */
3633
+ static isAvailable(): Promise<boolean>;
3634
+ /**
3635
+ * Get browser version
3636
+ */
3637
+ getVersion(): Promise<string>;
3638
+ /**
3639
+ * Debug logging
3640
+ */
3641
+ private log;
3642
+ }
3643
+ /**
3644
+ * Convenience function to create and use a renderer
3645
+ */
3646
+ declare function renderScreenshot(holoCode: string, options?: ScreenshotOptions): Promise<RenderResult>;
3647
+ /**
3648
+ * Convenience function to generate PDF
3649
+ */
3650
+ declare function renderPDF(holoCode: string, options?: PDFOptions): Promise<RenderResult>;
3651
+ /**
3652
+ * Convenience function to prerender HTML
3653
+ */
3654
+ declare function prerenderHTML(holoCode: string, options?: PrerenderOptions): Promise<RenderResult>;
3655
+
3656
+ /**
3657
+ * Rendering subsystem — extracted from @holoscript/core (A.011.01a).
3658
+ *
3659
+ * Includes WebGPU renderer, post-processing pipeline, headless (Puppeteer)
3660
+ * rendering, materials, lighting, ray tracing, shader graph, and visual effects.
3661
+ */
3662
+
3663
+ type index_AABB = AABB;
3664
+ type index_AdvancedLight = AdvancedLight;
3665
+ type index_AdvancedLightingManager = AdvancedLightingManager;
3666
+ declare const index_AdvancedLightingManager: typeof AdvancedLightingManager;
3667
+ type index_AdvancedPBRConfig = AdvancedPBRConfig;
3668
+ type index_AdvancedPBRMaterial = AdvancedPBRMaterial;
3669
+ declare const index_AdvancedPBRMaterial: typeof AdvancedPBRMaterial;
3670
+ type index_AmbientConfig = AmbientConfig;
3671
+ type index_AnimationFrameOptions = AnimationFrameOptions;
3672
+ type index_AnisotropyConfig = AnisotropyConfig;
3673
+ type index_AreaLightConfig = AreaLightConfig;
3674
+ type index_AreaLightShape = AreaLightShape;
3675
+ type index_AtlasPacker = AtlasPacker;
3676
+ type index_AtlasRect = AtlasRect;
3677
+ type index_AttachmentFormat = AttachmentFormat;
3678
+ type index_BVH = BVH;
3679
+ declare const index_BVH: typeof BVH;
3680
+ type index_BVHNode = BVHNode;
3681
+ type index_BatchStats = BatchStats;
3682
+ type index_BloomConfig = BloomConfig;
3683
+ type index_CausticConfig = CausticConfig;
3684
+ type index_ChromaticAberrationConfig = ChromaticAberrationConfig;
3685
+ type index_ClearOp = ClearOp;
3686
+ type index_ClearcoatConfig = ClearcoatConfig;
3687
+ type index_CloudConfig = CloudConfig;
3688
+ type index_CloudRenderer = CloudRenderer;
3689
+ declare const index_CloudRenderer: typeof CloudRenderer;
3690
+ type index_CloudSample = CloudSample;
3691
+ type index_ColorGrading = ColorGrading;
3692
+ declare const index_ColorGrading: typeof ColorGrading;
3693
+ type index_ColorGradingConfig = ColorGradingConfig;
3694
+ type index_CompiledShader = CompiledShader;
3695
+ type index_DOFConfig = DOFConfig;
3696
+ type index_DecalBatcher = DecalBatcher;
3697
+ declare const index_DecalBatcher: typeof DecalBatcher;
3698
+ type index_DecalDef = DecalDef;
3699
+ type index_DecalInstance = DecalInstance;
3700
+ type index_DecalSystem = DecalSystem;
3701
+ declare const index_DecalSystem: typeof DecalSystem;
3702
+ type index_DetailMapConfig = DetailMapConfig;
3703
+ type index_DisplacementConfig = DisplacementConfig;
3704
+ type index_DrawBatch = DrawBatch;
3705
+ type index_FogConfig = FogConfig;
3706
+ type index_FogMode = FogMode;
3707
+ type index_FogSystem = FogSystem;
3708
+ declare const index_FogSystem: typeof FogSystem;
3709
+ type index_FramebufferAttachment = FramebufferAttachment;
3710
+ type index_GIConfig = GIConfig;
3711
+ type index_GIMode = GIMode;
3712
+ type index_GIProbe = GIProbe;
3713
+ type index_GIProbeGrid = GIProbeGrid;
3714
+ declare const index_GIProbeGrid: typeof GIProbeGrid;
3715
+ type index_GraphStats = GraphStats;
3716
+ type index_HitRecord = HitRecord;
3717
+ type index_IBlendComponent = IBlendComponent;
3718
+ type index_IBlendState = IBlendState;
3719
+ type index_IBoundingBox = IBoundingBox;
3720
+ type index_IBufferDescriptor = IBufferDescriptor;
3721
+ type index_ICameraUniforms = ICameraUniforms;
3722
+ type index_IColorTargetState = IColorTargetState;
3723
+ type index_IDepthStencilState = IDepthStencilState;
3724
+ type index_IDeviceCapabilities = IDeviceCapabilities;
3725
+ type index_IDrawCall = IDrawCall;
3726
+ type index_IESProfile = IESProfile;
3727
+ type index_IFrameStats = IFrameStats;
3728
+ type index_IGPUTexture = IGPUTexture;
3729
+ type index_IIndexBuffer = IIndexBuffer;
3730
+ type index_IRenderMaterial = IRenderMaterial;
3731
+ type index_IRenderMesh = IRenderMesh;
3732
+ type index_IRenderPassColorAttachment = IRenderPassColorAttachment;
3733
+ type index_IRenderPassDepthStencilAttachment = IRenderPassDepthStencilAttachment;
3734
+ type index_IRenderPassDescriptor = IRenderPassDescriptor;
3735
+ type index_IRenderPipelineDescriptor = IRenderPipelineDescriptor;
3736
+ type index_IRendererStats = IRendererStats;
3737
+ type index_ISamplerDescriptor = ISamplerDescriptor;
3738
+ type index_ISceneUniforms = ISceneUniforms;
3739
+ type index_IShaderModule = IShaderModule;
3740
+ type index_ITextureDescriptor = ITextureDescriptor;
3741
+ type index_IUniformBuffer = IUniformBuffer;
3742
+ type index_IVertexAttribute = IVertexAttribute;
3743
+ type index_IVertexBuffer = IVertexBuffer;
3744
+ type index_IVertexBufferLayout = IVertexBufferLayout;
3745
+ type index_IWebGPUContext = IWebGPUContext;
3746
+ type index_IWebGPUInitOptions = IWebGPUInitOptions;
3747
+ type index_IridescenceConfig = IridescenceConfig;
3748
+ type index_Light = Light;
3749
+ type index_LightCookie = LightCookie;
3750
+ type index_LightType = LightType;
3751
+ type index_LightingModel = LightingModel;
3752
+ declare const index_LightingModel: typeof LightingModel;
3753
+ type index_MaterialDef = MaterialDef;
3754
+ type index_MaterialInstance = MaterialInstance;
3755
+ type index_MaterialLibrary = MaterialLibrary;
3756
+ declare const index_MaterialLibrary: typeof MaterialLibrary;
3757
+ type index_MaterialSystem = MaterialSystem;
3758
+ declare const index_MaterialSystem: typeof MaterialSystem;
3759
+ type index_MotionBlurConfig = MotionBlurConfig;
3760
+ type index_NLMConfig = NLMConfig;
3761
+ type index_PDFOptions = PDFOptions;
3762
+ type index_POMConfig = POMConfig;
3763
+ declare const index_PP_PRESETS: typeof PP_PRESETS;
3764
+ type index_PassContext = PassContext;
3765
+ type index_PathTracerScene = PathTracerScene;
3766
+ type index_PhysicsDebugDrawer = PhysicsDebugDrawer;
3767
+ declare const index_PhysicsDebugDrawer: typeof PhysicsDebugDrawer;
3768
+ type index_PixelBuffer = PixelBuffer;
3769
+ type index_PostProcessProfile = PostProcessProfile;
3770
+ type index_PostProcessStack = PostProcessStack;
3771
+ declare const index_PostProcessStack: typeof PostProcessStack;
3772
+ type index_PostProcessingStack = PostProcessingStack;
3773
+ declare const index_PostProcessingStack: typeof PostProcessingStack;
3774
+ type index_PrerenderOptions = PrerenderOptions;
3775
+ type index_ProbeInfo = ProbeInfo;
3776
+ type index_ProjectorConfig = ProjectorConfig;
3777
+ type index_ProjectorLight = ProjectorLight;
3778
+ declare const index_ProjectorLight: typeof ProjectorLight;
3779
+ type index_PuppeteerRenderer = PuppeteerRenderer;
3780
+ declare const index_PuppeteerRenderer: typeof PuppeteerRenderer;
3781
+ type index_PuppeteerRendererOptions = PuppeteerRendererOptions;
3782
+ type index_RTApi = RTApi;
3783
+ type index_RTFeature = RTFeature;
3784
+ type index_Ray = Ray;
3785
+ type index_RayTracer = RayTracer;
3786
+ declare const index_RayTracer: typeof RayTracer;
3787
+ type index_RayTracingConfig = RayTracingConfig;
3788
+ type index_RenderGraph = RenderGraph;
3789
+ declare const index_RenderGraph: typeof RenderGraph;
3790
+ type index_RenderPass = RenderPass;
3791
+ declare const index_RenderPass: typeof RenderPass;
3792
+ type index_RenderPassConfig = RenderPassConfig;
3793
+ type index_RenderPassDescriptor = RenderPassDescriptor;
3794
+ type index_RenderResult = RenderResult;
3795
+ type index_RenderTarget = RenderTarget;
3796
+ type index_SH9 = SH9;
3797
+ declare const index_SHADER_NODES: typeof SHADER_NODES;
3798
+ type index_SSAOConfig = SSAOConfig;
3799
+ type index_SSGIConfig = SSGIConfig;
3800
+ type index_SSRConfig = SSRConfig;
3801
+ type index_SSSConfig = SSSConfig;
3802
+ type index_SSSLayer = SSSLayer;
3803
+ type index_SSSMaterial = SSSMaterial;
3804
+ declare const index_SSSMaterial: typeof SSSMaterial;
3805
+ type index_SSSModel = SSSModel;
3806
+ declare const index_SSS_PRESETS: typeof SSS_PRESETS;
3807
+ declare const index_STANDARD_FRAGMENT_SHADER: typeof STANDARD_FRAGMENT_SHADER;
3808
+ declare const index_STANDARD_VERTEX_SHADER: typeof STANDARD_VERTEX_SHADER;
3809
+ type index_ScreenshotOptions = ScreenshotOptions;
3810
+ type index_ShaderConnection = ShaderConnection;
3811
+ type index_ShaderDataType = ShaderDataType;
3812
+ type index_ShaderGraph = ShaderGraph;
3813
+ declare const index_ShaderGraph: typeof ShaderGraph;
3814
+ type index_ShaderNode = ShaderNode;
3815
+ type index_ShaderNodeDef = ShaderNodeDef;
3816
+ type index_ShaderPort = ShaderPort;
3817
+ type index_ShaderPortRef = ShaderPortRef;
3818
+ type index_ShaderUniform = ShaderUniform;
3819
+ type index_SheenConfig = SheenConfig;
3820
+ type index_TAAConfig = TAAConfig;
3821
+ type index_Texture2D = Texture2D;
3822
+ type index_TextureFormat = TextureFormat;
3823
+ type index_TextureSlot = TextureSlot;
3824
+ type index_ToneMapper = ToneMapper;
3825
+ type index_TonemapOperator = TonemapOperator;
3826
+ type index_Triangle = Triangle;
3827
+ declare const index_UNLIT_FRAGMENT_SHADER: typeof UNLIT_FRAGMENT_SHADER;
3828
+ declare const index_UNLIT_VERTEX_SHADER: typeof UNLIT_VERTEX_SHADER;
3829
+ type index_UniformDef = UniformDef;
3830
+ type index_UniformType = UniformType;
3831
+ type index_VolumetricLight = VolumetricLight;
3832
+ declare const index_VolumetricLight: typeof VolumetricLight;
3833
+ type index_VolumetricLightConfig = VolumetricLightConfig;
3834
+ type index_VolumetricSample = VolumetricSample;
3835
+ type index_WebGPURenderer = WebGPURenderer;
3836
+ declare const index_WebGPURenderer: typeof WebGPURenderer;
3837
+ declare const index_aabbCentroid: typeof aabbCentroid;
3838
+ declare const index_aabbSurfaceArea: typeof aabbSurfaceArea;
3839
+ declare const index_addSHSample: typeof addSHSample;
3840
+ declare const index_anisotropicRoughness: typeof anisotropicRoughness;
3841
+ declare const index_applyChromaticAberration: typeof applyChromaticAberration;
3842
+ declare const index_applyDOF: typeof applyDOF;
3843
+ declare const index_applyDetailAlbedo: typeof applyDetailAlbedo;
3844
+ declare const index_applyFilmGrain: typeof applyFilmGrain;
3845
+ declare const index_applyMotionBlur: typeof applyMotionBlur;
3846
+ declare const index_applyVignette: typeof applyVignette;
3847
+ declare const index_blendDetailNormal: typeof blendDetailNormal;
3848
+ declare const index_blendTAA: typeof blendTAA;
3849
+ declare const index_buildCircleCookie: typeof buildCircleCookie;
3850
+ declare const index_buildSeparableSSSKernel: typeof buildSeparableSSSKernel;
3851
+ declare const index_burleyProfile: typeof burleyProfile;
3852
+ declare const index_burleyProfileRGB: typeof burleyProfileRGB;
3853
+ declare const index_christensenProfile: typeof christensenProfile;
3854
+ declare const index_computeAABB: typeof computeAABB;
3855
+ declare const index_computeCoC: typeof computeCoC;
3856
+ declare const index_computeDiffuseAlbedo: typeof computeDiffuseAlbedo;
3857
+ declare const index_computeDisplacedPosition: typeof computeDisplacedPosition;
3858
+ declare const index_computeDisplacementNormalsFromHeightMap: typeof computeDisplacementNormalsFromHeightMap;
3859
+ declare const index_computeF0: typeof computeF0;
3860
+ declare const index_computePOM: typeof computePOM;
3861
+ declare const index_computeSSAO: typeof computeSSAO;
3862
+ declare const index_computeSSGI: typeof computeSSGI;
3863
+ declare const index_computeSSR: typeof computeSSR;
3864
+ declare const index_computeTriangleNormal: typeof computeTriangleNormal;
3865
+ declare const index_createAtlasPacker: typeof createAtlasPacker;
3866
+ declare const index_createDefaultMaterialDef: typeof createDefaultMaterialDef;
3867
+ declare const index_createSH9: typeof createSH9;
3868
+ declare const index_createSolidTexture: typeof createSolidTexture;
3869
+ declare const index_diskSolidAngle: typeof diskSolidAngle;
3870
+ declare const index_distributionGGX: typeof distributionGGX;
3871
+ declare const index_distributionGGXAnisotropic: typeof distributionGGXAnisotropic;
3872
+ declare const index_evalSH9Irradiance: typeof evalSH9Irradiance;
3873
+ declare const index_evalSeparableKernel: typeof evalSeparableKernel;
3874
+ declare const index_evaluateClearcoat: typeof evaluateClearcoat;
3875
+ declare const index_evaluateIridescence: typeof evaluateIridescence;
3876
+ declare const index_evaluateSheen: typeof evaluateSheen;
3877
+ declare const index_fresnelRoughness: typeof fresnelRoughness;
3878
+ declare const index_fresnelSchlick: typeof fresnelSchlick;
3879
+ declare const index_geometrySmith: typeof geometrySmith;
3880
+ declare const index_getAtlasEfficiency: typeof getAtlasEfficiency;
3881
+ declare const index_getRectUV: typeof getRectUV;
3882
+ declare const index_haltonJitter: typeof haltonJitter;
3883
+ declare const index_hexToRGBA: typeof hexToRGBA;
3884
+ declare const index_intersectRayAABB: typeof intersectRayAABB;
3885
+ declare const index_intersectRayTriangle: typeof intersectRayTriangle;
3886
+ declare const index_lerpSH9: typeof lerpSH9;
3887
+ declare const index_nlmDenoise: typeof nlmDenoise;
3888
+ declare const index_packRect: typeof packRect;
3889
+ declare const index_parseIESProfile: typeof parseIESProfile;
3890
+ declare const index_pathTrace: typeof pathTrace;
3891
+ declare const index_prerenderHTML: typeof prerenderHTML;
3892
+ declare const index_rectSolidAngle: typeof rectSolidAngle;
3893
+ declare const index_renderPDF: typeof renderPDF;
3894
+ declare const index_renderScreenshot: typeof renderScreenshot;
3895
+ declare const index_rgbaToHex: typeof rgbaToHex;
3896
+ declare const index_sampleCookie: typeof sampleCookie;
3897
+ declare const index_sampleIES: typeof sampleIES;
3898
+ declare const index_sampleTexture: typeof sampleTexture;
3899
+ declare const index_sampleTextureBilinear: typeof sampleTextureBilinear;
3900
+ declare const index_sampleTriplanar: typeof sampleTriplanar;
3901
+ declare const index_scaleSH9: typeof scaleSH9;
3902
+ declare const index_sheenDistribution: typeof sheenDistribution;
3903
+ declare const index_sheenVisibility: typeof sheenVisibility;
3904
+ declare const index_thinSlabTransmission: typeof thinSlabTransmission;
3905
+ declare const index_triplanarWeights: typeof triplanarWeights;
3906
+ declare namespace index {
3907
+ export { type index_AABB as AABB, MATERIAL_PRESETS$1 as ADVANCED_PBR_PRESETS, type index_AdvancedLight as AdvancedLight, type LightType$1 as AdvancedLightingLightType, index_AdvancedLightingManager as AdvancedLightingManager, type Vec2$1 as AdvancedLightingVec2, type Vec3$4 as AdvancedLightingVec3, type index_AdvancedPBRConfig as AdvancedPBRConfig, index_AdvancedPBRMaterial as AdvancedPBRMaterial, type Vec3$3 as AdvancedPBRVec3, type Vec2 as AdvancedTexturingVec2, type Vec3$2 as AdvancedTexturingVec3, type index_AmbientConfig as AmbientConfig, type index_AnimationFrameOptions as AnimationFrameOptions, type index_AnisotropyConfig as AnisotropyConfig, type index_AreaLightConfig as AreaLightConfig, type index_AreaLightShape as AreaLightShape, type index_AtlasPacker as AtlasPacker, type index_AtlasRect as AtlasRect, type index_AttachmentFormat as AttachmentFormat, index_BVH as BVH, type index_BVHNode as BVHNode, type index_BatchStats as BatchStats, type BlendMode$2 as BlendMode, type index_BloomConfig as BloomConfig, BloomEffect$1 as BloomEffect, type index_CausticConfig as CausticConfig, type index_ChromaticAberrationConfig as ChromaticAberrationConfig, type index_ClearOp as ClearOp, type index_ClearcoatConfig as ClearcoatConfig, type index_CloudConfig as CloudConfig, index_CloudRenderer as CloudRenderer, type index_CloudSample as CloudSample, index_ColorGrading as ColorGrading, type index_ColorGradingConfig as ColorGradingConfig, type index_CompiledShader as CompiledShader, type CullMode$1 as CullMode, type index_DOFConfig as DOFConfig, index_DecalBatcher as DecalBatcher, type index_DecalDef as DecalDef, type index_DecalInstance as DecalInstance, index_DecalSystem as DecalSystem, type index_DetailMapConfig as DetailMapConfig, type index_DisplacementConfig as DisplacementConfig, type index_DrawBatch as DrawBatch, type index_FogConfig as FogConfig, type index_FogMode as FogMode, index_FogSystem as FogSystem, type index_FramebufferAttachment as FramebufferAttachment, type index_GIConfig as GIConfig, type index_GIMode as GIMode, type index_GIProbe as GIProbe, index_GIProbeGrid as GIProbeGrid, type Vec3$1 as GlobalIlluminationVec3, type index_GraphStats as GraphStats, type index_HitRecord as HitRecord, type index_IBlendComponent as IBlendComponent, type index_IBlendState as IBlendState, type index_IBoundingBox as IBoundingBox, type index_IBufferDescriptor as IBufferDescriptor, type index_ICameraUniforms as ICameraUniforms, type index_IColorTargetState as IColorTargetState, type index_IDepthStencilState as IDepthStencilState, type index_IDeviceCapabilities as IDeviceCapabilities, type index_IDrawCall as IDrawCall, type index_IESProfile as IESProfile, type index_IFrameStats as IFrameStats, type index_IGPUTexture as IGPUTexture, type index_IIndexBuffer as IIndexBuffer, type index_IRenderMaterial as IRenderMaterial, type index_IRenderMesh as IRenderMesh, type index_IRenderPassColorAttachment as IRenderPassColorAttachment, type index_IRenderPassDepthStencilAttachment as IRenderPassDepthStencilAttachment, type index_IRenderPassDescriptor as IRenderPassDescriptor, type index_IRenderPipelineDescriptor as IRenderPipelineDescriptor, type index_IRendererStats as IRendererStats, type index_ISamplerDescriptor as ISamplerDescriptor, type index_ISceneUniforms as ISceneUniforms, type index_IShaderModule as IShaderModule, type index_ITextureDescriptor as ITextureDescriptor, type index_IUniformBuffer as IUniformBuffer, type index_IVertexAttribute as IVertexAttribute, type index_IVertexBuffer as IVertexBuffer, type index_IVertexBufferLayout as IVertexBufferLayout, type index_IWebGPUContext as IWebGPUContext, type index_IWebGPUInitOptions as IWebGPUInitOptions, type index_IridescenceConfig as IridescenceConfig, type index_Light as Light, type index_LightCookie as LightCookie, type index_LightType as LightType, index_LightingModel as LightingModel, type index_MaterialDef as MaterialDef, type index_MaterialInstance as MaterialInstance, index_MaterialLibrary as MaterialLibrary, index_MaterialSystem as MaterialSystem, type BlendMode$1 as MaterialSystemBlendMode, type CullMode as MaterialSystemCullMode, type Material as MaterialSystemMaterial, type index_MotionBlurConfig as MotionBlurConfig, type index_NLMConfig as NLMConfig, type index_PDFOptions as PDFOptions, type index_POMConfig as POMConfig, index_PP_PRESETS as PP_PRESETS, type index_PassContext as PassContext, type index_PathTracerScene as PathTracerScene, index_PhysicsDebugDrawer as PhysicsDebugDrawer, type index_PixelBuffer as PixelBuffer, index$1 as PostProcess, type PostProcessEffect$1 as PostProcessEffect, type index_PostProcessProfile as PostProcessProfile, index_PostProcessStack as PostProcessStack, index_PostProcessingStack as PostProcessingStack, type index_PrerenderOptions as PrerenderOptions, type index_ProbeInfo as ProbeInfo, type index_ProjectorConfig as ProjectorConfig, index_ProjectorLight as ProjectorLight, index_PuppeteerRenderer as PuppeteerRenderer, type index_PuppeteerRendererOptions as PuppeteerRendererOptions, MATERIAL_PRESETS as RENDERING_MATERIAL_PRESETS, type RGB$1 as RGB, type index_RTApi as RTApi, type index_RTFeature as RTFeature, type index_Ray as Ray, index_RayTracer as RayTracer, type index_RayTracingConfig as RayTracingConfig, type Vec3 as RayTracingVec3, index_RenderGraph as RenderGraph, index_RenderPass as RenderPass, type index_RenderPassConfig as RenderPassConfig, type index_RenderPassDescriptor as RenderPassDescriptor, type index_RenderResult as RenderResult, type index_RenderTarget as RenderTarget, type MaterialType as RenderingMaterialType, type index_SH9 as SH9, index_SHADER_NODES as SHADER_NODES, type index_SSAOConfig as SSAOConfig, type index_SSGIConfig as SSGIConfig, type index_SSRConfig as SSRConfig, type index_SSSConfig as SSSConfig, type index_SSSLayer as SSSLayer, index_SSSMaterial as SSSMaterial, type index_SSSModel as SSSModel, type RGB as SSSRGB, index_SSS_PRESETS as SSS_PRESETS, index_STANDARD_FRAGMENT_SHADER as STANDARD_FRAGMENT_SHADER, index_STANDARD_VERTEX_SHADER as STANDARD_VERTEX_SHADER, type index_ScreenshotOptions as ScreenshotOptions, type index_ShaderConnection as ShaderConnection, type index_ShaderDataType as ShaderDataType, index_ShaderGraph as ShaderGraph, type index_ShaderNode as ShaderNode, type index_ShaderNodeDef as ShaderNodeDef, type index_ShaderPort as ShaderPort, type index_ShaderPortRef as ShaderPortRef, type index_ShaderUniform as ShaderUniform, type index_SheenConfig as SheenConfig, type index_TAAConfig as TAAConfig, type index_Texture2D as Texture2D, type index_TextureFormat as TextureFormat, type index_TextureSlot as TextureSlot, type index_ToneMapper as ToneMapper, type index_TonemapOperator as TonemapOperator, type index_Triangle as Triangle, index_UNLIT_FRAGMENT_SHADER as UNLIT_FRAGMENT_SHADER, index_UNLIT_VERTEX_SHADER as UNLIT_VERTEX_SHADER, type index_UniformDef as UniformDef, type index_UniformType as UniformType, index_VolumetricLight as VolumetricLight, type index_VolumetricLightConfig as VolumetricLightConfig, type index_VolumetricSample as VolumetricSample, index_WebGPURenderer as WebGPURenderer, index_aabbCentroid as aabbCentroid, index_aabbSurfaceArea as aabbSurfaceArea, index_addSHSample as addSHSample, index_anisotropicRoughness as anisotropicRoughness, index_applyChromaticAberration as applyChromaticAberration, index_applyDOF as applyDOF, index_applyDetailAlbedo as applyDetailAlbedo, index_applyFilmGrain as applyFilmGrain, index_applyMotionBlur as applyMotionBlur, index_applyVignette as applyVignette, index_blendDetailNormal as blendDetailNormal, index_blendTAA as blendTAA, index_buildCircleCookie as buildCircleCookie, index_buildSeparableSSSKernel as buildSeparableSSSKernel, index_burleyProfile as burleyProfile, index_burleyProfileRGB as burleyProfileRGB, index_christensenProfile as christensenProfile, index_computeAABB as computeAABB, index_computeCoC as computeCoC, index_computeDiffuseAlbedo as computeDiffuseAlbedo, index_computeDisplacedPosition as computeDisplacedPosition, index_computeDisplacementNormalsFromHeightMap as computeDisplacementNormalsFromHeightMap, index_computeF0 as computeF0, index_computePOM as computePOM, index_computeSSAO as computeSSAO, index_computeSSGI as computeSSGI, index_computeSSR as computeSSR, index_computeTriangleNormal as computeTriangleNormal, index_createAtlasPacker as createAtlasPacker, index_createDefaultMaterialDef as createDefaultMaterialDef, index_createSH9 as createSH9, index_createSolidTexture as createSolidTexture, index_diskSolidAngle as diskSolidAngle, index_distributionGGX as distributionGGX, index_distributionGGXAnisotropic as distributionGGXAnisotropic, index_evalSH9Irradiance as evalSH9Irradiance, index_evalSeparableKernel as evalSeparableKernel, index_evaluateClearcoat as evaluateClearcoat, index_evaluateIridescence as evaluateIridescence, index_evaluateSheen as evaluateSheen, index_fresnelRoughness as fresnelRoughness, index_fresnelSchlick as fresnelSchlick, index_geometrySmith as geometrySmith, index_getAtlasEfficiency as getAtlasEfficiency, index_getRectUV as getRectUV, index_haltonJitter as haltonJitter, index_hexToRGBA as hexToRGBA, index_intersectRayAABB as intersectRayAABB, index_intersectRayTriangle as intersectRayTriangle, index_lerpSH9 as lerpSH9, index_nlmDenoise as nlmDenoise, index_packRect as packRect, index_parseIESProfile as parseIESProfile, index_pathTrace as pathTrace, index_prerenderHTML as prerenderHTML, index_rectSolidAngle as rectSolidAngle, index_renderPDF as renderPDF, index_renderScreenshot as renderScreenshot, index_rgbaToHex as rgbaToHex, index_sampleCookie as sampleCookie, index_sampleIES as sampleIES, index_sampleTexture as sampleTexture, index_sampleTextureBilinear as sampleTextureBilinear, index_sampleTriplanar as sampleTriplanar, index_scaleSH9 as scaleSH9, index_sheenDistribution as sheenDistribution, index_sheenVisibility as sheenVisibility, index_thinSlabTransmission as thinSlabTransmission, index_triplanarWeights as triplanarWeights };
3908
+ }
3909
+
3910
+ export { type Vec3$1 as $, type AABB as A, BVH as B, type CausticConfig as C, type CloudSample as D, ColorGrading as E, type ColorGradingConfig as F, type CompiledShader as G, type CullMode$1 as H, type DOFConfig as I, DecalBatcher as J, type DecalDef as K, type LightType$1 as L, MATERIAL_PRESETS$1 as M, type DecalInstance as N, DecalSystem as O, type DetailMapConfig as P, type DisplacementConfig as Q, type DrawBatch as R, type FogConfig as S, type FogMode as T, FogSystem as U, type Vec2$1 as V, type FramebufferAttachment as W, type GIConfig as X, type GIMode as Y, type GIProbe as Z, GIProbeGrid as _, type AdvancedLight as a, type PuppeteerRendererOptions as a$, type GraphStats as a0, type HitRecord as a1, type IBlendComponent as a2, type IBlendState as a3, type IBoundingBox as a4, type IBufferDescriptor as a5, type ICameraUniforms as a6, type IColorTargetState as a7, type IDepthStencilState as a8, type IDeviceCapabilities as a9, LightingModel as aA, type MaterialDef as aB, type MaterialInstance as aC, MaterialLibrary as aD, MaterialSystem as aE, type BlendMode$1 as aF, type CullMode as aG, type Material as aH, type MotionBlurConfig as aI, type NLMConfig as aJ, type PDFOptions as aK, type POMConfig as aL, PP_PRESETS as aM, type PassContext as aN, type PathTracerScene as aO, PhysicsDebugDrawer as aP, type PixelBuffer as aQ, index$1 as aR, type PostProcessEffect$1 as aS, type PostProcessProfile as aT, PostProcessStack as aU, PostProcessingStack as aV, type PrerenderOptions as aW, type ProbeInfo as aX, type ProjectorConfig as aY, ProjectorLight as aZ, PuppeteerRenderer as a_, type IDrawCall as aa, type IESProfile as ab, type IFrameStats as ac, type IGPUTexture as ad, type IIndexBuffer as ae, type IRenderMaterial as af, type IRenderMesh as ag, type IRenderPassColorAttachment as ah, type IRenderPassDepthStencilAttachment as ai, type IRenderPassDescriptor as aj, type IRenderPipelineDescriptor as ak, type IRendererStats as al, type ISamplerDescriptor as am, type ISceneUniforms as an, type IShaderModule as ao, type ITextureDescriptor as ap, type IUniformBuffer as aq, type IVertexAttribute as ar, type IVertexBuffer as as, type IVertexBufferLayout as at, type IWebGPUContext as au, type IWebGPUInitOptions as av, type IridescenceConfig as aw, type Light as ax, type LightCookie as ay, type LightType as az, AdvancedLightingManager as b, applyVignette as b$, MATERIAL_PRESETS as b0, type RGB$1 as b1, type RTApi as b2, type RTFeature as b3, type Ray as b4, RayTracer as b5, type RayTracingConfig as b6, type Vec3 as b7, RenderGraph as b8, RenderPass as b9, type ShaderPortRef as bA, type ShaderUniform as bB, type SheenConfig as bC, type TAAConfig as bD, type Texture2D as bE, type TextureFormat as bF, type TextureSlot as bG, type ToneMapper as bH, type TonemapOperator as bI, type Triangle as bJ, UNLIT_FRAGMENT_SHADER as bK, UNLIT_VERTEX_SHADER as bL, type UniformDef as bM, type UniformType as bN, VolumetricLight as bO, type VolumetricLightConfig as bP, type VolumetricSample as bQ, WebGPURenderer as bR, aabbCentroid as bS, aabbSurfaceArea as bT, addSHSample as bU, anisotropicRoughness as bV, applyChromaticAberration as bW, applyDOF as bX, applyDetailAlbedo as bY, applyFilmGrain as bZ, applyMotionBlur as b_, type RenderPassConfig as ba, type RenderPassDescriptor as bb, type RenderResult as bc, type RenderTarget as bd, index as be, type MaterialType as bf, type SH9 as bg, SHADER_NODES as bh, type SSAOConfig as bi, type SSGIConfig as bj, type SSRConfig as bk, type SSSConfig as bl, type SSSLayer as bm, SSSMaterial as bn, type SSSModel as bo, type RGB as bp, SSS_PRESETS as bq, STANDARD_FRAGMENT_SHADER as br, STANDARD_VERTEX_SHADER as bs, type ScreenshotOptions as bt, type ShaderConnection as bu, type ShaderDataType as bv, ShaderGraph as bw, type ShaderNode as bx, type ShaderNodeDef as by, type ShaderPort as bz, type Vec3$4 as c, blendDetailNormal as c0, blendTAA as c1, buildCircleCookie as c2, buildSeparableSSSKernel as c3, burleyProfile as c4, burleyProfileRGB as c5, christensenProfile as c6, computeAABB as c7, computeCoC as c8, computeDiffuseAlbedo as c9, hexToRGBA as cA, intersectRayAABB as cB, intersectRayTriangle as cC, lerpSH9 as cD, nlmDenoise as cE, packRect as cF, parseIESProfile as cG, pathTrace as cH, prerenderHTML as cI, rectSolidAngle as cJ, renderPDF as cK, renderScreenshot as cL, rgbaToHex as cM, sampleCookie as cN, sampleIES as cO, sampleTexture as cP, sampleTextureBilinear as cQ, sampleTriplanar as cR, scaleSH9 as cS, sheenDistribution as cT, sheenVisibility as cU, thinSlabTransmission as cV, triplanarWeights as cW, computeDisplacedPosition as ca, computeDisplacementNormalsFromHeightMap as cb, computeF0 as cc, computePOM as cd, computeSSAO as ce, computeSSGI as cf, computeSSR as cg, computeTriangleNormal as ch, createAtlasPacker as ci, createDefaultMaterialDef as cj, createSH9 as ck, createSolidTexture as cl, diskSolidAngle as cm, distributionGGX as cn, distributionGGXAnisotropic as co, evalSH9Irradiance as cp, evalSeparableKernel as cq, evaluateClearcoat as cr, evaluateIridescence as cs, evaluateSheen as ct, fresnelRoughness as cu, fresnelSchlick as cv, geometrySmith as cw, getAtlasEfficiency as cx, getRectUV as cy, haltonJitter as cz, type AdvancedPBRConfig as d, AdvancedPBRMaterial as e, type Vec3$3 as f, type Vec2 as g, type Vec3$2 as h, type AmbientConfig as i, type AnimationFrameOptions as j, type AnisotropyConfig as k, type AreaLightConfig as l, type AreaLightShape as m, type AtlasPacker as n, type AtlasRect as o, type AttachmentFormat as p, type BVHNode as q, type BatchStats as r, type BlendMode$2 as s, type BloomConfig as t, BloomEffect$1 as u, type ChromaticAberrationConfig as v, type ClearOp as w, type ClearcoatConfig as x, type CloudConfig as y, CloudRenderer as z };