Files
editor/packages/core/src/material-library.ts
T
a71de82ccb nodes: add MEP movement controls and DWV parity (#438)
* Add roof surface placement support for items

Items (e.g. solar panels) can now be placed on sloped roof surfaces.
The placement system computes euler rotation from the roof surface
normal so items sit flush on the slope instead of going inside.

- Add roofStrategy to placement-strategies with enter/move/click/leave
- Wire roof:enter/move/click/leave events in the placement coordinator
- Add calculateRoofRotation in placement-math using surface normals
- Support full 3D cursor rotation for sloped surfaces
- Items on roofs are parented to the level with world-space rotation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fixed conflict

* feat(duct): ceiling-snap drawing + connected-joint endpoint move

Duct draw tool's ceiling mode now hangs each path point just below the
ceiling actually covering it (per-room heights tracked), with a
translucent surface highlight and a plumb line to the floor so the
in-flight point reads clearly from any angle.

Dragging a duct corner that sits on a fitting now carries the fitting's
other ducts along (port-connectivity second hop), so the joint moves
together instead of tearing apart.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): detach + vertical modifiers for duct/pipe joint editing

Alt detaches a dragged duct/pipe endpoint or fitting from its connected
joint (no elbow re-aim, no connectivity follow); Ctrl/Cmd drives vertical
riser movement on the fitting move. Behavioral parity across 2D and 3D.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): full DWV pipe parity for joint editing

Bring pipe-segment endpoint drags and pipe-fitting moves to parity with
duct: free-drag endpoints, Alt-detach, Ctrl/Cmd-vertical riser, elbow
re-aim, and connectivity follow. Generalizes the shared elbow-reaim and
auto-fitting helpers to dispatch by run kind so 2D and 3D share one path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): wall-style arrow handles for duct fittings + segments

Add violet directional arrow affordances to duct-fitting selection (height,
move cross, rotate arc) mirroring the duct-segment rig: portaled into the
parent frame to stay out of the selection outline, rendered via the shared
HandleArrow, and carrying mated-run connectivity through the single-undo
dance. The move cross engages press-drag-release (placementDragMode) the same
way the floating drag does, so the markup hit-areas go inert and the fitting
move tool commits on pointer-up.

Also re-export the HandleArrow primitives from @pascal-app/editor and extend
the duct-segment side-move/floorplan affordances.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): click-to-latch cube handles for duct + fitting editing

Replace the hover-reveal / multi-handle selection rigs with a single
click-to-latch cube that opens a directional cluster, shared between
duct segments and fittings via a new selection-handles module
(HandleCube / MoveChevron / RotateArc, all sized to the roof pitch cube).

- Duct segment: per-vertex + run-center cubes reveal axis-locked move
  chevrons (down arrow always shown), plus a roll arc at the run center.
- Duct fitting: center cube reveals six ±XYZ move arrows and three
  per-axis rotation arcs (oriented in place), replacing the old
  height/move/rotate trio with axis-cycling.
- Rotation (fitting arcs + duct roll) snaps to 45° steps; Shift = smooth.
- thin chevron profile + press-drag-release commit retained.

* fix(mep): orient duct roll arc consistently + drop Ctrl-vertical drag

Build a fully-determined basis for the duct roll gizmo so the curved
arrow always seats at the top-outer 45° corner regardless of run
direction, instead of an arbitrary apex from a single setFromUnitVectors.
The selection-rig ±Y arrows now own vertical movement, so the redundant
Ctrl-modifier riser drag is removed from the fitting move tool.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): run-aligned duct handles, swing snapping, elbow flatten

Align the duct run-center cube + horizontal arrows to the run axis
(matching the per-vertex handles) while keeping whole-run translate.
Endpoint side / up-down swing arrows now follow grid snap points and
port-snap onto nearby collars (Shift sweeps smoothly). Relax elbow
realign + fitting schemas to flatten to a straight 0° coupling. Surface
HVAC-specific hints in the select-mode helper panel for duct / fitting.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): per-segment linesets/liquid-lines with joint-follow editing

Linesets and liquid lines now commit one independent two-point node per
drawn segment instead of folding into a single mitered polyline, so each
line selects and deletes on its own. Endpoint caps fill shared-coordinate
joints so connected segments still read as continuous pipe.

Dragging a shared endpoint carries mated segments along via port
connectivity (Alt detaches), so a run still edits as one welded piece.
Liquid-line follow mode traces the whole connected lineset run, laying a
per-segment parallel line down its full assembled length.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(mep): vertical-offset auto-routing on duct center-cube ±Y drag

Lifting/lowering a connected run with the run-center cube now keeps each
connected end welded to its stationary partner instead of dragging the
whole network. Run-to-run ends get the classic S/Z offset (two elbows +
plumb riser, partner trimmed back one leg); elbow-connected ends form a
clean L — the existing elbow stays put and re-aims its collar vertical,
with one new top elbow + riser reconnecting to the lifted endpoint. The
offset is ghosted live and minted as a single undo step on release.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Add roof accessory placement guides

Measure roof accessory placement against the active roof face using visible surface bounds and preview geometry footprints. Add dormer-local guides and special linear handling for ridge vents and gutters.

* Improve duct and placement routing

* Fix duct vertical movement routing

* Fix duct vertical offsets and roof accessory movement

* Add DWV movement parity and line endpoint controls

* Fix MEP handle review issues

* Fix chimney placement and duct offset cleanup

* Use snapped targets for roof accessory commits

* fix(nodes): repair MEP movement review issues

- auto-fitting: tee branch now follows the drawn lateral angle; update the
  stale square-tee test + doc comment that contradicted the rewrite
- duct-segment: re-enable the vertical auto-offset rewind (the disabled stub
  left mintedIds empty, so re-dragging a tagged duct stranded old elbows/risers
  and stacked duplicates); remove the dead stub
- duct-segment: strip the stale auto-offset tag on manual corner/roll commits
  so the horizontal-move path no longer trusts an out-of-date base
- chimney: resume history before mutating segment children arrays so a
  cross-segment move reparents in one tracked transaction (undo stays consistent)
- dormer: align schema test with the new windowSill=false default

* fix: address mep movement review issues

* fix: address follow-up mep review comments

* fix: address additional mep review comments

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: pascal-open-bot <open@pascal.app>
2026-06-23 08:37:15 -04:00

4217 lines
114 KiB
TypeScript

