0
// set the scene size
var WIDTH = 1650,
    HEIGHT = 700;

// set some camera attributes
var VIEW_ANGLE = 100,
    ASPECT = WIDTH / HEIGHT,
    NEAR = 0.1,
    FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(  VIEW_ANGLE,
                                ASPECT,
                                NEAR,
                                FAR  );

//camera.lookAt(new THREE.Vector3( 0, 0, 0 ));

var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.x = 200;
camera.position.y = 200;
camera.position.z = 300;


// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
    color: 0xCC0000
});

// set up the sphere vars
var radius = 60, segments = 20, rings = 20;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
   new THREE.SphereGeometry(radius, segments, rings),
   img);

// add the sphere to the scene
scene.add(sphere);

// and the camera
scene.add(camera);

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 50;
pointLight.position.y = 100;
pointLight.position.z = 180;

// add to the scene
scene.add(pointLight);

// add a base plane
var planeGeo = new THREE.PlaneGeometry(500, 500,8, 8);
var planeMat = new THREE.MeshLambertMaterial({color: 0x666699});
var plane = new THREE.Mesh(planeGeo, planeMat);

plane.position.x = 160;
plane.position.y = 0;
plane.position.z = 20;

//rotate it to correct position
plane.rotation.x = -Math.PI/2;
scene.add(plane);

// add 3D img

var img = new THREE.MeshBasicMaterial({
map:THREE.ImageUtils.loadTexture('cube.png')
});
img.map.needsUpdate = true;

// draw!
renderer.render(scene, camera);

我已经将 var img 作为球体的材料,但每次我渲染它时都会自动改变颜色......我该怎么做才能拥有我想要的图像......不是所有的颜色?我可能会把img放在飞机上。

4

1 回答 1

0

您需要使用 loadTexture 函数的回调。如果您参考源代码,THREE.ImageUtils您会看到 loadTexture 函数定义为

loadTexture: function ( url, mapping, onLoad, onError ) {

        var image = new Image();
        var texture = new THREE.Texture( image, mapping );

        var loader = new THREE.ImageLoader();

        loader.addEventListener( 'load', function ( event ) {

            texture.image = event.content;
            texture.needsUpdate = true;

            if ( onLoad ) onLoad( texture );

        } );

        loader.addEventListener( 'error', function ( event ) {

            if ( onError ) onError( event.message );

        } );

        loader.crossOrigin = this.crossOrigin;
        loader.load( url, image );

        return texture;

    },

这里只需要 url 参数。纹理映射可以作为 null 传入。最后两个参数是回调。您可以为每个函数传入一个函数,该函数将在相应的加载和错误事件中调用。您遇到的问题很可能是由于three.js 试图在您的纹理正确加载之前应用您的材质。为了解决这个问题,您应该只在作为 onLoad 回调传递的函数中执行此操作(仅在加载图像后调用)。此外,您应该始终在将材质应用于对象之前创建材质。

所以你应该改变你的代码:

// set up the sphere vars
var radius = 60, segments = 20, rings = 20;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
   new THREE.SphereGeometry(radius, segments, rings),
   img);

// add the sphere to the scene
scene.add(sphere);

类似于:

var sphereGeo, sphereTex, sphereMat, sphereMesh;
var radius = 60, segments = 20, rings = 20;

sphereGeo = new THREE.SphereGeometry(radius, segments, rings);
sphereTex = THREE.ImageUtils.loadTexture('cube.png', null, function () {
    sphereMat = new THREE.MeshBasicMaterial({map: sphereTex});
    sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
    scene.add(sphereMesh);
});
于 2012-10-09T05:37:36.550 回答