Material
Как выглядит 3D-поверхность. Встроенные виды — статические фабрики: Material.lit (PBR),
Material.unlit (плоский), Material.video, Material.shadow — и кастомные скомпилированные шейдеры
тоже грузятся как материалы. Юниформы задаются через .set() / прокси uniforms, который приводит
каждое JS-значение к нужному нативному вызову юниформа. Присваивай мешу через mesh.material — см.
Mesh.
Обзор
const tex = await Texture.load(asset('./crate.jpg'))
const crate = Mesh.box({ material: Material.lit({ color: '#ffffff', map: tex }) })
const marker = Mesh.sphere({ material: Material.unlit({ color: '#0f0' }) })
scene.add(crate, marker)
crate.material.set('roughness', 0.3).set('metallic', 1)Фабрики
Material.lit(options?: { color?: ColorInput, map?: Texture | Canvas | null }): Material // PBR с освещением
Material.unlit(options?: { color?: ColorInput, map?: Texture | Canvas | null }): Material // плоский, игнорирует свет
Material.video(map?: Texture): Material // сэмплит текстуру VideoPlayer
Material.shadow(color = '#000000aa'): Material // ловец теней: невидим, кроме мест, куда падают тени
Material.load(url: string): Promise<Material> // кастомный скомпилированный шейдер (.mat / filamat)litтребует света, чтобы быть видимым — IBL и/илиLight.sun().videoберёт текстуру изVideoPlayer.texture.shadow— AR-классика: плоскость земли, показывающая только падающие на неё тени.
Цвет и карта
material.color = '#ff8800' // любой ColorInput
material.map = tex // Texture или Canvas (запекается в текстуру при присвоении)
material.map = null // убрать картуcolor и map — удобства поверх нижележащих юниформов (baseColor / baseColorMap у lit/unlit,
color у shadow). На кастомном материале они не знают имён юниформов — color тихий no-op, а
map пишет baseColorMap; задавай свои юниформы напрямую.
Кастомные шейдеры и юниформы
const material = await Material.load(asset('./hologram.mat'))
// или из ответа, который у тебя уже есть:
const material = new Material(await fetch(asset('./hologram.mat'), { useOnce: true }))
material.set(key: string, value): this // чейнится
material.uniforms[key] = value // то же, в стиле свойства
material.uniforms.speed // чтение возвращает последнее ТВОЁ значение (нативного чтения нет)Каждый тип значения приводится к конкретному вызову юниформа:
| JS-значение | Приводится к |
|---|---|
строка '#rrggbb' |
RGB-цвет |
строка '#rrggbbaa' |
RGBA-цвет |
number |
float |
boolean |
bool |
Texture |
сэмплер (учитывает wrapS/wrapT текстуры) |
number[] / Float32Array |
массив float / вектор |
null |
очищает юниформ |
строки цвета здесь должны быть #-hex — более широкие формы ColorInput (rgba(…), упакованные
int) понимает только сеттер color, не set(). И обёртка Vec3/Quat не приводится —
разверни её в обычный массив: material.set('dir', [...v]).
Окклюзионный материал сцены
scene.occlusionMaterial отдаёт окклюзионный материал сцены как обычный Material, чтобы ты задавал
на нём юниформы — см. Scene (гейтится хостом: недоступен в веб-вьювере).
Подводные камни
// ✗ ждать, что material.color сработает на кастомном шейдере
customMat.color = '#f00' // no-op: SDK не знает имя твоего юниформа
// ✓ адресуй юниформ напрямую
customMat.set('baseColor', '#ff0000')
// ✗ передавать Vec3 как значение юниформа
mat.set('lightDir', dir) // не Array — приводится к NULL, не к vec3
// ✓
mat.set('lightDir', [...dir])