使用GLTF支持混合材料/纹理

时间:2019-03-31 01:26:01

标签: three.js blender gltf

在开始讨论问题之前,我想强调的是,在3D建模,纹理化和渲染技术方面,我还不是专家。我知道一些基本知识,但是请首先让我知道我的处理方法是否错误。

也请原谅缺少嵌入式图像。 StackOverflow要求我首先赢得10个声誉...

问题

我目前正在从事一个涉及管道的项目,其中在 Blender(2.80 Beta)中创建模型,将其导出为GLTF using these export settings,然后在 3中导入.js 0.102.1 。这对于大多数模型都适用。但是,当我要导出地形模型时,材料并没有按预期导出(或导入)。

Example image of the problem

由于这是地形,因此首选多个纹理(或更好的材质),并在它们相交的位置混合它们。当然,可以在整个地形上使用一个巨大的纹理来完成此操作,但是使用多个纹理的好处在于,您只需在整个地形上重复它们,然后使用遮罩确定混合即可。您可以保持较高的细节水平,而不必创建大量的奇异纹理。

为什么我认为GLTF是瓶颈

不是Blender:

在Blender中,地图看起来很好,并且可以按预期混合材质:
Blending of grass and dirt

使用以下节点设置:
Material node graph

不是three.js:

我已经使用NodeMaterials在three.js中创建了类似的材质设置:

// 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项目中):
Properly textured terrain
Proper blending

所以我想这是GLTF吗?

当然,可能是出口商进口商在这里失败。

  • 将GLTF导入Blender会得到与three.js相同的结果(黑色地形带有白色高光,应该去污垢),所以我怀疑这就是问题所在。
  • 关于出口,我真的很茫然,所以问题可能出在这里。

此外,当我尝试阅读和理解GLTF 2.0规范时,我在材质或纹理规范中看不到任何允许进行任何混合或混合的内容。
我还遇到了KHR_technique_webgl扩展名,尽管我不确定具体细节,但它也可能解决此问题。

结论

由于我真的很想避免使用硬编码的解决方案或使用单一的巨型纹理,因此GLTF仍然是我的选择。那么,我在管道中缺少任何内容吗?目前可以在这种情况下使用GLTF吗?作品中是否有任何东西可以支持这样的材料?

任何见解将不胜感激。谢谢。

其他链接:

1 个答案:

答案 0 :(得分:0)

不幸的是,在撰写本文时,没有可以导出到的格式可以保留Blender中的自定义节点图并将其放入实时引擎中。每个Principled BSDF插槽只需一个纹理即可。如果有帮助,glTF导出器中可以选择包含纹理转换(旋转,缩放,重复)。

对于类似这样的自定义内容,建议您在材料中添加名称和自定义属性(文本或数字)。在导出设置中启用“导出自定义属性/附加”后,这些将作为material.userData传递到threejs中,您可以从中重构节点图。