Rework Byzantine hall as a late-antique basilica interior.

Replace the flat gold-mosaic chapel with marble revetment walls, a
Cosmatesque stone floor, and a coffered timber ceiling, matching
Santa Sabina / San Vitale reference interiors.

New procedural surfaces in galleryProceduralTextures.ts:
- marble-revetment: book-matched veined panels in moulded travertine
  surrounds (each panel mirrored about its centre)
- marble-opus-sectile: cut-stone bays with diagonal diamond inlays and
  corner triangles in porphyry, verd-antique, giallo, and grey
- coffered-wood: recessed walnut coffers with lit beam chamfers

Add a byzantine detail set to MovementHallDetails.tsx: engaged porphyry
colonnettes with white-marble basket capitals and impost blocks carrying
the ceiling, a marble revetment dado, and hanging brass polycandela.
Colonnettes stay flush in the corner pockets so they do not clip the
~0.7m frame hang margin.

Basilicas are lit by shafts from high windows rather than evenly
flooded, but the shared hall lights carry a brightness floor that
prevented dimming. Add an opt-in lightScale to the interior style that
scales the scene, hall, track, and HDR environment lights. It defaults
to 1, so all other halls are unchanged; only Byzantine opts down. Window
fill lights are left unscaled so the daylight shafts still read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Danila Khodjaef
2026-07-31 18:59:56 +03:00
co-authored by Claude Opus 5
parent 1853222e01
commit 1cb9eef935
5 changed files with 400 additions and 37 deletions
+12 -10
View File
@@ -1484,6 +1484,7 @@ function ArtistHall({
);
const titleColor = interiorStyle?.titleColor ?? '#4a3020';
const warmLight = interiorStyle?.warmLight ?? '#fff5e8';
const hallLightScale = interiorStyle?.lightScale ?? 1;
const wallRoughness = interiorStyle ? 0.75 : 0.92;
const wallMetalness = interiorStyle ? 0.08 : 0.06;
@@ -1656,7 +1657,7 @@ function ArtistHall({
<GalleryTrackLights
width={width}
depth={depth}
intensity={Math.max(1.8, interiorStyle.trackLights * 2.8) * Math.PI}
intensity={Math.max(1.8, interiorStyle.trackLights * 2.8) * Math.PI * interiorStyle.lightScale}
color={interiorStyle.warmLight}
/>
</>
@@ -1736,14 +1737,14 @@ function ArtistHall({
<pointLight
position={[0, WALL_HEIGHT - 0.4, 0]}
intensity={(interiorStyle ? Math.max(1.0, interiorStyle.ambient * 1.8) : 0.7) * Math.PI}
intensity={(interiorStyle ? Math.max(1.0, interiorStyle.ambient * 1.8) : 0.7) * Math.PI * hallLightScale}
distance={width + depth}
decay={0}
color={warmLight}
/>
<pointLight
position={[0, WALL_HEIGHT - 0.4, -halfD / 2]}
intensity={(interiorStyle ? Math.max(0.7, interiorStyle.ambient * 1.2) : 0.5) * Math.PI}
intensity={(interiorStyle ? Math.max(0.7, interiorStyle.ambient * 1.2) : 0.5) * Math.PI * hallLightScale}
distance={Math.max(12, depth * 0.75)}
decay={0}
color={warmLight}
@@ -1751,7 +1752,7 @@ function ArtistHall({
{interiorStyle && (
<directionalLight
position={[0, 6, -halfD - 2]}
intensity={Math.max(0.55, interiorStyle.ambient * 0.85) * Math.PI}
intensity={Math.max(0.55, interiorStyle.ambient * 0.85) * Math.PI * hallLightScale}
color={interiorStyle.sunLight}
/>
)}
@@ -2431,7 +2432,8 @@ export default function VirtualGallery(props: Props) {
const sceneFog = interiorStyle?.fog ?? '#0d0906';
// Floor ambient so dark period styles (Gothic, Byzantine) stay readable without HDR IBL.
// three r155+ physical lights need ~π× legacy intensity for similar brightness.
const ambientIntensity = Math.max(0.85, interiorStyle?.ambient ?? 0.55) * Math.PI;
const lightScale = interiorStyle?.lightScale ?? 1;
const ambientIntensity = Math.max(0.85, interiorStyle?.ambient ?? 0.55) * Math.PI * lightScale;
const handleCanvasPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
if (!active || showExitNav || e.button !== 0) return;
@@ -2546,22 +2548,22 @@ export default function VirtualGallery(props: Props) {
<hemisphereLight
color={interiorStyle?.warmLight ?? '#fff8f0'}
groundColor={sceneFog}
intensity={0.55 * Math.PI}
intensity={0.55 * Math.PI * lightScale}
/>
<directionalLight
position={interiorStyle ? [2, 10, -4] : [3, 9, 4]}
intensity={(interiorStyle ? 1.4 : 0.9) * Math.PI}
intensity={(interiorStyle ? 1.4 : 0.9) * Math.PI * lightScale}
color={interiorStyle?.sunLight ?? '#fff8f0'}
/>
<directionalLight
position={[-4, 6, 5]}
intensity={0.55 * Math.PI}
intensity={0.55 * Math.PI * lightScale}
color={interiorStyle?.warmLight ?? '#fff5e8'}
/>
{/* Guaranteed fill so walls never disappear if HDR Environment fails. */}
<pointLight
position={[0, 3.2, 0]}
intensity={2.2 * Math.PI}
intensity={2.2 * Math.PI * lightScale}
distance={40}
decay={0}
color={interiorStyle?.warmLight ?? '#fff5e8'}
@@ -2573,7 +2575,7 @@ export default function VirtualGallery(props: Props) {
<Suspense fallback={null}>
<Environment
preset={interiorStyle?.details === 'modern' || interiorStyle?.details === 'industrial' ? 'city' : 'warehouse'}
environmentIntensity={interiorStyle ? 0.55 : 0.25}
environmentIntensity={(interiorStyle ? 0.55 : 0.25) * lightScale}
/>
</Suspense>
</SceneErrorBoundary>