From c535811c1d2a06932e1bde364d9e0d958cd15e59 Mon Sep 17 00:00:00 2001 From: Mark Greene Date: Fri, 30 Oct 2026 17:26:50 +1300 Subject: [PATCH] Fix: Fade glowing camouflage parts with the lights Unlit `Textured` materials loaded as `MeshBasicMaterial`, so they stayed bright while the lights receded during a camouflage switch (E 100 legendary camouflage). - `Textured` materials now export as standard materials with the base color texture as emissive and a black base color, so they look the same as before. - The Tankopedia model fades their emissive intensity with the lighting transition. - Additive blending applies to these parts again, since they are standard materials. --- .../TankSandbox/components/TankModel.tsx | 38 ++++++++++++++++++- .../[...chunk_models_tanks]/[id]/model.glb.ts | 11 +++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx index 88ac06c6e..718ca7bbd 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx @@ -1,5 +1,6 @@ import { invalidate, useThree, type ThreeEvent } from "@react-three/fiber"; -import { useRef } from "react"; +import type { QuicklimeEvent } from "quicklime"; +import { useEffect, useRef } from "react"; import { Group, Mesh, MeshStandardMaterial, Vector2 } from "three"; import { applyPitchYawLimits } from "../../../../../../core/blitz/applyPitchYawLimits"; import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment"; @@ -14,6 +15,7 @@ import { Duel } from "../../../../../../stores/duel"; import { Tankopedia } from "../../../../../../stores/tankopedia"; import { TankopediaDisplay } from "../../../../../../stores/tankopediaPersistent/constants"; import { ModelTankWrapper } from "../../../../../Armor/components/ModelTankWrapper"; +import { transitionEvent } from "./Lighting"; export function TankModel() { const protagonist = Duel.use((draft) => draft.protagonist); @@ -35,6 +37,40 @@ export function TankModel() { useTankTransform(track, turret, turretContainer, gunContainer); + useEffect(() => { + const emissiveMaterials = new Set(); + + for (const scene of [gltf.scene, ...skins.map((skin) => skin.scene)]) { + scene.traverse((object) => { + if ( + object instanceof Mesh && + object.material instanceof MeshStandardMaterial && + object.material.emissiveMap + ) { + emissiveMaterials.add(object.material); + } + }); + } + + // emissive parts fade with the lights instead of glowing in the dark + function applyIntensity(intensity: number) { + for (const material of emissiveMaterials) { + material.emissiveIntensity = intensity; + } + } + + function handleTransitionEvent(event: QuicklimeEvent) { + applyIntensity(event.data); + } + + applyIntensity(transitionEvent.last!); + transitionEvent.on(handleTransitionEvent); + + return () => { + transitionEvent.off(handleTransitionEvent); + }; + }, [gltf, skinGltf, attachmentGltf]); + return ( {nodes.map((node) => { diff --git a/packages/website/src/pages/[...chunk_models_tanks]/[id]/model.glb.ts b/packages/website/src/pages/[...chunk_models_tanks]/[id]/model.glb.ts index 771655ba0..d0b9d70ef 100644 --- a/packages/website/src/pages/[...chunk_models_tanks]/[id]/model.glb.ts +++ b/packages/website/src/pages/[...chunk_models_tanks]/[id]/model.glb.ts @@ -14,7 +14,7 @@ import { } from "@blitzkit/core"; import type { AbstractVFS } from "@blitzkit/core/src/blitzkit/vfs/abstract"; import { Document, Material, Node, NodeIO, Scene } from "@gltf-transform/core"; -import { ALL_EXTENSIONS, KHRMaterialsUnlit } from "@gltf-transform/extensions"; +import { ALL_EXTENSIONS } from "@gltf-transform/extensions"; import { dedup, prune } from "@gltf-transform/functions"; import type { APIContext } from "astro"; import { isEqual, times } from "lodash-es"; @@ -366,10 +366,11 @@ export async function extractMaterials( } if (fxName?.endsWith("/Textured.material")) { - material.setExtension( - "KHR_materials_unlit", - document.createExtension(KHRMaterialsUnlit).createUnlit(), - ); + // unlit in game, emissive so the viewer can fade it with the lights + material + .setEmissiveTexture(material.getBaseColorTexture()) + .setEmissiveFactor([1, 1, 1]) + .setBaseColorFactor([0, 0, 0, 1]); } if (textures.miscMap) {