Posts mit dem Label cube werden angezeigt. Alle Posts anzeigen
Posts mit dem Label cube werden angezeigt. Alle Posts anzeigen

Sonntag, 8. September 2013

Three.js - Heightmaps

Heightmaps are used for a rough terrain based on an image which gives us the desired heights. For adding a heightmap to a plane in three.js, 2 steps are required.

  • get data from an image
  • apply data to the vertices of the plane

Read data from image

This function returns an array with all the pixels of an image converted into a value. If the scale value is set to 1, you will get values from 1 (black) to 63,75 (white).
 
    //return array with height data from img
    function getHeightData(img,scale) {
     
     if (scale == undefined) scale=1;
     
        var canvas = document.createElement( 'canvas' );
        canvas.width = img.width;
        canvas.height = img.height;
        var context = canvas.getContext( '2d' );

        var size = img.width * img.height;
        var data = new Float32Array( size );

        context.drawImage(img,0,0);

        for ( var i = 0; i < size; i ++ ) {
            data[i] = 0
        }

        var imgd = context.getImageData(0, 0, img.width, img.height);
        var pix = imgd.data;

        var j=0;
        for (var i = 0; i<pix.length; i +=4) {
            var all = pix[i]+pix[i+1]+pix[i+2];
            data[j++] = all/(12*scale);
        }
        
        return data;
    }

Apply height data to plane

        // terrain
 var img = new Image();
 img.onload = function () {
  
     //get height data from img
     var data = getHeightData(img);
  
     // plane
     var geometry = new THREE.PlaneGeometry(10,10,9,9);
     var texture = THREE.ImageUtils.loadTexture( 'images/heightmap2.png' );
     var material = new THREE.MeshLambertMaterial( { map: texture } );
     plane = new THREE.Mesh( geometry, material );
     
     //set height of vertices
     for ( var i = 0; i<plane.geometry.vertices.length; i++ ) {
          plane.geometry.vertices[i].z = data[i];
     }

     scene.add(plane);
   
 };
 // load img source
 img.src = "images/heightmap2.png";

Example

I have a 10x10 plane with 100 vertices. My heightmap image is 10x10 px and looks like this:
Scaling the image data by 10 the result looks like this:

Important

The amount of vertices a plane has is (segmentsWidth+1) * (segmentsHeight+1).
If your image is 10x10 px it will give you 100 values. So you have to divide your plane into 9x9 segments.

For example this plane is divided into 5x5 segments, which results into 36 vertices.
var geometry = new THREE.PlaneGeometry(10,10,5,5);


Samstag, 7. September 2013

Three.js - Skybox

A skybox is a big cube in which our scene is placed inside. Our texture is drawn on the inside faces of the cube to create a sky.

Texture

The texture is divided into 6 parts, facing in all directions. Corresponding to the asex, we name them skybox-xpos.png (right), skybox-xnef.png (left), skybox-ypos.png (top), ....

This is the structure:

Creating the skybox

We first have to load all 6 textures into the material. Then we add the cube. It's as simple as that.
Keep in mind that the size of the skybox's cube has to fit into the camera's near/far viewpoint.
If the skybox is somehow rotated, you have to correct it (see example).


//skybox
 
 var imagePrefix = "images/skybox-";
 var directions  = ["xpos", "xneg", "ypos", "yneg", "zpos", "zneg"];
 var imageSuffix = ".png";
  
 var materialArray = [];
 for (var i = 0; i < 6; i++)
  materialArray.push( new THREE.MeshBasicMaterial({
   map: THREE.ImageUtils.loadTexture( imagePrefix + directions[i] + imageSuffix ),
   side: THREE.BackSide
  }));
 
 var skyGeometry = new THREE.CubeGeometry( 500, 500, 500 );
 var skyMaterial = new THREE.MeshFaceMaterial( materialArray );
 var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );
 skyBox.rotation.x += Math.PI / 2;
 scene.add( skyBox );


Three.js - Geometries

We have a set of different 3D objects we can place into our scene. For a better handling we are always using the same construct:

  • geometry: the object's geometry like cube, sphere, etc
  • material: the material/color, see materials
  • creating the object mit new TREE.Mesh()
  • positioning, rotation, etc
  • add object to scene

 
    //cube
    var geometry = new THREE.CubeGeometry(1,1,1);
    var material = new THREE.MeshNormalMaterial();
    var cube = new THREE.Mesh( geometry, material );
    cube.position.set(4,4,0.5)
    scene.add( cube );

Geometries

Plane

    //plane
    var geometry = new THREE.PlaneGeometry(10, 10)
    var material = new THREE.MeshBasicMaterial( { color: 0x666666 } );
    var plane = new THREE.Mesh( geometry, material );
    scene.add(plane);


Cube

    //cube
    var geometry = new THREE.CubeGeometry(1,1,1);
    var material = new THREE.MeshNormalMaterial();
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );


Sphere

    //sphere
    //SphereGeometry(RADIUS,SEGMENTWIDTH,SEGMENTHEIGHT)
    var geometry = new THREE.SphereGeometry(1, 100, 100);
    var material = new THREE.MeshNormalMaterial();
    var sphere = new THREE.Mesh( geometry, material );
    scene.add( sphere );


Cylinder/Cone

    //cylinder
    //CylinderGeometry(BOTTOMRADIUS,TOPRADIUS,HEIGHT,SEGMENTRADIUS,SEGMENTHEIGHT,BUTTOM)
    var geometry = new THREE.CylinderGeometry(1, 0.5, 2, 50, 50, false)
    var material = new THREE.MeshNormalMaterial();
    var cylinder = new THREE.Mesh( geometry, material );
    cylinder.rotation.x = Math.PI / 2;
    scene.add( cylinder );



For more shapes check this out: http://stemkoski.github.io/Three.js/Shapes.html