【问题标题】:ThreeJS: Add Two Materials on an Mesh Object三JS:在一个网格物体上添加两种材质
【发布时间】:2021-08-14 07:36:35
【问题描述】:

在 ThreeJS 中,可以根据 documentationObject3D/Mesh 添加多个材质。我们可以使用单个Material 或使用Material 的数组:

Mesh typescript 文件类声明和构造器(来自 ThreeJS src 代码):

export class Mesh<
    TGeometry extends BufferGeometry = BufferGeometry,
    TMaterial extends Material | Material[] = Material | Material[] // ### Here: Material[] ###
> extends Object3D {
    constructor(geometry?: TGeometry, material?: TMaterial);

这是我似乎无法解决的问题... 当我使用单个Material 时,会显示我的Mesh但是,当我使用两种材质作为数组时,我的Mesh 不会显示。渲染场景时,我也没有在控制台中打印出任何错误。

我在这里的最终目标是能够为我的对象的内部和外部分离材料。


这是我的代码:

export function init(radius: number = 18.0, innerColor: number = 0xFFFFFF, outerColor: number = 0x444444) {
    var obj = new Object3D();
    loader.load(
        objPath, 
        function(object){
            obj = object;
            const mesh = obj.children[0] as Mesh;
            // WORKING:
            mesh.material = new MeshPhongMaterial({color: outerColor});
            // NOT WORKING: Using two materials
            // mesh.material = new Array<Material>(new MeshPhongMaterial({color: outerColor}), new MeshPhongMaterial({color:innerColor}));
            mesh.scale.setLength(radius)
            scene.add(mesh);
        },
        function (error){
            console.log(error)
        }
    );
}

为什么我在使用两种材质时看不到我的对象?

我知道以前的版本中有MeshFaceMaterial,并且从某种意义上说,构造器的材料阵列验收应该可以替代它。


三JS版本:r128

任何帮助将不胜感激!

【问题讨论】:

  • 要在一个网格上有两种材质,网格的几何体必须有两个groups。另一种选择是修改材质并检查,如果归一化位置和法线的点积小于0,则使用innerColor,否则使用outerColor
  • 另一种选择是拥有两个相同的网格(它们可以共享几何体),其中一个的材质设置为THREE.FrontSide,另一个网格的材质设置为THREE.BackSide。不过,这可能会导致 z-fighting,因此您可能还需要将 polygonOffset 应用于其中一个或另一个。

标签: javascript typescript three.js webgl


【解决方案1】:

最简单的方法是克隆您的网格并分配两种单独的材质,一种用于内部,另一种用于外部:

const meshOuter = obj.children[0] as THREE.Mesh;
const meshInner = meshOuter.clone();

// Outer mesh shows front side
meshOuter.material = new THREE.MeshPhongMaterial({
    color: outerColor,
    side: THREE.FrontSide
});
// Inner mesh shows back side
meshInner.material = new THREE.MeshPhongMaterial({
    color: innerColor,
    side: THREE.BackSide
});

// Scale inner mesh down just a bit to avoid z-fighting
meshInner.scale.multiplyScalar(0.99);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多