Поддержка смешанных материалов / текстур с использованием GLTF

Прежде чем я перейду к проблеме, я хочу подчеркнуть, что я далек от эксперта в том, что касается методов 3D-моделирования, текстурирования и рендеринга. Я знаю некоторые основы, но, пожалуйста, дайте мне знать, если мой подход к этому изначально неверен.

Также простите за отсутствие встроенных изображений. StackOverflow требует, чтобы я сначала заработал 10 репутации ...

Эта проблема

В настоящее время я работаю над проектом, который включает конвейер, в котором модели создаются в Blender (2.80 Beta), экспортируются как GLTF , используя эти настройки экспорта, а затем импортированный в three.js 0.102.1. Это отлично работает для большинства моделей. Однако, когда я хочу экспортировать свою модель ландшафта, материалы не экспортируются (или, возможно, не импортируются), как ожидалось.

Пример изображения проблемы

Поскольку это местность, предпочтительнее использовать несколько текстур (или, лучше сказать, материалов), смешивая их в местах пересечения. Конечно, это можно сделать, используя одну гигантскую текстуру для всего ландшафта, но прелесть использования нескольких текстур в том, что вы просто повторяете их по всей местности и используете маску для определения смешивания. Вы сохраняете высокий уровень детализации без необходимости создавать массивную уникальную текстуру.

Почему я считаю GLTF узким местом

Это не Блендер:

В Blender карта выглядит нормально, а материалы смешиваются должным образом:
Смешивание травы и грязи

Используя следующую настройку узла:
Граф узлов материала

Это не three.js:

Я создал аналогичную настройку материала в three.js, используя NodeMaterials:

// MATERIAL
let mtl = new THREE.StandardNodeMaterial();
mtl.roughness = new THREE.FloatNode( .9 );
mtl.metalness = new THREE.FloatNode( 0 );

function createUv(scale, offset) {
    let uvOffset = new THREE.FloatNode( offset || 0 );
    let uvScale = new THREE.FloatNode( scale || 1 );

    let uvNode = new THREE.UVNode();
    let offsetNode = new THREE.OperatorNode(
        uvOffset,
        uvNode,
        THREE.OperatorNode.ADD
    );
    let scaleNode = new THREE.OperatorNode(
        offsetNode,
        uvScale,
        THREE.OperatorNode.MUL
    );

    return scaleNode;
}

let grass = new THREE.TextureNode( getTexture("grass"), createUv(35) );
let dirt = new THREE.TextureNode( getTexture("dirt"), createUv(35) );
let mask = new THREE.TextureNode( getTexture("mask"), createUv() );
let maskAlphaChannel = new THREE.SwitchNode(mask, "w");
let blend = new THREE.Math3Node(
    grass,
    dirt,
    maskAlphaChannel,
    THREE.Math3Node.MIX
);
mtl.color = blend;
mtl.normal = new THREE.NormalMapNode(
    new THREE.TextureNode( getTexture("dirtNormal"), createUv(35) )
);

let normalMask = new THREE.OperatorNode(
    new THREE.TextureNode( getTexture("mask"), createUv() ),
    new THREE.FloatNode(1),
    THREE.OperatorNode.MUL
);

mtl.normalScale = normalMask;

// build shader
mtl.build();

// set material
return mtl;

В результате получается следующий, довольно прилично выглядящий ландшафт (это в моем проекте three.js):
Правильно текстурированный ландшафт
Правильное смешивание

Полагаю, это GLTF?

Конечно, здесь может быть ошибка экспортера или импортера.

  • Импорт GLTF обратно в Blender дает тот же результат, что и three.js (черный ландшафт с белыми бликами там, где должна была идти грязь), поэтому я сомневаюсь, что проблема в этом.
  • Я действительно в неведении, когда дело доходит до экспорта, так что проблема может заключаться в этом.

Кроме того, когда я попытался прочитать и понять спецификацию GLTF 2.0, я не увидел ничего в спецификациях материалов или текстур, которые позволяли бы смешивать или смешивать любого рода.
Я также наткнулся на расширение KHR_technique_webgl, которое потенциально могло разрешить эта проблема тоже, хотя я не уверен в деталях.

Заключение

Поскольку я действительно хотел бы избежать жестко запрограммированного решения или использования одной гигантской текстуры, GLTF по-прежнему будет для меня лучшим вариантом. Итак, я что-то упустил в моем конвейере? Можно ли в данном случае использовать GLTF в данный момент? Есть ли в работе что-нибудь, что могло бы поддержать подобные материалы?

Мы будем благодарны за любую информацию. Спасибо.

Дополнительные ссылки:


person Zemanzo    schedule 31.03.2019    source источник


Ответы (1)


К сожалению, нет формата, в который можно экспортировать, который сохранил бы настраиваемый граф узлов из Blender и передал его в движок реального времени на момент написания этой статьи. Одна текстура на сокет Principled BSDF - это все, что вы можете сделать. В экспортере glTF есть опция для включения преобразования текстуры (поворот, масштаб, повтор), если это помогает.

Для чего-то подобного, я бы предложил добавить к вашим материалам имена и настраиваемые свойства (текстовые или числовые). Если в настройках экспорта включен параметр «Экспорт пользовательских свойств / дополнительных функций», они будут переданы в threejs как material.userData, и вы сможете восстановить из этого граф узлов.

person Don McCurdy    schedule 31.03.2019
comment
А, об использовании настраиваемых свойств я еще не думал. Тогда я, наверное, пойду по этому пути, большое вам спасибо! - person Zemanzo; 31.03.2019