Cap shared hall lights (no per-painting spots) so MeshStandard walls stay within WebGL limits, tuck classical/neoclassical details into engaged corner pilasters, and document the light budget. Co-authored-by: Cursor <cursoragent@cursor.com>
33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
import { useEffect, useMemo } from 'react';
|
|
import * as THREE from 'three';
|
|
import { cloneSurfaceTexture, getSurfaceTexture, type SurfaceTextureKind } from '../utils/galleryProceduralTextures';
|
|
|
|
export function useTexturedMaterial(
|
|
kind: SurfaceTextureKind,
|
|
tint: string,
|
|
spanW: number,
|
|
spanH: number
|
|
): THREE.MeshStandardMaterial {
|
|
const material = useMemo(() => {
|
|
const meters = getSurfaceTexture(kind).metersPerRepeat;
|
|
const surf = cloneSurfaceTexture(
|
|
kind,
|
|
Math.max(1, spanW / meters),
|
|
Math.max(1, spanH / meters)
|
|
);
|
|
return new THREE.MeshStandardMaterial({
|
|
map: surf.map,
|
|
normalMap: surf.normalMap,
|
|
normalScale: new THREE.Vector2(surf.normalScale, surf.normalScale),
|
|
color: tint,
|
|
roughness: surf.roughness,
|
|
metalness: surf.metalness,
|
|
// Keep walls readable without HDR Environment IBL (CDN may be slow/offline).
|
|
envMapIntensity: kind.startsWith('painted-') ? 0.2 : 0.3,
|
|
});
|
|
}, [kind, tint, spanW, spanH]);
|
|
|
|
useEffect(() => () => material.dispose(), [material]);
|
|
return material;
|
|
}
|