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.
This commit is contained in:
Mark Greene committed 2026-10-30 17:26:50 +13:00
1 parent c772d47a07
commit c535811c1d
2 files changed
+43 -6

No files matched your search

@@ -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<MeshStandardMaterial>();
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<number>) {
applyIntensity(event.data);
}
applyIntensity(transitionEvent.last!);
transitionEvent.on(handleTransitionEvent);
return () => {
transitionEvent.off(handleTransitionEvent);
};
}, [gltf, skinGltf, attachmentGltf]);
return (
<ModelTankWrapper ref={hullContainer}>
{nodes.map((node) => {
@@ -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) {