使用 GLTF 支持混合材质/纹理
Posted
技术标签:
【中文标题】使用 GLTF 支持混合材质/纹理【英文标题】:Blended materials / textures support using GLTF 【发布时间】:2019-08-21 13:19:42 【问题描述】:在讨论这个问题之前,我想强调一下,在 3D 建模、纹理和渲染技术方面,我远非专家。我知道一些基础知识,但如果我的处理方法一开始就有问题,请告诉我。
另外,请原谅缺少嵌入图像。 *** 要求我先获得 10 点声望...
问题
我目前正在处理一个项目,该项目涉及一个管道,其中模型在 Blender (2.80 Beta) 中创建,导出为 GLTF using these export settings,然后导入 three.js 0.102.1。这适用于大多数模型。但是,当我想导出我的地形模型时,材质并没有按预期导出(或可能导入)。
Example image of the problem
由于这是地形,因此首选多个纹理(或更好的材质),在它们相交的地方混合它们。当然,这可以对整个地形使用一个巨大的纹理来完成,但是使用多个纹理的美妙之处在于您只需在整个地形上重复它们,并使用蒙版来确定混合。您无需创建庞大的单一纹理即可保持高水平的细节。
为什么我认为 GLTF 是瓶颈
这不是搅拌机:
在 Blender 中,地图看起来很好,并且材料按预期混合:Blending of grass and dirt
使用以下节点设置:Material node graph
不是三.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 terrainProper blending
所以我猜是 GLTF?
当然,可能是 exporter 或 importer 在这里失败了。
将 GLTF 重新导入 Blender 会得到与 three.js 相同的结果(黑色地形,白色高光,污垢应该去的地方),所以我怀疑这是问题所在。 在导出方面我真的一无所知,所以问题可能出在此处。此外,当我尝试阅读和理解 GLTF 2.0 规范时,我在材料或纹理规范中没有看到任何允许混合或混合的任何内容。
我还遇到了KHR_technique_webgl
扩展,它也可能解决这个问题,尽管我不确定具体细节。
结论
由于我真的很想避免使用硬编码解决方案或使用单个巨型纹理,因此 GLTF 仍然是我的选择。那么,我是否遗漏了我的管道中的任何内容?此时是否可以在这种情况下使用 GLTF?有什么作品可以支持这样的材料吗?
任何形式的见解将不胜感激。谢谢。
其他链接:
Blend file Image album【问题讨论】:
【参考方案1】:不幸的是,在撰写本文时,您无法导出任何格式来保留 Blender 中的自定义节点图并将其导入实时引擎。每个 Principled BSDF 套接字一个纹理是您所能做的。如果有帮助,glTF 导出器中有一个选项可以包含纹理变换(旋转、缩放、重复)。
对于像这样的自定义内容,我建议为您的材质添加名称和自定义属性(文本或数字)。在导出设置中启用“导出自定义属性/附加”,这些将作为material.userData
传递到threejs,您可以从中重建节点图。
【讨论】:
啊,我还没有想到使用自定义属性。那我大概会走这条路,非常感谢!【参考方案2】:我知道它的旧帖子,但我发现 Blender 导出不混合节点。
【讨论】:
以上是关于使用 GLTF 支持混合材质/纹理的主要内容,如果未能解决你的问题,请参考以下文章