Documentation is work in progress and not completeEditor
3D System

Texture System

Textures are uploaded per material slot, loaded through Three.js TextureLoader, cached by URL and color-managed according to the map type. Getting the color space wrong is the most common source of incorrect-looking materials.

Upload and Loading Pipeline

  • The user clicks Upload on a texture slot in the properties panel.
  • A file input accepts .png, .jpg, .jpeg and .webp.
  • createTextureFromFile() creates an object URL, loads the texture through THREE.TextureLoader, sets the color space for the map type, caches the result, and revokes the object URL immediately after loading.

Color Space Rules

Map TypeColor SpaceWhy
Color (Albedo)sRGBColor data is authored in sRGB. Three.js needs to know this to linearize it correctly before lighting calculations.
Emissive MapsRGBEmissive colors are authored in sRGB for the same reason.
All other mapsLinearRoughness, metalness, normal, bump, AO and alpha maps store non-color data — physical parameters or vectors. Loaded as sRGB, the gamma curve would distort the values.
A roughness of 0.5 loaded as sRGB reads as roughly 0.73. A color map loaded as Linear appears washed out and desaturated; a normal map loaded as sRGB produces exaggerated, incorrect surface detail.

Transform Controls

ControlThree.js PropertyVisual Effect
Repeat X/Ytexture.repeatTiles the texture. Values above 1 repeat it, below 1 stretch it
Offset X/Ytexture.offsetSlides the texture across the surface
Rotationtexture.rotationRotates the texture around the UV origin
Wrap Modetexture.wrapS / wrapTClamp stretches edge pixels; Repeat tiles seamlessly; Mirror tiles with alternating flip
Anisotropytexture.anisotropyImproves clarity at oblique angles. 1 is none, 16 is maximum, and higher costs more GPU
const wrapMap = {
  clamp: THREE.ClampToEdgeWrapping,
  repeat: THREE.RepeatWrapping,
  mirror: THREE.MirroredRepeatWrapping,
};

AO Maps and UV2

Three.js MeshStandardMaterial reads AO maps from a second UV channel (uv2). The current code applies AO maps without explicitly creating a uv2 attribute. For primitives created by Three.js the default UV coordinates serve both channels, so this works — but imported models with a separate UV2 layout may show incorrect ambient occlusion.

Disposal

Removing a texture from a slot calls disposeTextureByUrl(), which disposes the GPU texture and deletes the cache entry. Textures are not released by SceneManager.removeObject() — that method handles geometries and materials only, so texture cleanup is a separate responsibility.