我是Three.js的新手,所以我问一个基本问题。我不能在球体上加载纹理。 它在函数createEarthMaterial中。我的纹理图像称为'map2.png'。 我几乎尝试了一切。我的代码来自“Three.js Essentials”一书,它不起作用。你能给出任何好的解决方案吗?提前致谢。 这是代码:
// global variables
var renderer;
var scene;
var camera;
var control;
var stats;
var cameraControl;
/**
* Initializes the scene, camera and objects. Called when the window is
* loaded by using window.onload (see below)
*/
function init() {
// create a scene, that will hold all our elements such as objects, cameras and lights.
scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render, sets the background color and the size
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xcccccc, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
var sphereGeometry = new THREE.SphereGeometry(15, 30, 30);
var sphereMaterial = createEarthMaterial();
var earthMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
earthMesh.name = 'earth';
scene.add(earthMesh);
// position and point the camera to the center of the scene
camera.position.x = 35;
camera.position.y = 36;
camera.position.z = 33;
camera.lookAt(scene.position);
// add controls
cameraControl = new THREE.OrbitControls(camera);
// setup the control object for the control gui
control = new function () {
this.rotationSpeed = 0.005;
this.opacity = 0.6;
};
// add extras
// add the output of the renderer to the html element
document.body.appendChild(renderer.domElement);
// call the render function, after the first render, interval is determined
// by requestAnimationFrame
render();
}
function createEarthMaterial() {
// 4096 is the maximum width for maps
var earthTexture = THREE.ImageUtils.loadTexture("map2.png");
var earthMaterial = new THREE.MeshBasicMaterial();
earthMaterial.map = earthTexture;
return earthMaterial;
}
/**
* Called when the scene needs to be rendered. Delegates to requestAnimationFrame
* for future renders
*/
function addControlGui(controlObject) {
var gui = new dat.GUI();
gui.add(controlObject, 'rotationSpeed', -0.01, 0.01);
}
function addStatsObject() {
stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
}
function render() {
// update stats
//stats.update();
cameraControl.update();
// update the camera
scene.getObjectByName('earth').rotation.y+=control.rotationSpeed;
// and render the scene
renderer.render(scene,camera);
// render using requestAnimationFrame
requestAnimationFrame(render);
}
/**
* Function handles the resize event. This make sure the camera and the renderer
* are updated at the correct moment.
*/
function handleResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// calls the init function when the window is done loading.
window.onload = init;
// calls the handleResize function when the window is resized
window.addEventListener('resize', handleResize, false);
答案 0 :(得分:3)
您没有考虑到Image加载是异步的这一事实。看一下示例http://threejs.org/examples/#canvas_geometry_earth和图片加载代码:
var loader = new THREE.TextureLoader();
loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
} );