如何在球体上显示材质

时间:2012-10-08 12:10:14

标签: three.js

// 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放在飞机上。

1 个答案:

答案 0 :(得分:0)

您需要使用loadTexture函数的回调。如果您参考source of 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);
});