import {
type MaterialPresetPayload,
type MaterialTarget,
MaterialTarget as MaterialTargetSchema,
} from './schema/material'
export type MaterialCatalogItem = {
id: string
label: string
category: MaterialCategory
/**
* Where this finish is appropriate. Absent = universal (e.g. flat colors).
* The paint picker may filter by the slot being painted; v1 shows everything.
*/
surfaces?: MaterialSurface[]
description?: string
previewThumbnailUrl?: string
previewColor?: string
preset: MaterialPresetPayload
}
const WALL_TARGETS: MaterialTarget[] = [
MaterialTargetSchema.enum.wall,
MaterialTargetSchema.enum.chimney,
MaterialTargetSchema.enum.dormer,
]
const SLAB_TARGETS: MaterialTarget[] = [
MaterialTargetSchema.enum.slab,
MaterialTargetSchema.enum.chimney,
]
const WALL_AND_SLAB_TARGETS: MaterialTarget[] = [
MaterialTargetSchema.enum.wall,
MaterialTargetSchema.enum.slab,
MaterialTargetSchema.enum.chimney,
MaterialTargetSchema.enum.dormer,
]
const STAIR_TARGETS: MaterialTarget[] = [
MaterialTargetSchema.enum.stair,
MaterialTargetSchema.enum['stair-segment'],
]
const STAIR_AND_FENCE_TARGETS: MaterialTarget[] = [
...STAIR_TARGETS,
MaterialTargetSchema.enum.fence,
]
const ROOF_TARGETS: MaterialTarget[] = [
MaterialTargetSchema.enum.roof,
MaterialTargetSchema.enum['roof-segment'],
MaterialTargetSchema.enum.chimney,
MaterialTargetSchema.enum.dormer,
]
const CEILING_TARGETS: MaterialTarget[] = [MaterialTargetSchema.enum.ceiling]
export const MATERIAL_CATEGORIES = [
'colors',
'wood',
'stone',
'brick',
'tile',
'concrete',
'metal',
'fabric',
'leather',
'roofing',
'ground',
'glass',
] as const
export type MaterialCategory = (typeof MATERIAL_CATEGORIES)[number]
export const MATERIAL_SURFACES = [
'floor',
'wall',
'ceiling',
'roof',
'furniture',
'outdoor',
] as const
export type MaterialSurface = (typeof MATERIAL_SURFACES)[number]
export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
{
id: 'wood-finewood27',
label: 'Finewood 27',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/finewood_27/finewood_27_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/finewood_27/finewood_27_basecolor.webp',
aoMap: '/material/wood/finewood_27/finewood_27_ambientocclusion.webp',
normalMap: '/material/wood/finewood_27/finewood_27_normal.webp',
roughnessMap: '/material/wood/finewood_27/finewood_27_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-floorplank1',
label: 'Floor Plank 1',
category: 'wood',
surfaces: ['floor'],
description: 'Wood plank finish',
previewThumbnailUrl: '/material/wood/floor_plank_1/floor_plank-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/floor_plank_1/floor_plank-diffuse.webp',
aoMap: '/material/wood/floor_plank_1/floor_plank-ao.webp',
metalnessMap: '/material/wood/floor_plank_1/floor_plank-specular.webp',
normalMap: '/material/wood/floor_plank_1/floor_plank-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 0.4,
repeatY: 0.4,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-hungarianparquet10',
label: 'Hungarian Parquet 10',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
metalnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_normal.webp',
roughnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-hungarianparquet2',
label: 'Hungarian Parquet 2',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
metalnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_normal.webp',
roughnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-squareparquet21',
label: 'Square Parquet 21',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl:
'/material/wood/square_parquet_21/Square Pattern Parquet_21_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_baseColor.webp',
metalnessMap:
'/material/wood/square_parquet_21/Square Pattern Parquet_21_specularLevel.webp',
normalMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_normal.webp',
roughnessMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-squareparquet23',
label: 'Square Parquet 23',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
metalnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_specularLevel.webp',
normalMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_normal.webp',
roughnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine1',
label: 'Wood Fine 1',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine/wood_fine_1-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine/wood_fine_1-diffuse.webp',
aoMap: '/material/wood/wood_fine/wood_fine_1-ao.webp',
metalnessMap: '/material/wood/wood_fine/wood_fine_1-specular.webp',
normalMap: '/material/wood/wood_fine/wood_fine_1-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine11',
label: 'Wood Fine 11',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine_11/wood_fine_11-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine_11/wood_fine_11-diffuse.webp',
aoMap: '/material/wood/wood_fine_11/wood_fine_11-ao.webp',
metalnessMap: '/material/wood/wood_fine_11/wood_fine_11-specular.webp',
normalMap: '/material/wood/wood_fine_11/wood_fine_11-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine13',
label: 'Wood Fine 13',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine_13/wood_fine_13-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine_13/wood_fine_13-diffuse.webp',
aoMap: '/material/wood/wood_fine_13/wood_fine_13-ao.webp',
metalnessMap: '/material/wood/wood_fine_13/wood_fine_13-specular.webp',
normalMap: '/material/wood/wood_fine_13/wood_fine_13-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine2',
label: 'Wood Fine 2',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine_2/wood_fine_2-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine_2/wood_fine_2-diffuse.webp',
aoMap: '/material/wood/wood_fine_2/wood_fine_2-ao.webp',
metalnessMap: '/material/wood/wood_fine_2/wood_fine_2-specular.webp',
normalMap: '/material/wood/wood_fine_2/wood_fine_2-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine22',
label: 'Wood Fine 22',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine_22/wood_fine_22-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine_22/wood_fine_22-diffuse.webp',
aoMap: '/material/wood/wood_fine_22/wood_fine_22-ao.webp',
metalnessMap: '/material/wood/wood_fine_22/wood_fine_22-specular.webp',
normalMap: '/material/wood/wood_fine_22/wood_fine_22-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodfine24',
label: 'Wood Fine 24',
category: 'wood',
surfaces: ['floor', 'wall', 'furniture'],
description: 'Fine wood finish',
previewThumbnailUrl: '/material/wood/wood_fine_24/wood_fine_24-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_fine_24/wood_fine_24-diffuse.webp',
aoMap: '/material/wood/wood_fine_24/wood_fine_24-ao.webp',
metalnessMap: '/material/wood/wood_fine_24/wood_fine_24-specular.webp',
normalMap: '/material/wood/wood_fine_24/wood_fine_24-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodparquet14',
label: 'Wood Parquet 14',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/wood_parquet_14/woodparquet_14_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/wood_parquet_14/woodparquet_14_basecolor.webp',
aoMap: '/material/wood/wood_parquet_14/woodparquet_14_ambientocclusion.webp',
metalnessMap: '/material/wood/wood_parquet_14/woodparquet_14_metallic.webp',
normalMap: '/material/wood/wood_parquet_14/woodparquet_14_normal.webp',
roughnessMap: '/material/wood/wood_parquet_14/woodparquet_14_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodenparquet11',
label: 'Wooden Parquet 11',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/wooden_parquet_11/Classic Parquet_11_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/wooden_parquet_11/Classic Parquet_11_baseColor.webp',
metalnessMap: '/material/wood/wooden_parquet_11/Classic Parquet_11_specularLevel.webp',
normalMap: '/material/wood/wooden_parquet_11/Classic Parquet_11_normal.webp',
roughnessMap: '/material/wood/wooden_parquet_11/Classic Parquet_11_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodparquet121',
label: 'Wood Parquet 121',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/woodparquet_121/woodparquet_121_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodparquet_121/woodparquet_121_basecolor.webp',
aoMap: '/material/wood/woodparquet_121/woodparquet_121_ambientocclusion.webp',
normalMap: '/material/wood/woodparquet_121/woodparquet_121_normal.webp',
roughnessMap: '/material/wood/woodparquet_121/woodparquet_121_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodparquet56',
label: 'Wood Parquet 56',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/woodparquet_56/woodparquet_56_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodparquet_56/woodparquet_56_basecolor.webp',
aoMap: '/material/wood/woodparquet_56/woodparquet_56_ambientocclusion.webp',
metalnessMap: '/material/wood/woodparquet_56/woodparquet_56_metallic.webp',
normalMap: '/material/wood/woodparquet_56/woodparquet_56_normal.webp',
roughnessMap: '/material/wood/woodparquet_56/woodparquet_56_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodparquet65',
label: 'Wood Parquet 65',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/woodparquet_65/woodparquet_65_BaseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodparquet_65/woodparquet_65_BaseColor.webp',
aoMap: '/material/wood/woodparquet_65/woodparquet_65_AmbientOcclusion.webp',
metalnessMap: '/material/wood/woodparquet_65/woodparquet_65_Metallic.webp',
normalMap: '/material/wood/woodparquet_65/woodparquet_65_Normal.webp',
roughnessMap: '/material/wood/woodparquet_65/woodparquet_65_Roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodparquet99',
label: 'Wood Parquet 99',
category: 'wood',
surfaces: ['floor'],
description: 'Parquet wood finish',
previewThumbnailUrl: '/material/wood/woodparquet_99/woodparquet_99_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodparquet_99/woodparquet_99_basecolor.webp',
aoMap: '/material/wood/woodparquet_99/woodparquet_99_ambientocclusion.webp',
metalnessMap: '/material/wood/woodparquet_99/woodparquet_99_metallic.webp',
normalMap: '/material/wood/woodparquet_99/woodparquet_99_normal.webp',
roughnessMap: '/material/wood/woodparquet_99/woodparquet_99_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodplank19',
label: 'Wood Plank 19',
category: 'wood',
surfaces: ['floor', 'wall'],
description: 'Wood plank finish',
previewThumbnailUrl: '/material/wood/woodplank_19/woodplank_19_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodplank_19/woodplank_19_basecolor.webp',
aoMap: '/material/wood/woodplank_19/woodplank_19_ambientocclusion.webp',
normalMap: '/material/wood/woodplank_19/woodplank_19_normal.webp',
roughnessMap: '/material/wood/woodplank_19/woodplank_19_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'wood-woodplank48',
label: 'Wood Plank 48',
category: 'wood',
surfaces: ['floor', 'wall'],
description: 'Wood plank finish',
previewThumbnailUrl: '/material/wood/woodplank_48/woodplank_48_BaseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/woodplank_48/woodplank_48_BaseColor.webp',
aoMap: '/material/wood/woodplank_48/woodplank_48_AmbientOcclusion.webp',
normalMap: '/material/wood/woodplank_48/woodplank_48_Normal.webp',
roughnessMap: '/material/wood/woodplank_48/woodplank_48_Roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tile85a',
label: 'Quarry Tile',
category: 'tile',
surfaces: ['floor'],
description: 'Floor tile finish',
previewThumbnailUrl: '/material/flooring/tile_quarry/tile_quarry_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/tile_quarry/tile_quarry_basecolor.webp',
aoMap: '/material/flooring/tile_quarry/tile_quarry_ambientocclusion.webp',
normalMap: '/material/flooring/tile_quarry/tile_quarry_normal.webp',
roughnessMap: '/material/flooring/tile_quarry/tile_quarry_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.3,
repeatY: 0.3,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-rusticbrick',
label: 'Rustic Brick',
category: 'brick',
surfaces: ['wall', 'floor', 'outdoor'],
description: 'Brick finish',
previewThumbnailUrl: '/material/flooring/brick_wall_rustic/brick_wall_rustic_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/brick_wall_rustic/brick_wall_rustic_basecolor.jpg',
aoMap: '/material/flooring/brick_wall_rustic/brick_wall_rustic_ambientocclusion.jpg',
metalnessMap: '/material/flooring/brick_wall_rustic/brick_wall_rustic_metallic.jpg',
normalMap: '/material/flooring/brick_wall_rustic/brick_wall_rustic_normal.jpg',
roughnessMap: '/material/flooring/brick_wall_rustic/brick_wall_rustic_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1.5,
repeatY: 1.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-agedbrick',
label: 'Aged Brick',
category: 'brick',
surfaces: ['wall', 'floor', 'outdoor'],
description: 'Brick finish',
previewThumbnailUrl: '/material/flooring/brick_wall_aged/brick_wall_aged_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/brick_wall_aged/brick_wall_aged_basecolor.jpg',
aoMap: '/material/flooring/brick_wall_aged/brick_wall_aged_ambientocclusion.jpg',
metalnessMap: '/material/flooring/brick_wall_aged/brick_wall_aged_metallic.jpg',
normalMap: '/material/flooring/brick_wall_aged/brick_wall_aged_normal.jpg',
roughnessMap: '/material/flooring/brick_wall_aged/brick_wall_aged_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1.5,
repeatY: 1.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-weatheredbrick',
label: 'Weathered Brick',
category: 'brick',
surfaces: ['wall', 'floor', 'outdoor'],
description: 'Brick finish',
previewThumbnailUrl:
'/material/flooring/brick_wall_weathered/brick_wall_weathered_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/brick_wall_weathered/brick_wall_weathered_basecolor.jpg',
aoMap: '/material/flooring/brick_wall_weathered/brick_wall_weathered_ambientocclusion.jpg',
normalMap: '/material/flooring/brick_wall_weathered/brick_wall_weathered_normal.jpg',
roughnessMap: '/material/flooring/brick_wall_weathered/brick_wall_weathered_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-garagedoor',
label: 'Garage Panel',
category: 'metal',
surfaces: ['wall', 'furniture'],
description: 'Panel finish',
previewThumbnailUrl: '/material/flooring/garage_panel/garage_panel_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/garage_panel/garage_panel_diffuse.jpg',
aoMap: '/material/flooring/garage_panel/garage_panel_ao.jpg',
metalnessMap: '/material/flooring/garage_panel/garage_panel_specular.jpg',
normalMap: '/material/flooring/garage_panel/garage_panel_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-greenlabradorite',
label: 'Green Labradorite',
category: 'stone',
surfaces: ['floor', 'wall'],
description: 'Stone flooring finish',
previewThumbnailUrl: '/material/flooring/green_labradorite/green_labradorite_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/green_labradorite/green_labradorite_diffuse.jpg',
aoMap: '/material/flooring/green_labradorite/green_labradorite_ao.jpg',
metalnessMap: '/material/flooring/green_labradorite/green_labradorite_specular.jpg',
normalMap: '/material/flooring/green_labradorite/green_labradorite_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.35,
metalness: 0,
repeatX: 0.6,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-ground13',
label: 'Earth Ground',
category: 'ground',
surfaces: ['outdoor', 'floor'],
description: 'Ground surface finish',
previewThumbnailUrl: '/material/flooring/ground_earth/ground_earth_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/ground_earth/ground_earth_basecolor.jpg',
aoMap: '/material/flooring/ground_earth/ground_earth_ambientocclusion.jpg',
metalnessMap: '/material/flooring/ground_earth/ground_earth_metallic.jpg',
normalMap: '/material/flooring/ground_earth/ground_earth_normal.jpg',
roughnessMap: '/material/flooring/ground_earth/ground_earth_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-pooltiles',
label: 'Pool Tiles',
category: 'tile',
surfaces: ['floor', 'outdoor'],
description: 'Pool tile finish',
previewThumbnailUrl: '/material/flooring/pool_tiles/pool_tiles_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/pool_tiles/pool_tiles_diffuse.jpg',
aoMap: '/material/flooring/pool_tiles/pool_tiles_ao.jpg',
metalnessMap: '/material/flooring/pool_tiles/pool_tiles_specular.jpg',
normalMap: '/material/flooring/pool_tiles/pool_tiles_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tiles3',
label: 'Checker Tiles',
category: 'tile',
surfaces: ['floor'],
description: 'Tile flooring finish',
previewThumbnailUrl: '/material/flooring/tiles_checker/tiles_checker_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/tiles_checker/tiles_checker_diffuse.jpg',
aoMap: '/material/flooring/tiles_checker/tiles_checker_ao.jpg',
metalnessMap: '/material/flooring/tiles_checker/tiles_checker_specular.jpg',
normalMap: '/material/flooring/tiles_checker/tiles_checker_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tiles4',
label: 'Grid Tiles',
category: 'tile',
surfaces: ['floor'],
description: 'Tile flooring finish',
previewThumbnailUrl: '/material/flooring/tiles_grid/tiles_grid_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/tiles_grid/tiles_grid_diffuse.jpg',
aoMap: '/material/flooring/tiles_grid/tiles_grid_ao.jpg',
metalnessMap: '/material/flooring/tiles_grid/tiles_grid_specular.jpg',
normalMap: '/material/flooring/tiles_grid/tiles_grid_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-wallstone1',
label: 'Stone Wall',
category: 'stone',
surfaces: ['wall', 'floor', 'outdoor'],
description: 'Stone finish',
previewThumbnailUrl: '/material/flooring/stone_wall/stone_wall_diffuse.webp',
preset: {
maps: {
albedoMap: '/material/flooring/stone_wall/stone_wall_diffuse.webp',
aoMap: '/material/flooring/stone_wall/stone_wall_ao.webp',
metalnessMap: '/material/flooring/stone_wall/stone_wall_specular.webp',
normalMap: '/material/flooring/stone_wall/stone_wall_normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-woodenceramic3',
label: 'Wooden Ceramic 3',
category: 'tile',
surfaces: ['floor'],
description: 'Wood-look ceramic flooring finish',
previewThumbnailUrl: '/material/flooring/wooden_ceramic_3/wooden_ceramic-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/flooring/wooden_ceramic_3/wooden_ceramic-diffuse.webp',
aoMap: '/material/flooring/wooden_ceramic_3/wooden_ceramic-ao.webp',
metalnessMap: '/material/flooring/wooden_ceramic_3/wooden_ceramic-specular.webp',
normalMap: '/material/flooring/wooden_ceramic_3/wooden_ceramic-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-ceramic53',
label: 'Ceramic Mosaic',
category: 'tile',
surfaces: ['floor', 'wall'],
description: 'Ceramic flooring finish',
previewThumbnailUrl: '/material/flooring/ceramic_mosaic/ceramic_mosaic_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/ceramic_mosaic/ceramic_mosaic_basecolor.jpg',
aoMap: '/material/flooring/ceramic_mosaic/ceramic_mosaic_ambientocclusion.jpg',
metalnessMap: '/material/flooring/ceramic_mosaic/ceramic_mosaic_metallic.jpg',
normalMap: '/material/flooring/ceramic_mosaic/ceramic_mosaic_normal.png',
roughnessMap: '/material/flooring/ceramic_mosaic/ceramic_mosaic_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-terrazzo19',
label: 'Terrazzo',
category: 'stone',
surfaces: ['floor', 'wall'],
description: 'Terrazzo flooring finish',
previewThumbnailUrl: '/material/flooring/terrazzo/terrazzo_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/terrazzo/terrazzo_basecolor.jpg',
metalnessMap: '/material/flooring/terrazzo/terrazzo_metallic.jpg',
normalMap: '/material/flooring/terrazzo/terrazzo_normal.jpg',
roughnessMap: '/material/flooring/terrazzo/terrazzo_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tile79',
label: 'Stone Tile',
category: 'stone',
surfaces: ['floor', 'wall'],
description: 'Floor tile finish',
previewThumbnailUrl: '/material/flooring/tile_stone/tile_stone_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/tile_stone/tile_stone_basecolor.webp',
aoMap: '/material/flooring/tile_stone/tile_stone_ambientocclusion.webp',
normalMap: '/material/flooring/tile_stone/tile_stone_normal.webp',
roughnessMap: '/material/flooring/tile_stone/tile_stone_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tile86',
label: 'Terracotta Tile',
category: 'tile',
surfaces: ['floor'],
description: 'Floor tile finish',
previewThumbnailUrl: '/material/flooring/tile_terracotta/tile_terracotta_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/tile_terracotta/tile_terracotta_basecolor.webp',
aoMap: '/material/flooring/tile_terracotta/tile_terracotta_ambientocclusion.webp',
normalMap: '/material/flooring/tile_terracotta/tile_terracotta_normal.webp',
roughnessMap: '/material/flooring/tile_terracotta/tile_terracotta_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-greenquartzitea',
label: 'Green Quartzite A',
category: 'stone',
surfaces: ['floor', 'wall'],
description: 'Green quartzite flooring finish',
previewThumbnailUrl:
'/material/flooring/green_glass_quartzite/green_glass_quartzite_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/green_glass_quartzite/green_glass_quartzite_diffuse.jpg',
aoMap: '/material/flooring/green_glass_quartzite/green_glass_quartzite_ao.jpg',
metalnessMap: '/material/flooring/green_glass_quartzite/green_glass_quartzite_specular.jpg',
normalMap: '/material/flooring/green_glass_quartzite/green_glass_quartzite_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.35,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-darkceramic22',
label: 'Dark Ceramic Grunge',
category: 'tile',
surfaces: ['floor'],
description: 'Dark ceramic flooring finish',
previewThumbnailUrl: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_basecolor.jpg',
aoMap: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_ambientocclusion.jpg',
metalnessMap: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_metallic.jpg',
normalMap: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_normal.jpg',
roughnessMap: '/material/flooring/dark_ceramic_grunge/dark_ceramic_grunge_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-lightceramic24',
label: 'Light Ceramic Grunge',
category: 'tile',
surfaces: ['floor'],
description: 'Light ceramic flooring finish',
previewThumbnailUrl:
'/material/flooring/light_ceramic_grunge/light_ceramic_grunge_basecolor.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/light_ceramic_grunge/light_ceramic_grunge_basecolor.jpg',
aoMap: '/material/flooring/light_ceramic_grunge/light_ceramic_grunge_ambientocclusion.jpg',
metalnessMap: '/material/flooring/light_ceramic_grunge/light_ceramic_grunge_metallic.jpg',
normalMap: '/material/flooring/light_ceramic_grunge/light_ceramic_grunge_normal.jpg',
roughnessMap: '/material/flooring/light_ceramic_grunge/light_ceramic_grunge_roughness.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-statuarettowhite',
label: 'Statuaretto White',
category: 'stone',
surfaces: ['floor', 'wall'],
description: 'White marble flooring finish',
previewThumbnailUrl: '/material/flooring/statuaretto/statuaretto_diffuse.jpg',
preset: {
maps: {
albedoMap: '/material/flooring/statuaretto/statuaretto_diffuse.jpg',
aoMap: '/material/flooring/statuaretto/statuaretto_ao.jpg',
metalnessMap: '/material/flooring/statuaretto/statuaretto_specular.jpg',
normalMap: '/material/flooring/statuaretto/statuaretto_normal.jpg',
},
mapProperties: {
color: '#ffffff',
roughness: 0.35,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tile20',
label: 'Mosaic Tile',
category: 'tile',
surfaces: ['floor', 'wall'],
description: 'Floor tile finish',
previewThumbnailUrl: '/material/flooring/tile_mosaic/tile_mosaic_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/tile_mosaic/tile_mosaic_basecolor.webp',
aoMap: '/material/flooring/tile_mosaic/tile_mosaic_ambientocclusion.webp',
metalnessMap: '/material/flooring/tile_mosaic/tile_mosaic_metallic.webp',
normalMap: '/material/flooring/tile_mosaic/tile_mosaic_normal.webp',
roughnessMap: '/material/flooring/tile_mosaic/tile_mosaic_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-tile68',
label: 'Pattern Tile',
category: 'tile',
surfaces: ['floor', 'wall'],
description: 'Floor tile finish',
previewThumbnailUrl: '/material/flooring/tile_pattern/tile_pattern_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/tile_pattern/tile_pattern_basecolor.webp',
aoMap: '/material/flooring/tile_pattern/tile_pattern_ambientocclusion.webp',
metalnessMap: '/material/flooring/tile_pattern/tile_pattern_metallic.webp',
normalMap: '/material/flooring/tile_pattern/tile_pattern_normal.webp',
roughnessMap: '/material/flooring/tile_pattern/tile_pattern_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-woodenceramic2',
label: 'Wooden Ceramic 2',
category: 'tile',
surfaces: ['floor'],
description: 'Wood-look ceramic flooring finish',
previewThumbnailUrl: '/material/flooring/wooden_ceramic_2/wooden_ceramic-diffuse.webp',
preset: {
maps: {
albedoMap: '/material/flooring/wooden_ceramic_2/wooden_ceramic-diffuse.webp',
aoMap: '/material/flooring/wooden_ceramic_2/wooden_ceramic-ao.webp',
metalnessMap: '/material/flooring/wooden_ceramic_2/wooden_ceramic-specular.webp',
normalMap: '/material/flooring/wooden_ceramic_2/wooden_ceramic-normal.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0,
repeatX: 1.5,
repeatY: 1.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'flooring-woodparquet76',
label: 'Wood Parquet',
category: 'wood',
surfaces: ['floor'],
description: 'Wood parquet flooring finish',
previewThumbnailUrl: '/material/flooring/woodparquet/woodparquet_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/flooring/woodparquet/woodparquet_basecolor.webp',
aoMap: '/material/flooring/woodparquet/woodparquet_ambientocclusion.webp',
metalnessMap: '/material/flooring/woodparquet/woodparquet_metallic.webp',
normalMap: '/material/flooring/woodparquet/woodparquet_normal.webp',
roughnessMap: '/material/flooring/woodparquet/woodparquet_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'roof-classicshingles',
label: 'Classic Shingles',
category: 'roofing',
surfaces: ['roof'],
description: 'Classic roof shingle finish',
previewThumbnailUrl:
'/material/roofing/roof_shingles_classic/roof_shingles_classic_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/roofing/roof_shingles_classic/roof_shingles_classic_basecolor.webp',
aoMap:
'/material/roofing/roof_shingles_classic/roof_shingles_classic_ambientocclusion.webp',
metalnessMap: '/material/roofing/roof_shingles_classic/roof_shingles_classic_metallic.webp',
normalMap: '/material/roofing/roof_shingles_classic/roof_shingles_classic_normal.webp',
roughnessMap:
'/material/roofing/roof_shingles_classic/roof_shingles_classic_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 1,
metalness: 0.15,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'roof-claytiles',
label: 'Clay Tiles',
category: 'roofing',
surfaces: ['roof'],
description: 'Clay roof tile finish',
previewThumbnailUrl: '/material/roofing/roof_tiles_clay/roof_tiles_clay_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/roofing/roof_tiles_clay/roof_tiles_clay_basecolor.webp',
aoMap: '/material/roofing/roof_tiles_clay/roof_tiles_clay_ambientocclusion.webp',
metalnessMap: '/material/roofing/roof_tiles_clay/roof_tiles_clay_metallic.png',
normalMap: '/material/roofing/roof_tiles_clay/roof_tiles_clay_normal.webp',
roughnessMap: '/material/roofing/roof_tiles_clay/roof_tiles_clay_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 1,
metalness: 0.1,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'roof-terracottatiles',
label: 'Terracotta Tiles',
category: 'roofing',
surfaces: ['roof'],
description: 'Terracotta roof tile finish',
previewThumbnailUrl:
'/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_basecolor.webp',
preset: {
maps: {
albedoMap: '/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_basecolor.webp',
aoMap:
'/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_ambientocclusion.webp',
metalnessMap: '/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_metallic.webp',
normalMap: '/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_normal.webp',
roughnessMap:
'/material/roofing/roof_tiles_terracotta/roof_tiles_terracotta_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 1,
metalness: 0.1,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'roof-weatheredshingles',
label: 'Weathered Shingles',
category: 'roofing',
surfaces: ['roof'],
description: 'Weathered roof shingle finish',
previewThumbnailUrl:
'/material/roofing/roof_shingles_weathered/roof_shingles_weathered_basecolor.webp',
preset: {
maps: {
albedoMap:
'/material/roofing/roof_shingles_weathered/roof_shingles_weathered_basecolor.webp',
aoMap:
'/material/roofing/roof_shingles_weathered/roof_shingles_weathered_ambientocclusion.webp',
metalnessMap:
'/material/roofing/roof_shingles_weathered/roof_shingles_weathered_metallic.webp',
normalMap: '/material/roofing/roof_shingles_weathered/roof_shingles_weathered_normal.webp',
roughnessMap:
'/material/roofing/roof_shingles_weathered/roof_shingles_weathered_roughness.webp',
},
mapProperties: {
color: '#ffffff',
roughness: 1,
metalness: 0.1,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-white',
label: 'White',
category: 'colors',
description: 'Clean painted finish',
previewColor: '#ffffff',
preset: {
maps: {},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-softwhite',
label: 'Soft White',
category: 'colors',
description: 'Warm off-white painted finish',
previewColor: '#f2eee6',
preset: {
maps: {},
mapProperties: {
color: '#f2eee6',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-cream',
label: 'Cream',
category: 'colors',
description: 'Soft cream painted finish',
previewColor: '#efe3cc',
preset: {
maps: {},
mapProperties: {
color: '#efe3cc',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-beige',
label: 'Beige',
category: 'colors',
description: 'Balanced beige painted finish',
previewColor: '#d9c7ad',
preset: {
maps: {},
mapProperties: {
color: '#d9c7ad',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-lightgrey',
label: 'Light grey',
category: 'colors',
description: 'Cool light grey painted finish',
previewColor: '#d8d6d1',
preset: {
maps: {},
mapProperties: {
color: '#d8d6d1',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-greige',
label: 'Greige',
category: 'colors',
description: 'Neutral greige painted finish',
previewColor: '#c8c1b8',
preset: {
maps: {},
mapProperties: {
color: '#c8c1b8',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-midgrey',
label: 'Mid grey',
category: 'colors',
description: 'Neutral mid grey painted finish',
previewColor: '#8b8a86',
preset: {
maps: {},
mapProperties: {
color: '#8b8a86',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-charcoal',
label: 'Charcoal',
category: 'colors',
description: 'Dark charcoal painted finish',
previewColor: '#4e5257',
preset: {
maps: {},
mapProperties: {
color: '#4e5257',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-nearblack',
label: 'Near-black',
category: 'colors',
description: 'Soft near-black painted finish',
previewColor: '#232322',
preset: {
maps: {},
mapProperties: {
color: '#232322',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-blush',
label: 'Blush',
category: 'colors',
description: 'Pale blush painted finish',
previewColor: '#e8c6c0',
preset: {
maps: {},
mapProperties: {
color: '#e8c6c0',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-tomato',
label: 'Tomato',
category: 'colors',
description: 'Warm tomato red painted finish',
previewColor: '#c0594f',
preset: {
maps: {},
mapProperties: {
color: '#c0594f',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-brickred',
label: 'Brick red',
category: 'colors',
description: 'Deep brick red painted finish',
previewColor: '#9e3b34',
preset: {
maps: {},
mapProperties: {
color: '#9e3b34',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-oxblood',
label: 'Oxblood',
category: 'colors',
description: 'Dark oxblood painted finish',
previewColor: '#6f2c2a',
preset: {
maps: {},
mapProperties: {
color: '#6f2c2a',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-peach',
label: 'Peach',
category: 'colors',
description: 'Soft peach painted finish',
previewColor: '#f0c3a0',
preset: {
maps: {},
mapProperties: {
color: '#f0c3a0',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-terracotta',
label: 'Terracotta',
category: 'colors',
description: 'Warm terracotta painted finish',
previewColor: '#c86f4c',
preset: {
maps: {},
mapProperties: {
color: '#c86f4c',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-burntorange',
label: 'Burnt orange',
category: 'colors',
description: 'Burnt orange painted finish',
previewColor: '#b25a2c',
preset: {
maps: {},
mapProperties: {
color: '#b25a2c',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-clay',
label: 'Clay',
category: 'colors',
description: 'Deep clay painted finish',
previewColor: '#8f4a2e',
preset: {
maps: {},
mapProperties: {
color: '#8f4a2e',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-paleyellow',
label: 'Pale yellow',
category: 'colors',
description: 'Pale yellow painted finish',
previewColor: '#f2e3b3',
preset: {
maps: {},
mapProperties: {
color: '#f2e3b3',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-mustard',
label: 'Mustard',
category: 'colors',
description: 'Warm mustard painted finish',
previewColor: '#c8a449',
preset: {
maps: {},
mapProperties: {
color: '#c8a449',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-ochre',
label: 'Ochre',
category: 'colors',
description: 'Warm ochre painted finish',
previewColor: '#b8852f',
preset: {
maps: {},
mapProperties: {
color: '#b8852f',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-gold',
label: 'Gold',
category: 'colors',
description: 'Deep gold painted finish',
previewColor: '#9c7320',
preset: {
maps: {},
mapProperties: {
color: '#9c7320',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-mint',
label: 'Mint',
category: 'colors',
description: 'Soft mint painted finish',
previewColor: '#cfe0cf',
preset: {
maps: {},
mapProperties: {
color: '#cfe0cf',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-sage',
label: 'Sage',
category: 'colors',
description: 'Muted sage painted finish',
previewColor: '#bcc5b2',
preset: {
maps: {},
mapProperties: {
color: '#bcc5b2',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-olive',
label: 'Olive',
category: 'colors',
description: 'Natural olive painted finish',
previewColor: '#8d9368',
preset: {
maps: {},
mapProperties: {
color: '#8d9368',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-forest',
label: 'Forest',
category: 'colors',
description: 'Deep forest green painted finish',
previewColor: '#4f6b57',
preset: {
maps: {},
mapProperties: {
color: '#4f6b57',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-paleteal',
label: 'Pale teal',
category: 'colors',
description: 'Pale teal painted finish',
previewColor: '#b9d2cf',
preset: {
maps: {},
mapProperties: {
color: '#b9d2cf',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-teal',
label: 'Teal',
category: 'colors',
description: 'Balanced teal painted finish',
previewColor: '#4f8a86',
preset: {
maps: {},
mapProperties: {
color: '#4f8a86',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-deepteal',
label: 'Deep teal',
category: 'colors',
description: 'Deep teal painted finish',
previewColor: '#2f5f5c',
preset: {
maps: {},
mapProperties: {
color: '#2f5f5c',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-powderblue',
label: 'Powder blue',
category: 'colors',
description: 'Powder blue painted finish',
previewColor: '#cddce8',
preset: {
maps: {},
mapProperties: {
color: '#cddce8',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-softblue',
label: 'Soft Blue',
category: 'colors',
description: 'Muted blue painted finish',
previewColor: '#c7d6e3',
preset: {
maps: {},
mapProperties: {
color: '#c7d6e3',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-sky',
label: 'Sky',
category: 'colors',
description: 'Sky blue painted finish',
previewColor: '#8fb4d4',
preset: {
maps: {},
mapProperties: {
color: '#8fb4d4',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-slateblue',
label: 'Slate Blue',
category: 'colors',
description: 'Muted slate blue painted finish',
previewColor: '#6f87a4',
preset: {
maps: {},
mapProperties: {
color: '#6f87a4',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-royalblue',
label: 'Royal blue',
category: 'colors',
description: 'Royal blue painted finish',
previewColor: '#3a5a9c',
preset: {
maps: {},
mapProperties: {
color: '#3a5a9c',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-navy',
label: 'Navy',
category: 'colors',
description: 'Classic navy painted finish',
previewColor: '#2f4865',
preset: {
maps: {},
mapProperties: {
color: '#2f4865',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-lavender',
label: 'Lavender',
category: 'colors',
description: 'Soft lavender painted finish',
previewColor: '#c9c2da',
preset: {
maps: {},
mapProperties: {
color: '#c9c2da',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-plum',
label: 'Plum',
category: 'colors',
description: 'Muted plum painted finish',
previewColor: '#6d4a63',
preset: {
maps: {},
mapProperties: {
color: '#6d4a63',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-aubergine',
label: 'Aubergine',
category: 'colors',
description: 'Deep aubergine painted finish',
previewColor: '#594354',
preset: {
maps: {},
mapProperties: {
color: '#594354',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-petal',
label: 'Petal',
category: 'colors',
description: 'Pale petal pink painted finish',
previewColor: '#f0d3da',
preset: {
maps: {},
mapProperties: {
color: '#f0d3da',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-rose',
label: 'Rose',
category: 'colors',
description: 'Muted rose painted finish',
previewColor: '#cf8fa6',
preset: {
maps: {},
mapProperties: {
color: '#cf8fa6',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-dustyrose',
label: 'Dusty Rose',
category: 'colors',
description: 'Muted rose painted finish',
previewColor: '#c48a8d',
preset: {
maps: {},
mapProperties: {
color: '#c48a8d',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-berry',
label: 'Berry',
category: 'colors',
description: 'Deep berry painted finish',
previewColor: '#8f4a5a',
preset: {
maps: {},
mapProperties: {
color: '#8f4a5a',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-sand',
label: 'Sand',
category: 'colors',
description: 'Warm sand painted finish',
previewColor: '#ddccae',
preset: {
maps: {},
mapProperties: {
color: '#ddccae',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-tan',
label: 'Tan',
category: 'colors',
description: 'Natural tan painted finish',
previewColor: '#c4a87f',
preset: {
maps: {},
mapProperties: {
color: '#c4a87f',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-taupe',
label: 'Taupe',
category: 'colors',
description: 'Earthy taupe painted finish',
previewColor: '#8f7a64',
preset: {
maps: {},
mapProperties: {
color: '#8f7a64',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-espresso',
label: 'Espresso',
category: 'colors',
description: 'Dark espresso painted finish',
previewColor: '#4a382c',
preset: {
maps: {},
mapProperties: {
color: '#4a382c',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-metal',
label: 'Metal',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Brushed metal finish',
previewColor: '#c0c0c0',
preset: {
maps: {},
mapProperties: {
color: '#c7ccd2',
roughness: 0.26,
metalness: 0.82,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: false,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'preset-glass',
label: 'Glass',
category: 'glass',
description: 'Light glass finish',
previewColor: '#87ceeb',
preset: {
maps: {},
mapProperties: {
color: '#87ceeb',
roughness: 0.1,
metalness: 0.1,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0.02,
transparent: true,
flipY: true,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
// FrontSide — DoubleSide on a NodeMaterial poisons the WebGPU MRT scene
// pass (window/door glass relies on this). It's the only glass we use.
side: 0,
opacity: 0.3,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-linen',
label: 'Linen',
category: 'fabric',
surfaces: ['furniture', 'wall'],
description: 'Natural linen weave',
previewThumbnailUrl: '/material/fabric/linen_hikari_fabric/linen_hikari_fabric_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/linen_hikari_fabric/linen_hikari_fabric_basecolor_512.ktx2',
normalMap: '/material/fabric/linen_hikari_fabric/linen_hikari_fabric_normal_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.85,
metalness: 0,
repeatX: 2,
repeatY: 2,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-cotton',
label: 'Cotton',
category: 'fabric',
surfaces: ['furniture', 'wall'],
description: 'Plain cotton weave',
previewThumbnailUrl: '/material/fabric/blue_cotton/blue_cotton_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/blue_cotton/blue_cotton_basecolor_512.ktx2',
normalMap: '/material/fabric/blue_cotton/blue_cotton_normal_512.ktx2',
roughnessMap: '/material/fabric/blue_cotton/blue_cotton_roughness_512.ktx2',
aoMap: '/material/fabric/blue_cotton/blue_cotton_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.85,
metalness: 0,
repeatX: 2,
repeatY: 2,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-velvet',
label: 'Velvet',
category: 'fabric',
surfaces: ['furniture'],
description: 'Velvet with a soft sheen',
previewThumbnailUrl: '/material/fabric/red_velvet/red_velvet_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/red_velvet/red_velvet_basecolor_512.ktx2',
normalMap: '/material/fabric/red_velvet/red_velvet_normal_512.ktx2',
roughnessMap: '/material/fabric/red_velvet/red_velvet_roughness_512.ktx2',
aoMap: '/material/fabric/red_velvet/red_velvet_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.6,
metalness: 0,
repeatX: 2.5,
repeatY: 2.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-wool',
label: 'Wool',
category: 'fabric',
surfaces: ['furniture'],
description: 'Matte wool felt',
previewThumbnailUrl: '/material/fabric/white_wool/white_wool_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/white_wool/white_wool_basecolor_512.ktx2',
normalMap: '/material/fabric/white_wool/white_wool_normal_512.ktx2',
roughnessMap: '/material/fabric/white_wool/white_wool_roughness_512.ktx2',
aoMap: '/material/fabric/white_wool/white_wool_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 2.5,
repeatY: 2.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-suede',
label: 'Suede',
category: 'fabric',
surfaces: ['furniture'],
description: 'Matte suede nap',
previewThumbnailUrl: '/material/fabric/suede/suede_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/suede/suede_basecolor_512.ktx2',
normalMap: '/material/fabric/suede/suede_normal_512.ktx2',
roughnessMap: '/material/fabric/suede/suede_roughness_512.ktx2',
aoMap: '/material/fabric/suede/suede_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 2,
repeatY: 2,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'fabric-boucle',
label: 'Bouclé',
category: 'fabric',
surfaces: ['furniture'],
description: 'Looped bouclé upholstery',
previewThumbnailUrl: '/material/fabric/wool_boucle/wool_boucle_thumb.webp',
preset: {
maps: {
albedoMap: '/material/fabric/wool_boucle/wool_boucle_basecolor_512.ktx2',
normalMap: '/material/fabric/wool_boucle/wool_boucle_normal_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 3.3,
repeatY: 3.3,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'leather-black',
label: 'Black Leather',
category: 'leather',
surfaces: ['furniture'],
description: 'Smooth black leather',
previewThumbnailUrl: '/material/leather/black_leather/black_leather_thumb.webp',
preset: {
maps: {
albedoMap: '/material/leather/black_leather/black_leather_basecolor_512.ktx2',
normalMap: '/material/leather/black_leather/black_leather_normal_512.ktx2',
roughnessMap: '/material/leather/black_leather/black_leather_roughness_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 1.67,
repeatY: 1.67,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'leather-calf',
label: 'Calf Leather',
category: 'leather',
surfaces: ['furniture'],
description: 'Pebbled calf leather',
previewThumbnailUrl: '/material/leather/calf_leather/calf_leather_thumb.webp',
preset: {
maps: {
albedoMap: '/material/leather/calf_leather/calf_leather_basecolor_512.ktx2',
normalMap: '/material/leather/calf_leather/calf_leather_normal_512.ktx2',
roughnessMap: '/material/leather/calf_leather/calf_leather_roughness_512.ktx2',
aoMap: '/material/leather/calf_leather/calf_leather_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 2,
repeatY: 2,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-plaster',
label: 'Painted Plaster',
category: 'concrete',
surfaces: ['wall', 'ceiling'],
description: 'Smooth painted plaster wall',
previewThumbnailUrl: '/material/concrete/plaster_painted/plaster_painted_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/plaster_painted/plaster_painted_basecolor_512.ktx2',
normalMap: '/material/concrete/plaster_painted/plaster_painted_normal_512.ktx2',
roughnessMap: '/material/concrete/plaster_painted/plaster_painted_roughness_512.ktx2',
aoMap: '/material/concrete/plaster_painted/plaster_painted_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.85,
metalness: 0,
repeatX: 0.67,
repeatY: 0.67,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-polished',
label: 'Polished Concrete',
category: 'concrete',
surfaces: ['floor', 'wall'],
description: 'Polished concrete floor',
previewThumbnailUrl: '/material/concrete/concrete_polished/concrete_polished_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/concrete_polished/concrete_polished_basecolor_512.ktx2',
normalMap: '/material/concrete/concrete_polished/concrete_polished_normal_512.ktx2',
roughnessMap: '/material/concrete/concrete_polished/concrete_polished_roughness_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.5,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-raw',
label: 'Raw Concrete',
category: 'concrete',
surfaces: ['wall', 'floor', 'outdoor'],
description: 'Board-formed raw concrete',
previewThumbnailUrl: '/material/concrete/concrete_raw/concrete_raw_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/concrete_raw/concrete_raw_basecolor_512.ktx2',
normalMap: '/material/concrete/concrete_raw/concrete_raw_normal_512.ktx2',
roughnessMap: '/material/concrete/concrete_raw/concrete_raw_roughness_512.ktx2',
aoMap: '/material/concrete/concrete_raw/concrete_raw_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.8,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-plate',
label: 'Concrete Plate',
category: 'concrete',
surfaces: ['wall', 'floor'],
description: 'Smooth cast concrete plate',
previewThumbnailUrl: '/material/concrete/concrete_plate/concrete_plate_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/concrete_plate/concrete_plate_basecolor_512.ktx2',
normalMap: '/material/concrete/concrete_plate/concrete_plate_normal_512.ktx2',
roughnessMap: '/material/concrete/concrete_plate/concrete_plate_roughness_512.ktx2',
aoMap: '/material/concrete/concrete_plate/concrete_plate_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.8,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-stucco',
label: 'White Stucco',
category: 'concrete',
surfaces: ['wall', 'outdoor'],
description: 'Exterior stucco render',
previewThumbnailUrl: '/material/concrete/white_stucco/white_stucco_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/white_stucco/white_stucco_basecolor_512.ktx2',
normalMap: '/material/concrete/white_stucco/white_stucco_normal_512.ktx2',
roughnessMap: '/material/concrete/white_stucco/white_stucco_roughness_512.ktx2',
aoMap: '/material/concrete/white_stucco/white_stucco_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'concrete-drywall',
label: 'Prepared Drywall',
category: 'concrete',
surfaces: ['wall', 'ceiling'],
description: 'Smooth prepared drywall ready for paint',
previewThumbnailUrl: '/material/concrete/prepared_drywall/prepared_drywall_thumb.webp',
preset: {
maps: {
albedoMap: '/material/concrete/prepared_drywall/prepared_drywall_basecolor_512.ktx2',
normalMap: '/material/concrete/prepared_drywall/prepared_drywall_normal_512.ktx2',
roughnessMap: '/material/concrete/prepared_drywall/prepared_drywall_roughness_512.ktx2',
aoMap: '/material/concrete/prepared_drywall/prepared_drywall_ao_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.9,
metalness: 0,
repeatX: 0.5,
repeatY: 0.5,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'metal-copper',
label: 'Copper',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Warm copper',
previewThumbnailUrl: '/material/metal/copper_metal/copper_metal_thumb.webp',
preset: {
maps: {
albedoMap: '/material/metal/copper_metal/copper_metal_basecolor_512.ktx2',
normalMap: '/material/metal/copper_metal/copper_metal_normal_512.ktx2',
roughnessMap: '/material/metal/copper_metal/copper_metal_roughness_512.ktx2',
metalnessMap: '/material/metal/copper_metal/copper_metal_metallic_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.4,
metalness: 0.6,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'metal-polished',
label: 'Polished Metal',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Polished stainless steel',
previewThumbnailUrl: '/material/metal/polished_metal/polished_metal_thumb.webp',
preset: {
maps: {
albedoMap: '/material/metal/polished_metal/polished_metal_basecolor_512.ktx2',
normalMap: '/material/metal/polished_metal/polished_metal_normal_512.ktx2',
roughnessMap: '/material/metal/polished_metal/polished_metal_roughness_512.ktx2',
aoMap: '/material/metal/polished_metal/polished_metal_ao_512.ktx2',
metalnessMap: '/material/metal/polished_metal/polished_metal_metallic_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.3,
metalness: 0.6,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
id: 'metal-steel',
label: 'Brushed Steel',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Brushed stainless steel',
previewThumbnailUrl:
'/material/metal/stainless_steel_brushed/stainless_steel_brushed_thumb.webp',
preset: {
maps: {
albedoMap:
'/material/metal/stainless_steel_brushed/stainless_steel_brushed_basecolor_512.ktx2',
normalMap:
'/material/metal/stainless_steel_brushed/stainless_steel_brushed_normal_512.ktx2',
roughnessMap:
'/material/metal/stainless_steel_brushed/stainless_steel_brushed_roughness_512.ktx2',
},
mapProperties: {
color: '#ffffff',
roughness: 0.45,
metalness: 0.6,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
// Parameter-only metal (no texture maps) — a worked example of a non-PBR
// catalog finish driven purely by three.js material settings.
id: 'metal-brass',
label: 'Brass',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Polished brass (flat metal, no maps)',
previewColor: '#b08d57',
preset: {
maps: {},
mapProperties: {
color: '#b08d57',
roughness: 0.35,
metalness: 0.9,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
{
// Parameter-only chrome (no texture maps) — moderate metalness so it reads
// as bright metal under direct/ambient light without needing an env map.
id: 'metal-chrome',
label: 'Chrome',
category: 'metal',
surfaces: ['furniture', 'wall'],
description: 'Polished chrome (flat metal, no maps)',
previewColor: '#c8ccce',
preset: {
maps: {},
mapProperties: {
color: '#c8ccce',
roughness: 0.2,
metalness: 0.6,
repeatX: 1,
repeatY: 1,
rotation: 0,
wrapS: 'Repeat',
wrapT: 'Repeat',
normalScaleX: 1,
normalScaleY: 1,
emissiveIntensity: 1,
displacementScale: 0,
transparent: false,
flipY: false,
bumpScale: 1,
emissiveColor: '#000000',
aoMapIntensity: 1,
side: 0,
opacity: 1,
lightMapIntensity: 1,
},
},
},
]
export function getMaterialsForCategory(category: MaterialCategory): MaterialCatalogItem[] {
return MATERIAL_CATALOG.filter((item) => item.category === category)
}
export function getCatalogMaterialById(id?: string): MaterialCatalogItem | undefined {
if (!id) return undefined
return MATERIAL_CATALOG.find((item) => item.id === id)
}
export const LIBRARY_MATERIAL_REF_PREFIX = 'library:'
export const SCENE_MATERIAL_REF_PREFIX = 'scene:'
export function toLibraryMaterialRef(id: string) {
return `${LIBRARY_MATERIAL_REF_PREFIX}${id}`
}
export function toSceneMaterialRef(id: string) {
return `${SCENE_MATERIAL_REF_PREFIX}${id}`
}
export function getLibraryMaterialIdFromRef(materialRef?: string | null) {
if (!materialRef) return null
if (!materialRef.startsWith(LIBRARY_MATERIAL_REF_PREFIX)) return null
return materialRef.slice(LIBRARY_MATERIAL_REF_PREFIX.length)
}
export function getSceneMaterialIdFromRef(materialRef?: string | null): string | null {
if (!materialRef?.startsWith(SCENE_MATERIAL_REF_PREFIX)) return null
return materialRef.slice(SCENE_MATERIAL_REF_PREFIX.length)
}
export type MaterialRef = string
export type ParsedMaterialRef = { kind: 'library'; id: string } | { kind: 'scene'; id: string }
export function parseMaterialRef(ref?: string | null): ParsedMaterialRef | null {
const lib = getLibraryMaterialIdFromRef(ref)
if (lib) return { kind: 'library', id: lib }
const scene = getSceneMaterialIdFromRef(ref)
if (scene) return { kind: 'scene', id: scene }
return null
}
export function getMaterialPresetByRef(materialRef?: string | null): MaterialPresetPayload | null {
const materialId = getLibraryMaterialIdFromRef(materialRef)
if (!materialId) return null
return getCatalogMaterialById(materialId)?.preset ?? null
}