LeCodesdocs

Material

Как выглядит 3D-поверхность. Встроенные виды — статические фабрики: Material.lit (PBR), Material.unlit (плоский), Material.video, Material.shadow — и кастомные скомпилированные шейдеры тоже грузятся как материалы. Юниформы задаются через .set() / прокси uniforms, который приводит каждое JS-значение к нужному нативному вызову юниформа. Присваивай мешу через mesh.material — см. Mesh.

Обзор

TypeScript
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)

Фабрики

TypeScript
Material.lit(options?: { color?: ColorInput, map?: Texture | Canvas | null,
                         roughness?: number, metallic?: number }): Material   // PBR с освещением
Material.unlit(options?: { color?: ColorInput, map?: Texture | Canvas | null }): Material  // плоский, игнорирует свет
Material.video(map?: Texture): Material              // сэмплит текстуру VideoPlayer
Material.shadow(color = '#000000aa'): Material       // ловец теней: невидим, кроме мест, куда падают тени
Material.particles(options?: { map?: Texture | null, sheet?: number | [cols, rows],
                               emissive?: number, blend?: 'alpha' | 'add', soft?: boolean,
                               render?: 'point' | 'quad' | 'stretch' | 'ribbon', stretch?: number }): Material
                                                     // спрайты/квады/ленты для Particles + Trail (их дефолт)
Material.load(url: string): Promise<Material>        // кастомный скомпилированный шейдер (.mat / filamat)
  • lit требует света, чтобы быть видимым — IBL и/или Light.sun(). Его PBR-скаляры в 0–1: roughness 0 = зеркало, 1 = матовый; metallic 0 = диэлектрик, 1 = металл (оба — обычные юниформы: не задан — действует дефолт шейдера, а .set('roughness', v) меняет их позже).
  • video берёт текстуру из VideoPlayer.texture.
  • shadow — AR-классика: плоскость земли, показывающая только падающие на неё тени.
  • particles — то, чем рисует система ParticlesTrail), когда ты не передаёшь кастомный материал — сам ты его конструируешь редко: опции Particles/Trail пробрасываются в него. Тинт/размер/поворот/непрозрачность/кадр каждой частицы приходят из кривых частиц; юниформы (sheetSize, emissive, additive, softness, плюс mode/stretch у quad-варианта) задают вид системы в целом, и опции фабрики ложатся на них. render: 'point' использует particles.filamat; остальные режимы делят particles-quad.filamat.

Цвет и карта

TypeScript
material.color = '#ff8800'            // любой ColorInput
material.map = tex                    // Texture или Canvas (запекается в текстуру при присвоении)
material.map = null                   // убрать карту

color и map — удобства поверх нижележащих юниформов (baseColor / baseColorMap у lit/unlit, color у shadow). У lit/unlit шейдер их перемножает — baseColor × baseColorMap, оба по умолчанию белые (незаданную карту подменяет 1×1 белая текстура) — поэтому цвет сам по себе или карта сама по себе проходят без изменений, цвет, заданный вместе с картой, тонирует карту, а map = null сбрасывает текстуру обратно в белую. На кастомном материале они не знают имён юниформов — color тихий no-op, а map пишет baseColorMap; задавай свои юниформы напрямую.

Кастомные шейдеры и юниформы

TypeScript
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 очищает юниформ (текстура сбрасывается в 1×1 белую)
Note

строки цвета здесь должны быть #-hex — более широкие формы ColorInput (rgba(…), упакованные int) понимает только сеттер color, не set(). И обёртка Vec3/Quat не приводится — разверни её в обычный массив: material.set('dir', [...v]).

Окклюзионный материал сцены

scene.occlusionMaterial отдаёт окклюзионный материал сцены как обычный Material, чтобы ты задавал на нём юниформы — см. Scene (гейтится хостом: недоступен в веб-вьювере).

Подводные камни

TypeScript
// ✗ ждать, что material.color сработает на кастомном шейдере
customMat.color = '#f00'                  // no-op: SDK не знает имя твоего юниформа
// ✓ адресуй юниформ напрямую
customMat.set('baseColor', '#ff0000')

// ✗ передавать Vec3 как значение юниформа
mat.set('lightDir', dir)                  // не Array — приводится к NULL, не к vec3
// ✓
mat.set('lightDir', [...dir])

Смотрите также

  • Mesh — присвоение материалов (mesh.material, setMaterial(index)).
  • Texture — загрузка карт, режимы wrap, видео-текстуры.
  • Light — на что откликаются материалы lit.
  • SceneocclusionMaterial, setMaterialGlobalParameter для кастомных шейдеров.