diff --git a/ogl-engine/engine/Camera.ts b/ogl-engine/engine/Camera.ts index 9057af51..1852a510 100644 --- a/ogl-engine/engine/Camera.ts +++ b/ogl-engine/engine/Camera.ts @@ -1,5 +1,5 @@ import type { FolderApi } from "tweakpane"; -import { Camera as BaseCamera, Vec3 } from "ogl"; +import { Camera as BaseCamera, Mat4, Vec3 } from "ogl"; import { getPane } from "@ui/context/Pane"; import type { Engine } from "./engine"; @@ -9,6 +9,10 @@ export class Camera extends BaseCamera { name = "Camera"; engine: Engine; + invProjectionMatrix = new Mat4(); + invViewMatrix = new Mat4(); + invViewProjectionMatrix = new Mat4(); + private paneFolder: FolderApi; constructor(engine: Engine, initPane = true) { @@ -56,4 +60,16 @@ export class Camera extends BaseCamera { cameraPos.z + t * cameraDir.z ); } + + updateMatrixWorld() { + super.updateMatrixWorld(); + + this.invProjectionMatrix.inverse(this.projectionMatrix); + this.invViewMatrix.inverse(this.viewMatrix); + this.invViewProjectionMatrix + .copy(this.invProjectionMatrix) + .multiply(this.invViewMatrix); + + return this; + } } diff --git a/ogl-engine/materials/AsteroidNew/AsteroidNew.ts b/ogl-engine/materials/AsteroidNew/AsteroidNew.ts index eca477c9..0caaace3 100644 --- a/ogl-engine/materials/AsteroidNew/AsteroidNew.ts +++ b/ogl-engine/materials/AsteroidNew/AsteroidNew.ts @@ -3,6 +3,7 @@ import { Vec3, type Texture } from "ogl"; import { assetLoader } from "@ogl-engine/AssetLoader"; import fragment from "./shader.frag.glsl"; import vertex from "../pbr/shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface AsteroidNewMaterialArgs { @@ -11,13 +12,14 @@ interface AsteroidNewMaterialArgs { } export class AsteroidNewMaterial extends Material { - uniforms: Material["uniforms"] & { - tGrunge: { value: Texture }; - tNormal: { value: Texture }; - uMask: { value: number }; - uColor: { value: Vec3 }; - uEmissive: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tGrunge: Texture; + tNormal: Texture; + uMask: number; + uColor: Vec3; + uEmissive: number; + }>; constructor(engine: Engine3D, args: AsteroidNewMaterialArgs = {}) { super(engine); diff --git a/ogl-engine/materials/AsteroidRock/AsteroidRock.ts b/ogl-engine/materials/AsteroidRock/AsteroidRock.ts index fe25f8c6..1fdded51 100644 --- a/ogl-engine/materials/AsteroidRock/AsteroidRock.ts +++ b/ogl-engine/materials/AsteroidRock/AsteroidRock.ts @@ -3,6 +3,7 @@ import { type Texture } from "ogl"; import { assetLoader } from "@ogl-engine/AssetLoader"; import fragment from "./shader.frag.glsl"; import vertex from "../pbr/shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface AsteroidRockMaterialArgs { @@ -10,10 +11,11 @@ interface AsteroidRockMaterialArgs { } export class AsteroidRockMaterial extends Material { - uniforms: Material["uniforms"] & { - tGrunge: { value: Texture }; - tNormal: { value: Texture }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tGrunge: Texture; + tNormal: Texture; + }>; constructor(engine: Engine3D, args: AsteroidRockMaterialArgs = {}) { super(engine); diff --git a/ogl-engine/materials/asteroidDust/asteroidDust.ts b/ogl-engine/materials/asteroidDust/asteroidDust.ts index fc9f06fd..c45c6d01 100644 --- a/ogl-engine/materials/asteroidDust/asteroidDust.ts +++ b/ogl-engine/materials/asteroidDust/asteroidDust.ts @@ -5,15 +5,17 @@ import { assetLoader } from "@ogl-engine/AssetLoader"; import { colorToVec3 } from "@core/utils/maps"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class AsteroidDustMaterial extends Material { - uniforms: Material["uniforms"] & { - tMap: { value: Texture }; - uColor: { value: Vec3 }; - uEmissive: { value: number }; - uAlpha: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tMap: Texture; + uColor: Vec3; + uEmissive: number; + uAlpha: number; + }>; constructor( engine: Engine3D, diff --git a/ogl-engine/materials/atmosphere/atmosphere.ts b/ogl-engine/materials/atmosphere/atmosphere.ts index c9263537..4c38fcec 100644 --- a/ogl-engine/materials/atmosphere/atmosphere.ts +++ b/ogl-engine/materials/atmosphere/atmosphere.ts @@ -2,6 +2,7 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import { Vec3 } from "ogl"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface AtmosphereMaterialArgs { @@ -11,11 +12,12 @@ interface AtmosphereMaterialArgs { } export class AtmosphereMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - uX: { value: number }; - uY: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + uX: number; + uY: number; + }>; constructor(engine: Engine3D, args: AtmosphereMaterialArgs) { super(engine); diff --git a/ogl-engine/materials/color/color.ts b/ogl-engine/materials/color/color.ts index ac619873..57bb3248 100644 --- a/ogl-engine/materials/color/color.ts +++ b/ogl-engine/materials/color/color.ts @@ -6,14 +6,16 @@ import fragment from "./shader.frag.glsl"; import fragment2d from "./shader2d.frag.glsl"; import vertex from "./shader.vert.glsl"; import vertex2d from "./shader2d.vert.glsl"; +import type { Uniforms } from "../material"; import { Material, Material2D } from "../material"; export class ColorMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - fEmissive: { value: number }; - bShaded: { value: boolean }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + fEmissive: number; + bShaded: boolean; + }>; constructor( engine: Engine3D, @@ -52,9 +54,10 @@ export class ColorMaterial extends Material { } export class ColorMaterial2D extends Material2D { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + }>; constructor(engine: Engine2D, color: string) { super(engine); diff --git a/ogl-engine/materials/engineTrail/engineTrail.ts b/ogl-engine/materials/engineTrail/engineTrail.ts index 039e1959..24f96dba 100644 --- a/ogl-engine/materials/engineTrail/engineTrail.ts +++ b/ogl-engine/materials/engineTrail/engineTrail.ts @@ -3,12 +3,14 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import Color from "color"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class EngineTrailMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + }>; constructor(engine: Engine3D, color: string) { super(engine); diff --git a/ogl-engine/materials/entityIndicator/entityIndicator.ts b/ogl-engine/materials/entityIndicator/entityIndicator.ts index 18208f93..a3bf3a0b 100644 --- a/ogl-engine/materials/entityIndicator/entityIndicator.ts +++ b/ogl-engine/materials/entityIndicator/entityIndicator.ts @@ -4,17 +4,19 @@ import type { DockSize } from "@core/components/dockable"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class EntityIndicatorMaterial extends Material { - uniforms: Material["uniforms"] & { - uSize: { value: number }; - uColor: { value: Vec4 }; - uHp: { value: number }; - uShield: { value: number }; - uHovered: { value: number }; - uSelected: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uSize: number; + uColor: Vec4; + uHp: number; + uShield: number; + uHovered: number; + uSelected: number; + }>; constructor(engine: Engine3D) { super(engine); diff --git a/ogl-engine/materials/entityName/entityName.ts b/ogl-engine/materials/entityName/entityName.ts index 4398a1c2..cab01454 100644 --- a/ogl-engine/materials/entityName/entityName.ts +++ b/ogl-engine/materials/entityName/entityName.ts @@ -5,14 +5,16 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import type { DockSize } from "@core/components/dockable"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class EntityNameMaterial extends Material { - uniforms: Material["uniforms"] & { - tMap: { value: Texture }; - uOffset: { value: number }; - uColor: { value: Vec3 }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tMap: Texture; + uOffset: number; + uColor: Vec3; + }>; constructor(engine: Engine3D, texture: Texture) { super(engine); diff --git a/ogl-engine/materials/kineticGun/kineticGun.ts b/ogl-engine/materials/kineticGun/kineticGun.ts index 688ddeee..b131a3dc 100644 --- a/ogl-engine/materials/kineticGun/kineticGun.ts +++ b/ogl-engine/materials/kineticGun/kineticGun.ts @@ -2,6 +2,7 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import { Vec4 } from "ogl"; import fragment from "./shader.frag.glsl"; import vertex from "../orb/shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface KineticGunMaterialArgs { @@ -9,9 +10,10 @@ interface KineticGunMaterialArgs { } export class KineticGunMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec4 }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec4; + }>; constructor(engine: Engine3D, args: KineticGunMaterialArgs) { super(engine); diff --git a/ogl-engine/materials/laser/laser.ts b/ogl-engine/materials/laser/laser.ts index 45c06407..59a45826 100644 --- a/ogl-engine/materials/laser/laser.ts +++ b/ogl-engine/materials/laser/laser.ts @@ -2,7 +2,7 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import { Vec3 } from "ogl"; import fragment from "./shader.frag.glsl"; import vertex from "../base.vert.glsl"; -import type { Uniform } from "../material"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface LaserMaterialArgs { @@ -10,11 +10,12 @@ interface LaserMaterialArgs { } export class LaserMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: Uniform; - uIntensity: Uniform; - uAspectRatio: Uniform; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + uIntensity: number; + uAspectRatio: number; + }>; constructor(engine: Engine3D, { color }: LaserMaterialArgs) { super(engine); diff --git a/ogl-engine/materials/laserImpact/laserImpact.ts b/ogl-engine/materials/laserImpact/laserImpact.ts index 927b3085..0372da70 100644 --- a/ogl-engine/materials/laserImpact/laserImpact.ts +++ b/ogl-engine/materials/laserImpact/laserImpact.ts @@ -2,7 +2,7 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import { Vec3 } from "ogl"; import fragment from "./shader.frag.glsl"; import vertex from "../base.vert.glsl"; -import type { Uniform } from "../material"; +import type { Uniforms } from "../material"; import { Material } from "../material"; interface LaserImpactMaterialArgs { @@ -10,10 +10,11 @@ interface LaserImpactMaterialArgs { } export class LaserImpactMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: Uniform; - uIntensity: Uniform; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + uIntensity: number; + }>; constructor(engine: Engine3D, { color }: LaserImpactMaterialArgs) { super(engine); diff --git a/ogl-engine/materials/material.ts b/ogl-engine/materials/material.ts index 096e4ba2..05a75270 100644 --- a/ogl-engine/materials/material.ts +++ b/ogl-engine/materials/material.ts @@ -4,27 +4,35 @@ import { entries, join, map, pipe } from "@fxts/core"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import type { Light } from "@ogl-engine/engine/Light"; import Color from "color"; -import type { ProgramOptions, Mesh, Vec3, Vec4, Vec2 } from "ogl"; +import type { ProgramOptions, Mesh, Vec3, Vec4, Mat4 } from "ogl"; import { Texture, Program } from "ogl"; import type { BindingParams, FolderApi } from "tweakpane"; import { getPane } from "@ui/context/Pane"; -export interface Uniform { +export interface Uniform { value: T; meta?: { pane?: BindingParams; }; } +export type Uniforms> = { + [K in keyof T]: Uniform; +}; + export abstract class Material { engine: Engine3D; protected program: Program; - protected uniforms: { - ambient: { value: Vec3 }; + protected uniforms: Uniforms<{ + ambient: Vec3; + uTime: number; + tEnvMap: Texture; + uCameraScale: number; + invProjectionMatrix: Mat4; + invViewMatrix: Mat4; + invViewProjectionMatrix: Mat4; + }> & { lights: Light["uniforms"][]; - uTime: { value: number }; - tEnvMap: { value: Texture }; - uCameraScale: { value: number }; }; constructor(engine: Engine3D) { @@ -35,6 +43,9 @@ export abstract class Material { uTime: engine.uniforms.uTime, tEnvMap: engine.uniforms.env.tEnvMap, uCameraScale: { value: Math.log2(engine.camera.far) }, + invProjectionMatrix: { value: engine.camera.invProjectionMatrix }, + invViewMatrix: { value: engine.camera.invViewMatrix }, + invViewProjectionMatrix: { value: engine.camera.invViewProjectionMatrix }, }; } @@ -116,12 +127,12 @@ export abstract class Material { }); } - static colorToVec3(color: string, uniform: { value: Vec3 }) { + static colorToVec3(color: string, uniform: Uniform) { const c = Color(color).rgb().array(); uniform.value.set(c[0], c[1], c[2]).divide(255); } - static colorToVec4(color: string, uniform: { value: Vec4 }) { + static colorToVec4(color: string, uniform: Uniform) { const c = Color(color).rgb(); uniform.value.set( c.red() / 255, diff --git a/ogl-engine/materials/msdf/msdf.ts b/ogl-engine/materials/msdf/msdf.ts index c626cd7d..f638dc4f 100644 --- a/ogl-engine/materials/msdf/msdf.ts +++ b/ogl-engine/materials/msdf/msdf.ts @@ -4,13 +4,15 @@ import type { Engine } from "@ogl-engine/engine/engine"; import Color from "color"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { MaterialAny } from "../material"; export class MSDFMaterial extends MaterialAny { - uniforms: MaterialAny["uniforms"] & { - tMap: { value: Texture }; - uColor: { value: Vec3 }; - }; + uniforms: MaterialAny["uniforms"] & + Uniforms<{ + tMap: Texture; + uColor: Vec3; + }>; constructor(engine: Engine, texture: Texture) { super(engine); diff --git a/ogl-engine/materials/orb/orb.ts b/ogl-engine/materials/orb/orb.ts index 2505970b..9a0e7738 100644 --- a/ogl-engine/materials/orb/orb.ts +++ b/ogl-engine/materials/orb/orb.ts @@ -2,14 +2,16 @@ import type { Vec4 } from "ogl"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class OrbMaterial extends Material { - uniforms: Material["uniforms"] & { - uStart: { value: Vec4 }; - uEnd: { value: Vec4 }; - fEmissive: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uStart: Vec4; + uEnd: Vec4; + fEmissive: number; + }>; constructor(engine: Engine3D, start: Vec4, end: Vec4, global = true) { super(engine); diff --git a/ogl-engine/materials/particleCloud/particleCloud.ts b/ogl-engine/materials/particleCloud/particleCloud.ts index d4e0cb4b..dd089f97 100644 --- a/ogl-engine/materials/particleCloud/particleCloud.ts +++ b/ogl-engine/materials/particleCloud/particleCloud.ts @@ -5,15 +5,17 @@ import { assetLoader } from "@ogl-engine/AssetLoader"; import { colorToVec3 } from "@core/utils/maps"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class ParticleCloudMaterial extends Material { - uniforms: Material["uniforms"] & { - tMap: { value: Texture }; - uColor: { value: Vec3 }; - uEmissive: { value: number }; - uAlpha: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tMap: Texture; + uColor: Vec3; + uEmissive: number; + uAlpha: number; + }>; constructor( engine: Engine3D, diff --git a/ogl-engine/materials/pbr/pbr.ts b/ogl-engine/materials/pbr/pbr.ts index 6ae046c1..30587bcc 100644 --- a/ogl-engine/materials/pbr/pbr.ts +++ b/ogl-engine/materials/pbr/pbr.ts @@ -2,17 +2,19 @@ import type { GLTFMaterial, Texture } from "ogl"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class PbrMaterial extends Material { - uniforms: Material["uniforms"] & { - tDiffuse: { value: Texture }; - tNormal: { value: Texture }; - tRoughness: { value: Texture }; - uRoughness: { value: number }; - tEmissive: { value: Texture }; - uMetallic: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tDiffuse: Texture; + tNormal: Texture; + tRoughness: Texture; + uRoughness: number; + tEmissive: Texture; + uMetallic: number; + }>; constructor( engine: Engine3D, diff --git a/ogl-engine/materials/selectionBox/selectionBox.ts b/ogl-engine/materials/selectionBox/selectionBox.ts index 90170269..c629b764 100644 --- a/ogl-engine/materials/selectionBox/selectionBox.ts +++ b/ogl-engine/materials/selectionBox/selectionBox.ts @@ -1,14 +1,16 @@ import { Program } from "ogl"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; +import type { Uniforms } from "../material"; import { Material } from "../material"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; export class SelectionBoxMaterial extends Material { - uniforms: Material["uniforms"] & { - lineWidthX: { value: number }; - lineWidthY: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + lineWidthX: number; + lineWidthY: number; + }>; constructor(engine: Engine3D) { super(engine); diff --git a/ogl-engine/materials/spritesheet/spritesheet.ts b/ogl-engine/materials/spritesheet/spritesheet.ts index 274b9e48..8ad023e8 100644 --- a/ogl-engine/materials/spritesheet/spritesheet.ts +++ b/ogl-engine/materials/spritesheet/spritesheet.ts @@ -1,17 +1,19 @@ import type { Texture } from "ogl"; import { Program, Vec4 } from "ogl"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; +import type { Uniforms } from "../material"; import { Material } from "../material"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; export class SpritesheetMaterial extends Material { - uniforms: Material["uniforms"] & { - tDiffuse: { value: Texture }; - sprite: { value: Vec4 }; - fAlpha: { value: number }; - fEmissive: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tDiffuse: Texture; + sprite: Vec4; + fAlpha: number; + fEmissive: number; + }>; index: number; constructor( diff --git a/ogl-engine/materials/star/star.ts b/ogl-engine/materials/star/star.ts index e8c84c6b..cb11de3e 100644 --- a/ogl-engine/materials/star/star.ts +++ b/ogl-engine/materials/star/star.ts @@ -4,17 +4,19 @@ import smoke from "@assets/textures/smoke.jpg"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class StarMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - uColor2: { value: Vec3 }; - tSmoke: { value: Texture }; - uNoise: { value: number }; - uNoisePower: { value: number }; - uEmissive: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + uColor2: Vec3; + tSmoke: Texture; + uNoise: number; + uNoisePower: number; + uEmissive: number; + }>; constructor(engine: Engine3D) { super(engine); diff --git a/ogl-engine/materials/starCorona/starCorona.ts b/ogl-engine/materials/starCorona/starCorona.ts index 96e44903..73573679 100644 --- a/ogl-engine/materials/starCorona/starCorona.ts +++ b/ogl-engine/materials/starCorona/starCorona.ts @@ -4,12 +4,14 @@ import type { Engine3D } from "@ogl-engine/engine/engine3d"; import Color from "color"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class StarCoronaMaterial extends Material { - uniforms: Material["uniforms"] & { - uColor: { value: Vec3 }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + uColor: Vec3; + }>; constructor(engine: Engine3D, color: Vec3) { super(engine); diff --git a/ogl-engine/materials/tintedTexture/tintedTexture.ts b/ogl-engine/materials/tintedTexture/tintedTexture.ts index 4ac31e56..0f7484bc 100644 --- a/ogl-engine/materials/tintedTexture/tintedTexture.ts +++ b/ogl-engine/materials/tintedTexture/tintedTexture.ts @@ -4,14 +4,16 @@ import Color from "color"; import type { Engine3D } from "@ogl-engine/engine/engine3d"; import fragment from "./shader.frag.glsl"; import vertex from "./shader.vert.glsl"; +import type { Uniforms } from "../material"; import { Material } from "../material"; export class TintedTextureMaterial extends Material { - uniforms: Material["uniforms"] & { - tMap: { value: Texture }; - uColor: { value: Vec3 }; - fEmissive: { value: number }; - }; + uniforms: Material["uniforms"] & + Uniforms<{ + tMap: Texture; + uColor: Vec3; + fEmissive: number; + }>; constructor(engine: Engine3D, texture: Texture, color?: string) { super(engine);