Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A sphere with texture in Three.js

I'm new to Three.js so I ask a basic question. I can't load texture on sphere. It's in function createEarthMaterial. My image with texture is called 'map2.png'. I tryed almost everything. My code comes form "Three.js Essentials" book and it doesn't work. Can U give any good solution? Thanks in advance. Here's code:

     // 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);
like image 757
mac Avatar asked Dec 23 '14 12:12

mac


1 Answers

You do not account for the fact that Image loading is asynchronous. Take a look at the example http://threejs.org/examples/#canvas_geometry_earth and the image loading code:

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 );

} );
like image 117
gaitat Avatar answered Oct 03 '22 05:10

gaitat