import { MeshStandardMaterial, type MeshStandardMaterialParameters, Color, Texture, Vector2, Vector3, type IUniform, type WebGLRenderer } from 'three'; type Shader = { uniforms: Record; vertexShader: string; fragmentShader: string; }; /** * GPU-side per-window emissive variation derived from `windowId` — lit/unlit * windows, warm/cool tones, brightness jitter. Because the decision happens in * the shader from `windowId` alone (hash seeds: lit 3.71, tone 9.27, * brightness 5.43), a far-LOD impostor shader can hash the same id with the * same seeds and reproduce the exact same window, enabling seamless LOD * crossfades. When set, this overrides `interiorEmissive`. */ export interface EmissiveVariation { /** Chance a window is lit, in [0, 1]. Default 0.5. */ litRatio?: number; /** Emissive tint of warm (incandescent) windows. Default (1.7, 1.35, 0.95). */ warm?: Color; /** Emissive tint of cool (fluorescent/TV) windows. Default (0.9, 1.15, 1.5). */ cool?: Color; /** Chance a lit window uses the cool tone. Default 0.22. */ coolChance?: number; /** Minimum brightness multiplier of a lit window. Default 0.3. */ brightMin?: number; /** Random brightness range added on top of brightMin. Default 0.35. */ brightRange?: number; /** Emissive of unlit windows (faintly visible dark room). Default (0.07, 0.08, 0.1). */ dim?: Color; } export interface InteriorMappingMaterialParameters extends MeshStandardMaterialParameters { /** Interior atlas — the rooms texture sampled by the ray-march. */ backAtlas: Texture; /** Columns in the back atlas grid. Default 4. */ backAtlasCols?: number; /** Rows in the back atlas grid. Default 4. */ backAtlasRows?: number; /** Apparent room depth in plane-local units. Default 1.0. */ depth?: number; /** Back-wall fill factor in [0.05, 0.999]. Default 0.66. */ backScale?: number; /** Plane size in world units (width, height). Must match the geometry. */ planeSize: Vector2; /** * Per-window seed (typically the window center). Controls cell picking. * Optional in instanced mode, where `instanceWindowId` replaces it. */ windowId?: Vector3; /** * Multiplier on the interior contribution before adding to the lit output. * Default (1, 1, 1). Tint warm + scale up for a "lights on" night look, * e.g. new Color(3.5, 3.0, 2.3). */ interiorEmissive?: Color; /** * Fraction of interior light that bleeds through the opaque front layer, * tinted by the front color. 0 = front layer fully blocks the interior * (hard cutoff), 1 = no blocking. Default 0.25. */ frontTransmission?: number; /** * Raises the effective opacity of the front layer. 1.0 = no change. >1 makes * semi-transparent pixels (sheer curtains, antialiased edges) read as more * opaque without re-authoring the texture. Useful for "lights on" night mode. * Computed as pow(alpha, 1/boost). Default 1.0. */ frontAlphaBoost?: number; /** Optional front PBR atlas (RGBA: albedo + alpha). */ frontAtlas?: Texture; /** Columns in the front atlas grid. Default 1. */ frontAtlasCols?: number; /** Rows in the front atlas grid. Default 1. */ frontAtlasRows?: number; /** Optional front normal atlas. Tangent-space normals. */ frontNormalAtlas?: Texture; /** Normal map strength multiplier on .xy. Default 1.0. */ frontNormalScale?: number; /** Optional front roughness atlas (samples .g). */ frontRoughnessAtlas?: Texture; /** Optional front metalness atlas (samples .b). */ frontMetalnessAtlas?: Texture; /** * Apparent glass thickness in plane-local units. Parallax-shifts the front * overlay sample so it appears to sit on the inside face of the pane rather * than glued to the outside surface. 0 disables. Default 0. */ glassThickness?: number; /** * Magnitude (in cellUV units) of the interior ray-march sample perturbation * driven by the glass dirt map. Sells the "looking through real glass" effect. * Keep tiny (0.003–0.015). 0 disables. Default 0. */ refractionStrength?: number; /** * Optional grayscale noise map used as a dirt/specular modulator over the * glass area (and as the source of the refraction perturbation). Centered * around 0.5; values >0.5 roughen the glass, <0.5 polish it. */ glassDirtMap?: Texture; /** * How strongly the dirt map modulates roughness on the glass area. Default 0.35. */ glassDirtStrength?: number; /** * Schlick fresnel sheen added to the glass area at grazing angles. This is * the primary "this is a pane of glass" cue. Default 0.0; example uses ~0.5. */ glassFresnelStrength?: number; /** Tint of the fresnel sheen. Default cool white (0.85, 0.92, 1.0). */ glassFresnelColor?: Color; /** * Additive brightness of dirt visible as smudges on the glass surface. * Different from glassDirtStrength (which is roughness modulation). Default 0.0. */ glassSmudgeStrength?: number; /** * Level-of-detail blend in [0, 1]. 1 = full interior mapping with all glass * cues. 0 = flat impostor: the back cell is sampled straight onto the plane * with no parallax, and fresnel/refraction/smudge/glass-thickness shut off — * pixel-equivalent to a cheap facade shader sampling the same atlas cell. * Drive by camera distance to crossfade against a far-LOD facade. Default 1. */ lod?: number; /** GPU-side per-window emissive variation (see {@link EmissiveVariation}). */ emissiveVariation?: EmissiveVariation; /** * Instanced mode: use with a THREE.InstancedMesh whose geometry carries * InstancedBufferAttributes `instanceWindowId` (vec3), `instanceLod` * (float) and `instanceFade` (float). They replace the `windowId` / `lod` * uniforms per window, and `instanceFade` scales the output alpha (set * `transparent: true` to use it for LOD crossfades). One material + * one InstancedMesh = thousands of windows in a single draw call. * Default false. */ instanced?: boolean; } type InteriorUniforms = { uBackAtlas: IUniform; uBackAtlasCols: IUniform; uBackAtlasRows: IUniform; uDepth: IUniform; uBackScale: IUniform; uPlaneSize: IUniform; uWindowId: IUniform; uInteriorEmissive: IUniform; uFrontTransmission: IUniform; uFrontAlphaBoost: IUniform; uFrontAtlas: IUniform; uFrontAtlasCols: IUniform; uFrontAtlasRows: IUniform; uFrontNormalAtlas: IUniform; uFrontNormalScale: IUniform; uFrontRoughnessAtlas: IUniform; uFrontMetalnessAtlas: IUniform; uGlassThickness: IUniform; uRefractionStrength: IUniform; uGlassDirtMap: IUniform; uGlassDirtStrength: IUniform; uGlassFresnelStrength: IUniform; uGlassFresnelColor: IUniform; uGlassSmudgeStrength: IUniform; uLod: IUniform; uVarEnabled: IUniform; uVarLitRatio: IUniform; uVarWarm: IUniform; uVarCool: IUniform; uVarCoolChance: IUniform; uVarBright: IUniform; uVarDim: IUniform; }; export declare class InteriorMappingMaterial extends MeshStandardMaterial { readonly isInteriorMappingMaterial = true; /** Custom uniforms — shared into the patched MeshStandardMaterial shader. */ readonly interiorUniforms: InteriorUniforms; private _instanced; constructor(params: InteriorMappingMaterialParameters); /** Set/replace the interior atlas. */ setBackAtlas(tex: Texture): void; /** * Enable/update GPU-side per-window emissive variation, or pass null to * disable and fall back to `interiorEmissive`. */ setEmissiveVariation(ev: EmissiveVariation | null): void; /** Set the front albedo atlas (RGBA). Pass null to remove. */ setFrontAtlas(tex: Texture | null, cols?: number, rows?: number): void; setFrontNormalAtlas(tex: Texture | null, scale?: number): void; setFrontRoughnessAtlas(tex: Texture | null): void; setFrontMetalnessAtlas(tex: Texture | null): void; setGlassDirtMap(tex: Texture | null): void; /** Mirror the texture presence into shader #defines so onBeforeCompile branches correctly. */ private applyDefines; onBeforeCompile: (shader: Shader, _renderer: WebGLRenderer) => void; /** Hot-reload-friendly clone of the live runtime knobs. */ get depth(): number; set depth(v: number); get backScale(): number; set backScale(v: number); get interiorEmissive(): Color; set interiorEmissive(c: Color); get frontTransmission(): number; set frontTransmission(v: number); get frontAlphaBoost(): number; set frontAlphaBoost(v: number); get glassThickness(): number; set glassThickness(v: number); get refractionStrength(): number; set refractionStrength(v: number); get glassDirtStrength(): number; set glassDirtStrength(v: number); get glassFresnelStrength(): number; set glassFresnelStrength(v: number); get glassFresnelColor(): Color; set glassFresnelColor(c: Color); get glassSmudgeStrength(): number; set glassSmudgeStrength(v: number); get lod(): number; set lod(v: number); } export {};