diff --git a/apps/editor/public/material/concrete/concrete_polished/concrete_polished_basecolor_512.ktx2 b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_basecolor_512.ktx2 new file mode 100644 index 00000000..b194d72d Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_polished/concrete_polished_normal_512.ktx2 b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_normal_512.ktx2 new file mode 100644 index 00000000..40409452 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_normal_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_polished/concrete_polished_roughness_512.ktx2 b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_roughness_512.ktx2 new file mode 100644 index 00000000..2f2d796c Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_polished/concrete_polished_thumb.webp b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_thumb.webp new file mode 100644 index 00000000..e86c3df3 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_polished/concrete_polished_thumb.webp differ diff --git a/apps/editor/public/material/concrete/concrete_raw/concrete_raw_ao_512.ktx2 b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_ao_512.ktx2 new file mode 100644 index 00000000..d42fed1c Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_ao_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_raw/concrete_raw_basecolor_512.ktx2 b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_basecolor_512.ktx2 new file mode 100644 index 00000000..a3dbedd3 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_raw/concrete_raw_normal_512.ktx2 b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_normal_512.ktx2 new file mode 100644 index 00000000..048e7384 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_normal_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_raw/concrete_raw_roughness_512.ktx2 b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_roughness_512.ktx2 new file mode 100644 index 00000000..1997dfa8 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/concrete_raw/concrete_raw_thumb.webp b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_thumb.webp new file mode 100644 index 00000000..9dd8ae17 Binary files /dev/null and b/apps/editor/public/material/concrete/concrete_raw/concrete_raw_thumb.webp differ diff --git a/apps/editor/public/material/concrete/plaster_painted/plaster_painted_ao_512.ktx2 b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_ao_512.ktx2 new file mode 100644 index 00000000..3b11c66a Binary files /dev/null and b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_ao_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/plaster_painted/plaster_painted_basecolor_512.ktx2 b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_basecolor_512.ktx2 new file mode 100644 index 00000000..f058bc47 Binary files /dev/null and b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/plaster_painted/plaster_painted_normal_512.ktx2 b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_normal_512.ktx2 new file mode 100644 index 00000000..e4d75718 Binary files /dev/null and b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_normal_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/plaster_painted/plaster_painted_roughness_512.ktx2 b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_roughness_512.ktx2 new file mode 100644 index 00000000..c23d72c3 Binary files /dev/null and b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/plaster_painted/plaster_painted_thumb.webp b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_thumb.webp new file mode 100644 index 00000000..dcc2c577 Binary files /dev/null and b/apps/editor/public/material/concrete/plaster_painted/plaster_painted_thumb.webp differ diff --git a/apps/editor/public/material/concrete/white_stucco/white_stucco_ao_512.ktx2 b/apps/editor/public/material/concrete/white_stucco/white_stucco_ao_512.ktx2 new file mode 100644 index 00000000..1f9fa9fc Binary files /dev/null and b/apps/editor/public/material/concrete/white_stucco/white_stucco_ao_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/white_stucco/white_stucco_basecolor_512.ktx2 b/apps/editor/public/material/concrete/white_stucco/white_stucco_basecolor_512.ktx2 new file mode 100644 index 00000000..65151883 Binary files /dev/null and b/apps/editor/public/material/concrete/white_stucco/white_stucco_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/white_stucco/white_stucco_normal_512.ktx2 b/apps/editor/public/material/concrete/white_stucco/white_stucco_normal_512.ktx2 new file mode 100644 index 00000000..0c700cd6 Binary files /dev/null and b/apps/editor/public/material/concrete/white_stucco/white_stucco_normal_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/white_stucco/white_stucco_roughness_512.ktx2 b/apps/editor/public/material/concrete/white_stucco/white_stucco_roughness_512.ktx2 new file mode 100644 index 00000000..e0804cba Binary files /dev/null and b/apps/editor/public/material/concrete/white_stucco/white_stucco_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/concrete/white_stucco/white_stucco_thumb.webp b/apps/editor/public/material/concrete/white_stucco/white_stucco_thumb.webp new file mode 100644 index 00000000..bcc006cb Binary files /dev/null and b/apps/editor/public/material/concrete/white_stucco/white_stucco_thumb.webp differ diff --git a/apps/editor/public/material/fabric/blue_cotton/blue_cotton_ao_512.ktx2 b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_ao_512.ktx2 new file mode 100644 index 00000000..8cd1a49d Binary files /dev/null and b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_ao_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/blue_cotton/blue_cotton_basecolor_512.ktx2 b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_basecolor_512.ktx2 new file mode 100644 index 00000000..a85618b2 Binary files /dev/null and b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/blue_cotton/blue_cotton_normal_512.ktx2 b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_normal_512.ktx2 new file mode 100644 index 00000000..e318d120 Binary files /dev/null and b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/blue_cotton/blue_cotton_roughness_512.ktx2 b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_roughness_512.ktx2 new file mode 100644 index 00000000..60f45f25 Binary files /dev/null and b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/blue_cotton/blue_cotton_thumb.webp b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_thumb.webp new file mode 100644 index 00000000..6171aeb8 Binary files /dev/null and b/apps/editor/public/material/fabric/blue_cotton/blue_cotton_thumb.webp differ diff --git a/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_basecolor_512.ktx2 b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_basecolor_512.ktx2 new file mode 100644 index 00000000..48cfd9eb Binary files /dev/null and b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_normal_512.ktx2 b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_normal_512.ktx2 new file mode 100644 index 00000000..40c80b30 Binary files /dev/null and b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_thumb.webp b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_thumb.webp new file mode 100644 index 00000000..945e4f09 Binary files /dev/null and b/apps/editor/public/material/fabric/linen_hikari_fabric/linen_hikari_fabric_thumb.webp differ diff --git a/apps/editor/public/material/fabric/red_velvet/red_velvet_ao_512.ktx2 b/apps/editor/public/material/fabric/red_velvet/red_velvet_ao_512.ktx2 new file mode 100644 index 00000000..d3ef0bc5 Binary files /dev/null and b/apps/editor/public/material/fabric/red_velvet/red_velvet_ao_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/red_velvet/red_velvet_basecolor_512.ktx2 b/apps/editor/public/material/fabric/red_velvet/red_velvet_basecolor_512.ktx2 new file mode 100644 index 00000000..f9a1fd4c Binary files /dev/null and b/apps/editor/public/material/fabric/red_velvet/red_velvet_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/red_velvet/red_velvet_normal_512.ktx2 b/apps/editor/public/material/fabric/red_velvet/red_velvet_normal_512.ktx2 new file mode 100644 index 00000000..378f5453 Binary files /dev/null and b/apps/editor/public/material/fabric/red_velvet/red_velvet_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/red_velvet/red_velvet_roughness_512.ktx2 b/apps/editor/public/material/fabric/red_velvet/red_velvet_roughness_512.ktx2 new file mode 100644 index 00000000..85ed42ec Binary files /dev/null and b/apps/editor/public/material/fabric/red_velvet/red_velvet_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/red_velvet/red_velvet_thumb.webp b/apps/editor/public/material/fabric/red_velvet/red_velvet_thumb.webp new file mode 100644 index 00000000..96f7b01d Binary files /dev/null and b/apps/editor/public/material/fabric/red_velvet/red_velvet_thumb.webp differ diff --git a/apps/editor/public/material/fabric/suede/suede_ao_512.ktx2 b/apps/editor/public/material/fabric/suede/suede_ao_512.ktx2 new file mode 100644 index 00000000..fed0781e Binary files /dev/null and b/apps/editor/public/material/fabric/suede/suede_ao_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/suede/suede_basecolor_512.ktx2 b/apps/editor/public/material/fabric/suede/suede_basecolor_512.ktx2 new file mode 100644 index 00000000..eb66e15e Binary files /dev/null and b/apps/editor/public/material/fabric/suede/suede_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/suede/suede_normal_512.ktx2 b/apps/editor/public/material/fabric/suede/suede_normal_512.ktx2 new file mode 100644 index 00000000..b8903106 Binary files /dev/null and b/apps/editor/public/material/fabric/suede/suede_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/suede/suede_roughness_512.ktx2 b/apps/editor/public/material/fabric/suede/suede_roughness_512.ktx2 new file mode 100644 index 00000000..0425bad9 Binary files /dev/null and b/apps/editor/public/material/fabric/suede/suede_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/suede/suede_thumb.webp b/apps/editor/public/material/fabric/suede/suede_thumb.webp new file mode 100644 index 00000000..c0f20472 Binary files /dev/null and b/apps/editor/public/material/fabric/suede/suede_thumb.webp differ diff --git a/apps/editor/public/material/fabric/white_wool/white_wool_ao_512.ktx2 b/apps/editor/public/material/fabric/white_wool/white_wool_ao_512.ktx2 new file mode 100644 index 00000000..1f62bf14 Binary files /dev/null and b/apps/editor/public/material/fabric/white_wool/white_wool_ao_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/white_wool/white_wool_basecolor_512.ktx2 b/apps/editor/public/material/fabric/white_wool/white_wool_basecolor_512.ktx2 new file mode 100644 index 00000000..0fcfc783 Binary files /dev/null and b/apps/editor/public/material/fabric/white_wool/white_wool_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/white_wool/white_wool_normal_512.ktx2 b/apps/editor/public/material/fabric/white_wool/white_wool_normal_512.ktx2 new file mode 100644 index 00000000..12f069f5 Binary files /dev/null and b/apps/editor/public/material/fabric/white_wool/white_wool_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/white_wool/white_wool_roughness_512.ktx2 b/apps/editor/public/material/fabric/white_wool/white_wool_roughness_512.ktx2 new file mode 100644 index 00000000..98db2263 Binary files /dev/null and b/apps/editor/public/material/fabric/white_wool/white_wool_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/white_wool/white_wool_thumb.webp b/apps/editor/public/material/fabric/white_wool/white_wool_thumb.webp new file mode 100644 index 00000000..2623dce8 Binary files /dev/null and b/apps/editor/public/material/fabric/white_wool/white_wool_thumb.webp differ diff --git a/apps/editor/public/material/fabric/wool_boucle/wool_boucle_basecolor_512.ktx2 b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_basecolor_512.ktx2 new file mode 100644 index 00000000..35f62d16 Binary files /dev/null and b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/wool_boucle/wool_boucle_normal_512.ktx2 b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_normal_512.ktx2 new file mode 100644 index 00000000..33ef3ade Binary files /dev/null and b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_normal_512.ktx2 differ diff --git a/apps/editor/public/material/fabric/wool_boucle/wool_boucle_thumb.webp b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_thumb.webp new file mode 100644 index 00000000..e627e159 Binary files /dev/null and b/apps/editor/public/material/fabric/wool_boucle/wool_boucle_thumb.webp differ diff --git a/apps/editor/public/material/leather/black_leather/black_leather_basecolor_512.ktx2 b/apps/editor/public/material/leather/black_leather/black_leather_basecolor_512.ktx2 new file mode 100644 index 00000000..a8967cc4 Binary files /dev/null and b/apps/editor/public/material/leather/black_leather/black_leather_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/leather/black_leather/black_leather_normal_512.ktx2 b/apps/editor/public/material/leather/black_leather/black_leather_normal_512.ktx2 new file mode 100644 index 00000000..6259e966 Binary files /dev/null and b/apps/editor/public/material/leather/black_leather/black_leather_normal_512.ktx2 differ diff --git a/apps/editor/public/material/leather/black_leather/black_leather_roughness_512.ktx2 b/apps/editor/public/material/leather/black_leather/black_leather_roughness_512.ktx2 new file mode 100644 index 00000000..b331e3cd Binary files /dev/null and b/apps/editor/public/material/leather/black_leather/black_leather_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/leather/black_leather/black_leather_thumb.webp b/apps/editor/public/material/leather/black_leather/black_leather_thumb.webp new file mode 100644 index 00000000..a7bf577b Binary files /dev/null and b/apps/editor/public/material/leather/black_leather/black_leather_thumb.webp differ diff --git a/apps/editor/public/material/leather/calf_leather/calf_leather_ao_512.ktx2 b/apps/editor/public/material/leather/calf_leather/calf_leather_ao_512.ktx2 new file mode 100644 index 00000000..3e3dfc3c Binary files /dev/null and b/apps/editor/public/material/leather/calf_leather/calf_leather_ao_512.ktx2 differ diff --git a/apps/editor/public/material/leather/calf_leather/calf_leather_basecolor_512.ktx2 b/apps/editor/public/material/leather/calf_leather/calf_leather_basecolor_512.ktx2 new file mode 100644 index 00000000..4bec7cd9 Binary files /dev/null and b/apps/editor/public/material/leather/calf_leather/calf_leather_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/leather/calf_leather/calf_leather_normal_512.ktx2 b/apps/editor/public/material/leather/calf_leather/calf_leather_normal_512.ktx2 new file mode 100644 index 00000000..9a068476 Binary files /dev/null and b/apps/editor/public/material/leather/calf_leather/calf_leather_normal_512.ktx2 differ diff --git a/apps/editor/public/material/leather/calf_leather/calf_leather_roughness_512.ktx2 b/apps/editor/public/material/leather/calf_leather/calf_leather_roughness_512.ktx2 new file mode 100644 index 00000000..aa9ac1b6 Binary files /dev/null and b/apps/editor/public/material/leather/calf_leather/calf_leather_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/leather/calf_leather/calf_leather_thumb.webp b/apps/editor/public/material/leather/calf_leather/calf_leather_thumb.webp new file mode 100644 index 00000000..6399dd03 Binary files /dev/null and b/apps/editor/public/material/leather/calf_leather/calf_leather_thumb.webp differ diff --git a/apps/editor/public/material/metal/copper_metal/copper_metal_basecolor_512.ktx2 b/apps/editor/public/material/metal/copper_metal/copper_metal_basecolor_512.ktx2 new file mode 100644 index 00000000..7e060ffd Binary files /dev/null and b/apps/editor/public/material/metal/copper_metal/copper_metal_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/metal/copper_metal/copper_metal_metallic_512.ktx2 b/apps/editor/public/material/metal/copper_metal/copper_metal_metallic_512.ktx2 new file mode 100644 index 00000000..a7c1c2a9 Binary files /dev/null and b/apps/editor/public/material/metal/copper_metal/copper_metal_metallic_512.ktx2 differ diff --git a/apps/editor/public/material/metal/copper_metal/copper_metal_normal_512.ktx2 b/apps/editor/public/material/metal/copper_metal/copper_metal_normal_512.ktx2 new file mode 100644 index 00000000..67d77b82 Binary files /dev/null and b/apps/editor/public/material/metal/copper_metal/copper_metal_normal_512.ktx2 differ diff --git a/apps/editor/public/material/metal/copper_metal/copper_metal_roughness_512.ktx2 b/apps/editor/public/material/metal/copper_metal/copper_metal_roughness_512.ktx2 new file mode 100644 index 00000000..67755a5f Binary files /dev/null and b/apps/editor/public/material/metal/copper_metal/copper_metal_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/metal/copper_metal/copper_metal_thumb.webp b/apps/editor/public/material/metal/copper_metal/copper_metal_thumb.webp new file mode 100644 index 00000000..bc4922b7 Binary files /dev/null and b/apps/editor/public/material/metal/copper_metal/copper_metal_thumb.webp differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_ao_512.ktx2 b/apps/editor/public/material/metal/polished_metal/polished_metal_ao_512.ktx2 new file mode 100644 index 00000000..9912baca Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_ao_512.ktx2 differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_basecolor_512.ktx2 b/apps/editor/public/material/metal/polished_metal/polished_metal_basecolor_512.ktx2 new file mode 100644 index 00000000..765e1565 Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_metallic_512.ktx2 b/apps/editor/public/material/metal/polished_metal/polished_metal_metallic_512.ktx2 new file mode 100644 index 00000000..ffb512d8 Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_metallic_512.ktx2 differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_normal_512.ktx2 b/apps/editor/public/material/metal/polished_metal/polished_metal_normal_512.ktx2 new file mode 100644 index 00000000..c3674540 Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_normal_512.ktx2 differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_roughness_512.ktx2 b/apps/editor/public/material/metal/polished_metal/polished_metal_roughness_512.ktx2 new file mode 100644 index 00000000..2d672c6e Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/metal/polished_metal/polished_metal_thumb.webp b/apps/editor/public/material/metal/polished_metal/polished_metal_thumb.webp new file mode 100644 index 00000000..74f5b301 Binary files /dev/null and b/apps/editor/public/material/metal/polished_metal/polished_metal_thumb.webp differ diff --git a/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_basecolor_512.ktx2 b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_basecolor_512.ktx2 new file mode 100644 index 00000000..97c228d0 Binary files /dev/null and b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_basecolor_512.ktx2 differ diff --git a/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_normal_512.ktx2 b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_normal_512.ktx2 new file mode 100644 index 00000000..07952d2a Binary files /dev/null and b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_normal_512.ktx2 differ diff --git a/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_roughness_512.ktx2 b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_roughness_512.ktx2 new file mode 100644 index 00000000..c8dd1f5f Binary files /dev/null and b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_roughness_512.ktx2 differ diff --git a/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_thumb.webp b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_thumb.webp new file mode 100644 index 00000000..2222f9b7 Binary files /dev/null and b/apps/editor/public/material/metal/stainless_steel_brushed/stainless_steel_brushed_thumb.webp differ diff --git a/packages/core/src/material-library.ts b/packages/core/src/material-library.ts index 30240d34..d743d03c 100644 --- a/packages/core/src/material-library.ts +++ b/packages/core/src/material-library.ts @@ -3448,6 +3448,574 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [ }, }, }, + { + 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-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: '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: 1, + 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: 1, + 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: 1, + 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[] { diff --git a/packages/viewer/src/components/viewer/index.tsx b/packages/viewer/src/components/viewer/index.tsx index 6f07db6d..8eaf9813 100644 --- a/packages/viewer/src/components/viewer/index.tsx +++ b/packages/viewer/src/components/viewer/index.tsx @@ -13,6 +13,7 @@ import * as THREE from 'three/webgpu' import { hasDrawableGeometry } from '../../lib/drawable-geometry' import { PERF_OVERLAY_ENABLED, pushGpuSample } from '../../lib/gpu-perf' import { applyIsolation, clearIsolation } from '../../lib/isolation' +import { ensureKtx2Support } from '../../lib/ktx2-loader' import type { ColorPreset, RenderShading } from '../../lib/materials' import { getSceneTheme } from '../../lib/scene-themes' import useViewer, { type RenderContext } from '../../store/use-viewer' @@ -144,6 +145,11 @@ function GPUDeviceWatcher() { const gl = useThree((s) => s.gl) useEffect(() => { + // Detect KTX2 transcode support as soon as the renderer exists, so catalog + // `.ktx2` finish textures load even in scenes with no GLB items (whose + // loader would otherwise be the only thing to call this). + ensureKtx2Support(gl) + const backend = (gl as any).backend const device = backend?.device as WebGPUDeviceLike | undefined diff --git a/packages/viewer/src/hooks/use-gltf-ktx2.tsx b/packages/viewer/src/hooks/use-gltf-ktx2.tsx index 040beaf7..000b8ff6 100644 --- a/packages/viewer/src/hooks/use-gltf-ktx2.tsx +++ b/packages/viewer/src/hooks/use-gltf-ktx2.tsx @@ -1,38 +1,16 @@ import { useGLTF } from '@react-three/drei' import { useThree } from '@react-three/fiber' -import { KTX2Loader } from 'three/examples/jsm/Addons.js' import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js' - -const ktx2LoaderInstance = new KTX2Loader() -ktx2LoaderInstance.setTranscoderPath('https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/') -const ktx2ConfiguredRenderers = new WeakSet() -const ktx2WarningLoggedRenderers = new WeakSet() +import { ensureKtx2Support, ktx2Loader } from '../lib/ktx2-loader' const useGLTFKTX2 = (path: string): ReturnType => { const gl = useThree((state) => state.gl) return useGLTF(path, true, true, (loader) => { - const renderer = gl as unknown as object - - if (!ktx2ConfiguredRenderers.has(renderer)) { - try { - ktx2LoaderInstance.detectSupport(gl) - ktx2ConfiguredRenderers.add(renderer) - } catch (error) { - // Some WebGPU flows can transiently call this before backend init. - // Avoid crashing the whole scene; scans may render without KTX2 on this pass. - if (!ktx2WarningLoggedRenderers.has(renderer)) { - console.warn('[viewer] Skipping KTX2 support detection for now.', error) - ktx2WarningLoggedRenderers.add(renderer) - } - } - } - - if (ktx2ConfiguredRenderers.has(renderer)) { + if (ensureKtx2Support(gl)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - loader.setKTX2Loader(ktx2LoaderInstance as any) + loader.setKTX2Loader(ktx2Loader as any) } - loader.setMeshoptDecoder(MeshoptDecoder) }) } diff --git a/packages/viewer/src/lib/ktx2-loader.ts b/packages/viewer/src/lib/ktx2-loader.ts new file mode 100644 index 00000000..c185ca8f --- /dev/null +++ b/packages/viewer/src/lib/ktx2-loader.ts @@ -0,0 +1,40 @@ +import { KTX2Loader } from 'three/examples/jsm/Addons.js' + +/** + * Single shared KTX2 loader for the whole viewer — used both by the GLB loader + * (`use-gltf-ktx2`) and by catalog finish textures (`materials.ts`). KTX2 must + * be transcoded at load via the Basis WASM, and `detectSupport(renderer)` has to + * run once before any `.ktx2` is loaded so the loader picks a GPU format the + * device supports. `ensureKtx2Support` is idempotent per renderer and is called + * from the viewer root the moment the renderer is ready (even when no GLB is in + * the scene, so catalog `.ktx2` finishes still load). + */ +export const ktx2Loader = new KTX2Loader() +ktx2Loader.setTranscoderPath('https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/') + +const configuredRenderers = new WeakSet() +const warnedRenderers = new WeakSet() + +/** Returns true once support has been detected for this renderer (KTX2 safe to load). */ +export function ensureKtx2Support(renderer: unknown): boolean { + const key = renderer as object | null + if (!key) return false + if (configuredRenderers.has(key)) return true + try { + ;(ktx2Loader as unknown as { detectSupport: (r: unknown) => void }).detectSupport(renderer) + configuredRenderers.add(key) + return true + } catch (error) { + // Some WebGPU flows can transiently call this before backend init; don't + // crash the scene — a later call (or the next render) retries. + if (!warnedRenderers.has(key)) { + console.warn('[viewer] Skipping KTX2 support detection for now.', error) + warnedRenderers.add(key) + } + return false + } +} + +export function isKtx2Url(url: string): boolean { + return url.toLowerCase().endsWith('.ktx2') +} diff --git a/packages/viewer/src/lib/materials.ts b/packages/viewer/src/lib/materials.ts index e607f914..fbfdc1ac 100644 --- a/packages/viewer/src/lib/materials.ts +++ b/packages/viewer/src/lib/materials.ts @@ -14,6 +14,7 @@ import * as THREE from 'three' import { MeshLambertNodeMaterial, MeshStandardNodeMaterial } from 'three/webgpu' import { resolveCdnUrl } from './asset-url' +import { isKtx2Url, ktx2Loader } from './ktx2-loader' import { getSceneTheme } from './scene-themes' export type RenderShading = 'solid' | 'rendered' @@ -105,6 +106,14 @@ const surfaceRoleMaterialCache = new Map() const textureCache = new Map() const textureLoadPromises = new Map>() const textureLoader = new THREE.TextureLoader() + +// `.ktx2` finish maps transcode through the shared KTX2 loader (support is +// detected once at viewer init); everything else loads as a normal image. +function pickTextureLoader(url: string): THREE.TextureLoader { + // KTX2Loader's load/loadAsync are call-compatible with TextureLoader (url → + // Texture / Promise); cast for typing. + return isKtx2Url(url) ? (ktx2Loader as unknown as THREE.TextureLoader) : textureLoader +} const wrapMap = { Repeat: THREE.RepeatWrapping, ClampToEdge: THREE.ClampToEdgeWrapping, @@ -183,7 +192,7 @@ function getTexture(material?: MaterialSchema): THREE.Texture | undefined { const cached = textureCache.get(cacheKey) if (cached) return cached - const texture = textureLoader.load(textureConfig.url) + const texture = pickTextureLoader(textureConfig.url).load(textureConfig.url) texture.wrapS = THREE.RepeatWrapping texture.wrapT = THREE.RepeatWrapping @@ -251,7 +260,7 @@ function getPresetTexture( const cached = textureCache.get(cacheKey) if (cached) return cached - const texture = textureLoader.load(resolvedPath) + const texture = pickTextureLoader(resolvedPath).load(resolvedPath) applyTextureProperties(texture, props, slot) setTextureCacheKey(texture, cacheKey) textureCache.set(cacheKey, texture) @@ -295,7 +304,7 @@ async function loadPresetTexture( const existingPromise = textureLoadPromises.get(cacheKey) if (existingPromise) return existingPromise - const promise = textureLoader + const promise = pickTextureLoader(resolvedPath) .loadAsync(resolvedPath) .then((texture) => { applyTextureProperties(texture, props, slot)