在开始讨论问题之前,我想强调的是,在3D建模,纹理化和渲染技术方面,我还不是专家。我知道一些基本知识,但是请首先让我知道我的处理方法是否错误。
也请原谅缺少嵌入式图像。 StackOverflow要求我首先赢得10个声誉...
我目前正在从事一个涉及管道的项目,其中在 Blender(2.80 Beta)中创建模型,将其导出为GLTF using these export settings,然后在 3中导入.js 0.102.1 。这对于大多数模型都适用。但是,当我要导出地形模型时,材料并没有按预期导出(或导入)。
由于这是地形,因此首选多个纹理(或更好的材质),并在它们相交的位置混合它们。当然,可以在整个地形上使用一个巨大的纹理来完成此操作,但是使用多个纹理的好处在于,您只需在整个地形上重复它们,然后使用遮罩确定混合即可。您可以保持较高的细节水平,而不必创建大量的奇异纹理。
在Blender中,地图看起来很好,并且可以按预期混合材质:
Blending of grass and dirt
使用以下节点设置:
Material node graph
我已经使用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 2.0规范时,我在材质或纹理规范中看不到任何允许进行任何混合或混合的内容。
我还遇到了KHR_technique_webgl
扩展名,尽管我不确定具体细节,但它也可能解决此问题。
由于我真的很想避免使用硬编码的解决方案或使用单一的巨型纹理,因此GLTF仍然是我的选择。那么,我在管道中缺少任何内容吗?目前可以在这种情况下使用GLTF吗?作品中是否有任何东西可以支持这样的材料?
任何见解将不胜感激。谢谢。
其他链接:
答案 0 :(得分:0)
不幸的是,在撰写本文时,没有可以导出到的格式可以保留Blender中的自定义节点图并将其放入实时引擎中。每个Principled BSDF插槽只需一个纹理即可。如果有帮助,glTF导出器中可以选择包含纹理转换(旋转,缩放,重复)。
对于类似这样的自定义内容,建议您在材料中添加名称和自定义属性(文本或数字)。在导出设置中启用“导出自定义属性/附加”后,这些将作为material.userData
传递到threejs中,您可以从中重构节点图。