如何使用Three.js将多个纹理/材质加载到模型中?

时间:2013-07-30 05:51:09

标签: javascript 3d three.js webgl textures

我正在使用一些示例代码,我刚刚使用JSONLoader添加了我的模型。我可以只用一个纹理加载对象,并且它们绘制得恰到好处。但是在我导入一个物体后,在这种情况下,一个房子有不同的纹理/材料(草,屋顶,窗户等),但我的模型只是以浅灰色显示。

这是我启动并运行的示例: http://trakalas.com/test/sandbox.php

这是Blender中的模型(.3ds),然后将其导出为.js: Image of model in Blender with textures

这是我正在使用的主要代码:

<script>

// MAIN

// standard global variables
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
// custom global variables
var cube;

init();
animate();

// FUNCTIONS        
function init() 
{
    // SCENE
    scene = new THREE.Scene();

    // CAMERA
    var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
    var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
    camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
    scene.add(camera);
    camera.position.set(0,550,50);
    camera.lookAt(scene.position);  

    // RENDERER
    if ( Detector.webgl )
        renderer = new THREE.WebGLRenderer( {antialias:true} );
    else
        renderer = new THREE.CanvasRenderer(); 
    renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
    container = document.getElementById( 'ThreeJS' );
    container.appendChild( renderer.domElement );

    // EVENTS
    THREEx.WindowResize(renderer, camera);
    THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });

    // CONTROLS
    controls = new THREE.OrbitControls( camera, renderer.domElement );

    // STATS

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.bottom = '0px';
    stats.domElement.style.zIndex = 100;
    container.appendChild( stats.domElement );

    // LIGHT
    var light = new THREE.PointLight(0xffffff);
    light.position.set(0,250,50);
    scene.add(light);

    // FLOOR
    var floorTexture = new THREE.ImageUtils.loadTexture( 'images/checkerboard.jpg' );
    floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; 
    floorTexture.repeat.set( 10, 10 );
    var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } );
    var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
    var floor = new THREE.Mesh(floorGeometry, floorMaterial);
    floor.position.y = -0.5;
    floor.rotation.x = Math.PI / 2;
    scene.add(floor);

    // SKYBOX/FOG
    var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 );
    var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x9999ff, side: THREE.BackSide } );
    var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
    // scene.add(skyBox);
    scene.fog = new THREE.FogExp2( 0x9999ff, 0.00025 );

    //////////////
    // THE REST //
    //////////////

    addSomething(-120,100,1);
}

function addSomething(posx,posy,posz) {
    var jsonLoader = new THREE.JSONLoader();
    jsonLoader.load("models/residential_001.js",
            function (geometry) {
                addObject(geometry,posx,posy,posz)
            });
}

function addObject(geometry,posx,posy,posz) {

    var materialArray = [];
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Asphalt .bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Brick Ru.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Brick Wh.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Grass Gr.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Lead.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Poured c.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Roof 4.bmp' ) }));
    materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'models/Wood Gra.bmp' ) }));
    var houseMaterials = new THREE.MeshLambertMaterial(materialArray);                  

    house = new THREE.Mesh(geometry, houseMaterials);
    house.position.set(posx, posy, posz);
    house.scale.set(100, 100, 100);
    scene.add(house);
}


function animate() 
{
    requestAnimationFrame( animate );
    render();       
    update();
}

function update()
{
    if ( keyboard.pressed("z") ) 
    { 
        // do something
    }

    controls.update();
    stats.update();
}

function render() 
{
    renderer.render( scene, camera );
}

</script>

将垫子/纹理加载到像我这样的物体的正确方法是什么?

非常感谢。

1 个答案:

答案 0 :(得分:1)

您只从JSON模型文件导入几何体,为什么不导入几何体和材质?

            loader = new THREE.JSONLoader();
            loader.load( "models/residential_001.js", function( geometry, materials ) {
                house = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
                house.position.set( -120, 100, 1 );
                house.scale.set( 1, 1, 1 );
                scene.add( house );
            } );