如何在THREE.js中为具有图像纹理的对象制作透明孔?

时间:2016-07-30 07:48:03

标签: three.js

我做了一个有墙壁,天花板和地板的房子。 现在我正试图在墙/门上打洞。 但是墙壁的纹理存在问题。

这是构建墙的功能:

function build_wall(start, end, materialFront, id){

        var dx = end.x - start.x;
        var dy = end.y - start.y;
        var wall_length = Math.sqrt(dx*dx + dy*dy);

        var centroid_x = start.x + dx/2;
        var centroid_y = (start.y + dy/2) * -1;

        var ry = Math.atan2(dy, dx);

        var materialBack = new THREE.MeshLambertMaterial( { color: 0xd9d9d9, shading: THREE.FlatShading, side: THREE.BackSide} );
        var materialTop = new THREE.MeshBasicMaterial({color: 0xb3b3b3, side: THREE.DoubleSide});

        var materials = [materialFront, materialBack, materialTop];
        var material = new THREE.MeshFaceMaterial(materials);

        var rectShape = new THREE.Shape();
        rectShape.moveTo( 0, 0 );
        rectShape.lineTo( 0, wall_height );
        rectShape.lineTo( wall_length, wall_height );
        rectShape.lineTo( wall_length, 0 );
        rectShape.lineTo( 0, 0 );

        var windowHole = new THREE.Path();
        windowHole.moveTo(20, 180);
        windowHole.lineTo(20, 160);
        windowHole.lineTo(40, 160);
        windowHole.lineTo(40, 180);

        rectShape.holes.push(windowHole);

        var extrudeSettings = { amount: 5, bevelEnabled: true, bevelSegments: 0, steps: 1, bevelSize: 0, bevelThickness: 1 };

        var wall = new THREE.ExtrudeGeometry( rectShape, extrudeSettings );
        for ( var face in wall.faces ) {
            if (wall.faces[ face ].normal.z > 0.9) wall.faces[ face ].materialIndex = 0;
            else if (wall.faces[ face ].normal.z < -0.9) wall.faces[ face ].materialIndex = 1;
            else wall.faces[ face ].materialIndex = 2;
        }

        var wall_mesh = new THREE.Mesh(wall, material);

        wall_mesh.position.set( start.x, 0, -start.y );
        wall_mesh.rotation.set(0, ry, 0);
        wall_mesh.name = id;
        wall_mesh.data = 'wall';

        scene.add(wall_mesh);
    }

我在init()中调用此函数:

//------Add Walls
            coordArray.push(coordArray[0]); //push the first corner to close loop

            for(var i = 0; i < coordArray.length-1; i++){ //iterate over the coordinate array, pushing vertices to the geometry
                var start_wall = coordArray[i];
                var end_wall = coordArray[(i+1)];

                if(!Rooms[r].wall_show || Rooms[r].wall_show[i] == 1){
                    var wallTexture = new THREE.TextureLoader().load( "images/room_" + r + "_wall_" + i + ".jpg" );

                    var wall_material = new THREE.MeshBasicMaterial({
                        map: wallTexture,
                        side: THREE.FrontSide,
                        overdraw: 0.5
                    });

                    build_wall( start_wall, end_wall, wall_material, scene_id);
                }


                //find tour boundary, find center target
                if(start_wall.x > maxX) maxX = start_wall.x;
                if(start_wall.y > maxY) maxY = start_wall.y;
                if(start_wall.x < minX) minX = start_wall.x;
                if(start_wall.y < minY) minY = start_wall.y;

            }

结果如下:

The screenshot of the result

1 个答案:

答案 0 :(得分:0)

对不起,这是因为我没有将UV调整到[0,1]范围。

var uvs = wall.faceVertexUvs[0];
        for (var i = 0; i < uvs.length; i++) {

            uv = uvs[i];

            for (var j = 0; j < uv.length; j++) {

                u = uv[j];

                u.x = u.x / wall_length;
                u.y = u.y/ wall_height;
            }
        }

        var wall_mesh = new THREE.Mesh(wall, material);

        wall_mesh.position.set( start.x, 0, -start.y );
        wall_mesh.rotation.set(0, ry, 0);
        wall_mesh.name = id;
        wall_mesh.data = 'wall';

        scene.add(wall_mesh);