From 56ae9b3cfe6d1e8f112ba55c142e2c3d70a88678 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:18:30 +1000 Subject: [PATCH 1/4] Add test for switching lightmap modes with "u" key. --- .../components/components/ModelComponent.ts | 5 +++ src/modules/scene/LightManager.ts | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/modules/scene/LightManager.ts diff --git a/src/modules/entity/components/components/ModelComponent.ts b/src/modules/entity/components/components/ModelComponent.ts index 9bf16f61..07ef7214 100644 --- a/src/modules/entity/components/components/ModelComponent.ts +++ b/src/modules/entity/components/components/ModelComponent.ts @@ -24,6 +24,7 @@ import { applicationStore } from "@Stores/index"; import Log from "@Modules/debugging/log"; import { LODManager } from "@Modules/scene/LODManager"; import { LightmapManager } from "@Modules/scene/LightmapManager"; +import { LightManager } from "@Modules/scene/LightManager"; const InteractiveModelTypes = [ { name: "chair", condition: /^(?:animate_sitting|animate_seat)/iu }, @@ -75,6 +76,10 @@ export class ModelComponent extends MeshComponent { if (this._gameObject?.getScene()) { meshes = LightmapManager.applySceneLightmapsToMeshes(meshes, this._gameObject.getScene()); } + // Light Handling + if (this._gameObject?.getScene()) { + LightManager.applyLightProperties(this._gameObject.getScene()); + } this.mesh = meshes[0]; this.renderGroupId = DEFAULT_MESH_RENDER_GROUP_ID; diff --git a/src/modules/scene/LightManager.ts b/src/modules/scene/LightManager.ts new file mode 100644 index 00000000..52cdeb07 --- /dev/null +++ b/src/modules/scene/LightManager.ts @@ -0,0 +1,39 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +// +// LightManager.ts +// +// Created by Kalila on 08 Feb 2024. +// Copyright 2024 Vircadia contributors. +// Copyright 2024 DigiSomni LLC. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import { + type Scene, +} from "@babylonjs/core"; +import Log from "../debugging/log"; + +export class LightManager { + private static handleKeyPress = (event: KeyboardEvent) => { + if (event.key === "u") { + const scene = LightManager.currentScene; // Ensure you have a reference to the current scene + const lights = scene.lights; + lights.forEach((light) => { + light.lightmapMode = (light.lightmapMode + 1) % 3; + Log.debug(Log.types.ENTITIES, `Lightmap mode for ${light.name}: ${light.lightmapMode}`); + }); + } + }; + + private static currentScene: Scene; + + public static applyLightProperties(scene: Scene): void { + this.currentScene = scene; // Store the current scene reference + + // Ensure we don't add the same event listener more than once + window.removeEventListener("keyup", this.handleKeyPress); + window.addEventListener("keyup", this.handleKeyPress); + } +} From cbf0bc9bed7807158f50ec3f213de49a8e43ae04 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:46:04 +1000 Subject: [PATCH 2/4] Revisions to handling [WIP]. --- .../components/components/ModelComponent.ts | 2 +- src/modules/scene/LODManager.ts | 34 ++++---- src/modules/scene/LightManager.ts | 15 ++-- src/modules/scene/LightmapManager.ts | 87 +++++++++++++++++-- types/vircadia_gameUse.ts | 34 ++++++-- 5 files changed, 135 insertions(+), 37 deletions(-) diff --git a/src/modules/entity/components/components/ModelComponent.ts b/src/modules/entity/components/components/ModelComponent.ts index 07ef7214..2ea785fb 100644 --- a/src/modules/entity/components/components/ModelComponent.ts +++ b/src/modules/entity/components/components/ModelComponent.ts @@ -78,7 +78,7 @@ export class ModelComponent extends MeshComponent { } // Light Handling if (this._gameObject?.getScene()) { - LightManager.applyLightProperties(this._gameObject.getScene()); + LightManager.applyLightProperties(meshes, this._gameObject.getScene()); } this.mesh = meshes[0]; diff --git a/src/modules/scene/LODManager.ts b/src/modules/scene/LODManager.ts index 59e1892c..d4f73968 100644 --- a/src/modules/scene/LODManager.ts +++ b/src/modules/scene/LODManager.ts @@ -18,15 +18,15 @@ import { // import Log from "../debugging/log"; import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; -export const StringsAsBillboardModes: { [key: string]: MeshTypes.BillboardModes } = { - none: MeshTypes.BillboardModes.BILLBOARDMODE_NONE, - x: MeshTypes.BillboardModes.BILLBOARDMODE_X, - y: MeshTypes.BillboardModes.BILLBOARDMODE_Y, - z: MeshTypes.BillboardModes.BILLBOARDMODE_Z, - all: MeshTypes.BillboardModes.BILLBOARDMODE_ALL, +export const StringsAsBillboardModes: { [key: string]: MeshTypes.BillboardMode } = { + none: MeshTypes.BillboardMode.BILLBOARDMODE_NONE, + x: MeshTypes.BillboardMode.BILLBOARDMODE_X, + y: MeshTypes.BillboardMode.BILLBOARDMODE_Y, + z: MeshTypes.BillboardMode.BILLBOARDMODE_Z, + all: MeshTypes.BillboardMode.BILLBOARDMODE_ALL, }; -export const DistanceTargets: { [key in MeshTypes.LOD.Levels]: number } = { +export const DistanceTargets: { [key in MeshTypes.LOD.Level]: number } = { LOD0: 0, LOD1: 15, LOD2: 30, @@ -34,7 +34,7 @@ export const DistanceTargets: { [key in MeshTypes.LOD.Levels]: number } = { LOD4: 120, }; -export const SizeTargets: { [key in MeshTypes.LOD.Levels]: number } = { +export const SizeTargets: { [key in MeshTypes.LOD.Level]: number } = { LOD0: 1.0, LOD1: 0.25, LOD2: 0.1, @@ -47,7 +47,7 @@ export interface AutoTarget { distance: number; optimizeMesh: boolean; } -export const AutoTargets: { [key in MeshTypes.LOD.Levels]?: AutoTarget } = { +export const AutoTargets: { [key in MeshTypes.LOD.Level]?: AutoTarget } = { LOD0: { quality: 0.9, distance: DistanceTargets.LOD0, @@ -129,8 +129,8 @@ export class LODManager { } } - private static setLODMode(mesh: Mesh, mode: MeshTypes.LOD.Modes): void { - if (mode === MeshTypes.LOD.Modes.SIZE) { + private static setLODMode(mesh: Mesh, mode: MeshTypes.LOD.Mode): void { + if (mode === MeshTypes.LOD.Mode.SIZE) { mesh.useLODScreenCoverage = true; // Log.debug( // Log.types.ENTITIES, @@ -203,7 +203,7 @@ export class LODManager { if ( // (mesh.constructor.name === "Mesh" || // mesh.constructor.name === "AbstractMesh") && - parse?.lodLevel === MeshTypes.LOD.Levels.LOD0 + parse?.lodLevel === MeshTypes.LOD.Level.LOD0 ) { roots.push({ prefix: parse?.prefix, @@ -228,7 +228,7 @@ export class LODManager { // Process metadata for root mesh. LODManager.setLODMode( roots[root].mesh, - roots[root].metadata.vircadia_lod_mode ?? MeshTypes.LOD.Modes.DISTANCE + roots[root].metadata.vircadia_lod_mode ?? MeshTypes.LOD.Mode.DISTANCE ); LODManager.setLODHide( roots[root].mesh, @@ -264,15 +264,15 @@ export class LODManager { (!(level in DistanceTargets) && !(level in SizeTargets) && !(level in AutoTargets)) || - level === MeshTypes.LOD.Levels.LOD0 + level === MeshTypes.LOD.Level.LOD0 ) { continue; } - const mode = metadata.vircadia_lod_mode ?? MeshTypes.LOD.Modes.DISTANCE; + const mode = metadata.vircadia_lod_mode ?? MeshTypes.LOD.Mode.DISTANCE; switch (mode) { - case MeshTypes.LOD.Modes.DISTANCE: { + case MeshTypes.LOD.Mode.DISTANCE: { let distanceTarget = DistanceTargets[ level as keyof typeof DistanceTargets @@ -290,7 +290,7 @@ export class LODManager { break; } - case MeshTypes.LOD.Modes.SIZE: { + case MeshTypes.LOD.Mode.SIZE: { let sizeTarget = SizeTargets[level as keyof typeof SizeTargets]; diff --git a/src/modules/scene/LightManager.ts b/src/modules/scene/LightManager.ts index 52cdeb07..ef2ff150 100644 --- a/src/modules/scene/LightManager.ts +++ b/src/modules/scene/LightManager.ts @@ -11,6 +11,7 @@ // import { + type AbstractMesh, type Scene, } from "@babylonjs/core"; import Log from "../debugging/log"; @@ -29,11 +30,15 @@ export class LightManager { private static currentScene: Scene; - public static applyLightProperties(scene: Scene): void { - this.currentScene = scene; // Store the current scene reference + public static applyLightProperties(meshes: AbstractMesh[], scene: Scene): void { + // this.currentScene = scene; // Store the current scene reference - // Ensure we don't add the same event listener more than once - window.removeEventListener("keyup", this.handleKeyPress); - window.addEventListener("keyup", this.handleKeyPress); + // // Find all the lights in the meshes as they are imported. + // const lights = meshes.filter((mesh) => mesh instanceof AbstractMesh && mesh.name.startsWith("Light_")); + // console.info("##### LIGHTS", lights); + + // // Ensure we don't add the same event listener more than once + // window.removeEventListener("keyup", this.handleKeyPress); + // window.addEventListener("keyup", this.handleKeyPress); } } diff --git a/src/modules/scene/LightmapManager.ts b/src/modules/scene/LightmapManager.ts index 825c9f01..b7c69485 100644 --- a/src/modules/scene/LightmapManager.ts +++ b/src/modules/scene/LightmapManager.ts @@ -21,6 +21,63 @@ import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; export class LightmapManager { public static applySceneLightmapsToMeshes(meshes: AbstractMesh[], scene: Scene): AbstractMesh[] { + // //// + // //// HANDLE MASTER LIGHTMAP DATA + // //// + + let lightmapColorSpace = null; + let lightmapLevel = null; + let lightmapMode = null; + + const foundLightmapMesh = meshes.find((m) => m.name.startsWith(MeshTypes.Lightmap.DATA_MESH_NAME)); + if (foundLightmapMesh) { + Log.debug(Log.types.ENTITIES, `Found lightmap mesh: ${foundLightmapMesh.name}`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const metadataExtras = foundLightmapMesh?.metadata?.gltf?.extras ?? foundLightmapMesh?.parent?.metadata?.gltf?.extras; + const metadata = new MeshTypes.Metadata(metadataExtras as Partial); + + if (metadata.vircadia_lightmap_mode) { + Log.debug(Log.types.ENTITIES, `Found lightmap mode for all meshes as ${metadata.vircadia_lightmap_mode}`); + lightmapMode = String(metadata.vircadia_lightmap_mode) as unknown as MeshTypes.Light.LightmapMode; + } + + if (metadata.vircadia_lightmap_level) { + Log.debug(Log.types.ENTITIES, `Found lightmap level for all meshes as ${metadata.vircadia_lightmap_level}`); + lightmapLevel = Number(metadata.vircadia_lightmap_level); + } + + if (metadata.vircadia_lightmap_color_space) { + Log.debug(Log.types.ENTITIES, `Found lightmap color space for all meshes as ${metadata.vircadia_lightmap_color_space}`); + lightmapColorSpace = String(metadata.vircadia_lightmap_color_space) as unknown as MeshTypes.Texture.ColorSpace; + } + + foundLightmapMesh.dispose(true, false); + Log.debug(Log.types.ENTITIES, `Deleting lightmap data mesh: ${foundLightmapMesh.name}`); + } + + const lights = scene.lights; + lights.forEach((light) => { + switch (lightmapMode) { + case MeshTypes.Light.LightmapMode.DEFAULT: + light.lightmapMode = 0; + break; + case MeshTypes.Light.LightmapMode.SHADOWSONLY: + light.lightmapMode = 1; + break; + case MeshTypes.Light.LightmapMode.SPECULAR: + light.lightmapMode = 2; + break; + default: + light.lightmapMode = 0; + break; + } + Log.debug(Log.types.ENTITIES, `Setting lightmap mode for ${light.name}: ${light.lightmapMode}`); + }); + + // //// + // //// APPLY LIGHTMAPS TO MESHES FOR EACH MESH + // //// + meshes.forEach((mesh) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const metadataExtras = mesh?.metadata?.gltf?.extras ?? mesh?.parent?.metadata?.gltf?.extras; @@ -43,7 +100,7 @@ export class LightmapManager { if (!(mesh.material instanceof PBRMaterial)) { Log.error(Log.types.ENTITIES, `Material type of ${JSON.stringify(mesh.material)} - for: ${mesh.name} is not supported for lightmap application. Need PBRMaterial. Skipping...`); + for: ${mesh.name} is not supported for lightmap application. Need PBRMaterial. Skipping...`); } const materialToUse = material as PBRMaterial; @@ -65,10 +122,30 @@ export class LightmapManager { } } - if (mesh.name.startsWith(MeshTypes.Lightmap.DATA_MESH_NAME)) { - mesh.dispose(true, false); - Log.debug(Log.types.ENTITIES, `Deleting lightmap data mesh: ${mesh.name}`); - } + mesh.material?.getActiveTextures().forEach((texture) => { + if (texture instanceof Texture) { + if (lightmapLevel) { + texture.level = lightmapLevel; + } + + if (lightmapColorSpace) { + switch (lightmapColorSpace) { + case MeshTypes.Texture.ColorSpace.LINEAR: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to linear.`); + texture.gammaSpace = false; + break; + case MeshTypes.Texture.ColorSpace.GAMMA: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); + texture.gammaSpace = true; + break; + default: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to linear.`); + texture.gammaSpace = false; + break; + } + } + } + }); }); return meshes; diff --git a/types/vircadia_gameUse.ts b/types/vircadia_gameUse.ts index 6bdafe92..8eca9e91 100644 --- a/types/vircadia_gameUse.ts +++ b/types/vircadia_gameUse.ts @@ -1,33 +1,39 @@ export namespace glTF { export interface MetadataInterface { - vircadia_lod_mode: LOD.Modes | null; + // LOD + vircadia_lod_mode: LOD.Mode | null; vircadia_lod_auto: boolean | null; vircadia_lod_distance: number | null; vircadia_lod_size: number | null; vircadia_lod_hide: number | null; + // Billboard vircadia_billboard_mode: string | null; // Lightmap vircadia_lightmap: string | null; + vircadia_lightmap_level: number | null; + vircadia_lightmap_color_space: Texture.ColorSpace | null; vircadia_lightmap_texcoord: number | null; vircadia_lightmap_use_as_shadowmap: boolean | null; - // Lightmap -> Lights - vircadia_lightmap_mode: Lightmap.Modes | null; + vircadia_lightmap_mode: Light.LightmapMode | null; } export class Metadata implements MetadataInterface { - [key: string]: LOD.Modes | Lightmap.Modes | boolean | number | string | null; + [key: string]: LOD.Mode | Light.LightmapMode | boolean | number | string | null; + // LOD public vircadia_lod_mode = null; public vircadia_lod_auto = null; public vircadia_lod_distance = null; public vircadia_lod_size = null; public vircadia_lod_hide = null; + // Billboard public vircadia_billboard_mode = null; // Lightmap public vircadia_lightmap = null; + public vircadia_lightmap_level = null; + public vircadia_lightmap_color_space = null; public vircadia_lightmap_texcoord = null; public vircadia_lightmap_use_as_shadowmap = null; - // Lightmap -> Lights public vircadia_lightmap_mode = null; constructor(metadata?: Partial>) { @@ -38,12 +44,12 @@ export namespace glTF { } export namespace LOD { - export enum Modes { + export enum Mode { DISTANCE = "distance", SIZE = "size", } - export enum Levels { + export enum Level { LOD0 = "LOD0", LOD1 = "LOD1", LOD2 = "LOD2", @@ -52,7 +58,7 @@ export namespace glTF { } } - export enum BillboardModes { + export enum BillboardMode { BILLBOARDMODE_NONE = 0, BILLBOARDMODE_X = 1, BILLBOARDMODE_Y = 2, @@ -60,10 +66,20 @@ export namespace glTF { BILLBOARDMODE_ALL = 7, } + export namespace Texture { + export enum ColorSpace { + LINEAR = "linear", + SRGB = "sRGB", + GAMMA = "gamma", + } + } + export namespace Lightmap { export const DATA_MESH_NAME = "vircadia_lightmapData"; + } - export enum Modes { + export namespace Light { + export enum LightmapMode { DEFAULT = "default", SHADOWSONLY = "shadowsOnly", SPECULAR = "specular", From d4f8484d91b4c2402f7d3cd06e63088a525b25af Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:30:52 +1000 Subject: [PATCH 3/4] Update. --- src/modules/scene/LightmapManager.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/modules/scene/LightmapManager.ts b/src/modules/scene/LightmapManager.ts index b7c69485..f74377ba 100644 --- a/src/modules/scene/LightmapManager.ts +++ b/src/modules/scene/LightmapManager.ts @@ -15,6 +15,7 @@ import { type Scene, PBRMaterial, Texture, + ImageProcessingConfiguration } from "@babylonjs/core"; import Log from "../debugging/log"; import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; @@ -25,6 +26,10 @@ export class LightmapManager { // //// HANDLE MASTER LIGHTMAP DATA // //// + // const postprocess = scene.imageProcessingConfiguration; + // postprocess.toneMappingEnabled = true; + // postprocess.toneMappingType = ImageProcessingConfiguration.TONEMAPPING_ACES; + let lightmapColorSpace = null; let lightmapLevel = null; let lightmapMode = null; @@ -138,9 +143,13 @@ export class LightmapManager { Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); texture.gammaSpace = true; break; + case MeshTypes.Texture.ColorSpace.SRGB: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to sRGB.`); + texture.gammaSpace = true; + break; default: - Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to linear.`); - texture.gammaSpace = false; + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); + texture.gammaSpace = true; break; } } From 0a052f531010b42c2fce1e11086a003acc906c13 Mon Sep 17 00:00:00 2001 From: Kalila <69767640+digisomni@users.noreply.github.com> Date: Thu, 2 May 2024 01:07:23 +1000 Subject: [PATCH 4/4] Update lightmap manager. --- .eslintrc.js | 3 +- src/modules/scene/LightmapManager.ts | 90 ++++++++++++++++------------ 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 6028795e..57978d46 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -182,6 +182,7 @@ module.exports = { "@typescript-eslint/no-use-before-define": ["error"], "no-useless-constructor": "off", "@typescript-eslint/no-useless-constructor": ["error"], + "@typescript-eslint/no-misused-promises": ["off"], "object-curly-spacing": "off", "@typescript-eslint/object-curly-spacing": ["error", "always"], quotes: "off", @@ -327,7 +328,7 @@ module.exports = { "jsx-quotes": ["error", "prefer-double"], "key-spacing": "error", // "keyword-spacing": "error", // TypeScript extension overrides. - "max-len": ["error", { code: 160, tabWidth: 4 }], + "max-len": ["error", { code: 270, tabWidth: 4 }], "multiline-ternary": ["error", "always-multiline"], "new-cap": "off", "new-parens": "error", diff --git a/src/modules/scene/LightmapManager.ts b/src/modules/scene/LightmapManager.ts index f74377ba..302dbd28 100644 --- a/src/modules/scene/LightmapManager.ts +++ b/src/modules/scene/LightmapManager.ts @@ -13,9 +13,9 @@ import { type AbstractMesh, type Scene, + BaseTexture, PBRMaterial, Texture, - ImageProcessingConfiguration } from "@babylonjs/core"; import Log from "../debugging/log"; import { glTF as MeshTypes } from "../../../types/vircadia_gameUse"; @@ -26,10 +26,6 @@ export class LightmapManager { // //// HANDLE MASTER LIGHTMAP DATA // //// - // const postprocess = scene.imageProcessingConfiguration; - // postprocess.toneMappingEnabled = true; - // postprocess.toneMappingType = ImageProcessingConfiguration.TONEMAPPING_ACES; - let lightmapColorSpace = null; let lightmapLevel = null; let lightmapMode = null; @@ -48,7 +44,7 @@ export class LightmapManager { if (metadata.vircadia_lightmap_level) { Log.debug(Log.types.ENTITIES, `Found lightmap level for all meshes as ${metadata.vircadia_lightmap_level}`); - lightmapLevel = Number(metadata.vircadia_lightmap_level); + lightmapLevel = 2; // Number(metadata.vircadia_lightmap_level); } if (metadata.vircadia_lightmap_color_space) { @@ -109,52 +105,68 @@ export class LightmapManager { } const materialToUse = material as PBRMaterial; + if (materialToUse && materialToUse.albedoTexture && mesh.material - && metadata.vircadia_lightmap_texcoord) { + && Boolean(metadata.vircadia_lightmap_texcoord)) { Texture.WhenAllReady([materialToUse.albedoTexture], () => { - (mesh.material as PBRMaterial).lightmapTexture = materialToUse.albedoTexture; - (mesh.material as PBRMaterial).useLightmapAsShadowmap = metadata.vircadia_lightmap_use_as_shadowmap ?? true; - - if ((mesh.material as PBRMaterial).lightmapTexture && metadata.vircadia_lightmap_texcoord) { - (mesh.material as PBRMaterial).lightmapTexture!.coordinatesIndex = metadata.vircadia_lightmap_texcoord; + try { + const lightmapTexture: Nullable = materialToUse.albedoTexture; + + if (lightmapTexture) { + (mesh.material as PBRMaterial).lightmapTexture = lightmapTexture; + (mesh.material as PBRMaterial).useLightmapAsShadowmap = metadata.vircadia_lightmap_use_as_shadowmap ?? true; + + if ((mesh.material as PBRMaterial).lightmapTexture && metadata.vircadia_lightmap_texcoord) { + (mesh.material as PBRMaterial).lightmapTexture!.coordinatesIndex = metadata.vircadia_lightmap_texcoord; + } + } + } catch (e) { + Log.error(Log.types.ENTITIES, `Error setting lightmap texture for: ${mesh.name}, error: ${e}`); } }); } else { + Log.error(Log.types.ENTITIES, `Could not find material or albedo texture for: ${mesh.name}`); } - } - mesh.material?.getActiveTextures().forEach((texture) => { - if (texture instanceof Texture) { - if (lightmapLevel) { - texture.level = lightmapLevel; - } - - if (lightmapColorSpace) { - switch (lightmapColorSpace) { - case MeshTypes.Texture.ColorSpace.LINEAR: - Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to linear.`); - texture.gammaSpace = false; - break; - case MeshTypes.Texture.ColorSpace.GAMMA: - Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); - texture.gammaSpace = true; - break; - case MeshTypes.Texture.ColorSpace.SRGB: - Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to sRGB.`); - texture.gammaSpace = true; - break; - default: - Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); - texture.gammaSpace = true; - break; + if (mesh.material) { + mesh.material?.getActiveTextures().forEach((texture) => { + if (texture instanceof Texture) { + if (lightmapLevel) { + texture.level = lightmapLevel; + } + + if (lightmapColorSpace) { + switch (lightmapColorSpace) { + case MeshTypes.Texture.ColorSpace.LINEAR: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to linear.`); + texture.gammaSpace = false; + break; + case MeshTypes.Texture.ColorSpace.GAMMA: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); + texture.gammaSpace = true; + break; + case MeshTypes.Texture.ColorSpace.SRGB: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to sRGB.`); + texture.gammaSpace = true; + break; + default: + Log.debug(Log.types.ENTITIES, `Setting color space for ${mesh.name} to gamma.`); + texture.gammaSpace = true; + break; + } + } + + if (lightmapLevel) { + texture.level = lightmapLevel; + } } - } + }); } - }); + } }); return meshes;