Three.js多种材料:如何改变透明度?

时间:2017-07-13 12:48:16

标签: javascript three.js

我正在尝试更改使用MTLLoader.js和OBJLoader.js导入的多面体的透明度。这是我用来加载多面体的代码:

// Model
var obj_file_name = file_name + ".obj";
var mtl_file_name = file_name + ".obj.mtl";
var dual_file_name = file_name + "-dual.obj";

var onProgress = function ( xhr ) {
    if ( xhr.lengthComputable ) {
        var percentComplete = xhr.loaded / xhr.total * 100;
        console.log( Math.round(percentComplete, 2) + '% downloaded' );
    }
};
var onError = function ( xhr ) { };
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'obj/' );
mtlLoader.load( mtl_file_name, function( materials ) {
    materials.preload();
    var objLoader = new THREE.OBJLoader();
    objLoader.setMaterials( materials );
    objLoader.setPath( 'obj/' );
    objLoader.load( obj_file_name, function ( object )
    {
        object.traverse(function (child)
        {
            if (child instanceof THREE.Mesh)
            {
                // Polyhedra
                child.name = "pdp-faces";
                context0.scene.add(child);
                // var geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
                // alert('From loaded OBJ: ' + geometry.vertices.length);


                // Edges
                var edges = new THREE.LineSegments(new THREE.EdgesGeometry(child.geometry), new THREE.LineBasicMaterial( {color: 0x000000}) );
                edges.name = "pdp-edges";
                context0.scene.add(edges);

                // Vertices
                var geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
                // alert('After EdgesGeometry(): ' + geometry.vertices.length);
                var vertices = [];
                var isNew;
                var tolerance = 0.0000001;
                if (geometry.vertices.length > 0)
                {
                    vertices.push(new THREE.Vector3(geometry.vertices[0].x, geometry.vertices[0].y, geometry.vertices[0].z));
                }
                for (i = 1; i < geometry.vertices.length; i++)
                {
                    l = vertices.length;
                    isNew = true;
                    for (j = 0; j < l; j++)
                    {
                        var d = geometry.vertices[i].distanceTo(vertices[j]);
                        if (d < tolerance)
                        {
                            isNew = false;
                        }
                    }
                    if (isNew == true)
                    {
                        vertices.push(new THREE.Vector3(geometry.vertices[i].x, geometry.vertices[i].y, geometry.vertices[i].z));
                    }
                }

                // Fit screen
                child.geometry.computeBoundingSphere();
                var fov = context0.camera.fov * ( Math.PI / 180 );
                var objectSize = child.geometry.boundingSphere.radius;
                var distance = 0.7*Math.abs( objectSize / Math.sin( fov / 2 ) );
                context0.camera.position.z = distance;
                context0.camera.position.x = distance;
                context0.camera.position.y = distance;
            }
        });
    }, onProgress, onError );
});

此后,我使用以下代码更改其透明度:

   context0.scene.getObjectByName("pdp-faces").material.transparent = true;
   context0.scene.getObjectByName("pdp-faces").material.opacity = (1 - val/100.0);

问题是代码仅适用于单一材质。我的意思是,如果加载了具有两个或更多颜色面的多面体OBJ,我就无法以这种方式改变其透明度。

Here是一个显示问题的视频。

Here是该计划网站。

拜托,你能帮助我吗?

提前致谢,温贝托。

1 个答案:

答案 0 :(得分:1)

在three.js中,当可渲染对象具有多个材质时,mesh.material是一个数组。因此,如果要更改材质的不透明度,则需要使用此模式:

object.material[ 0 ].opacity = 0.5;
object.material[ 1 ].opacity = 0.5;

请务必为每种材料设置transparent为真。

您可以测试材质是否是这样的数组:

if ( Array.isArray( object.material ) ) {

    // your code

}

three.js r.86