Sunday, August 4, 2013

3D in Your Web Browser

Rendering a 3D image was a difficult task in early days. But now you can render a 3D image even in your web browser. Using HTML 5 with CSS 3 you can make 3D images in your web browser. But if you use JavaScript with HTML 5 you can do amazing things. But if you choose a proper JavaScript framework you will be amazed what it can do in a web browser. One such framework is three.js
three.js allows you to choose how you  render the image on your web browser. You can choose from WebGL of Canvas. WebGL uses graphics processor of your computer. So it gives you a good experience. But to use WebGL, you must use Windows operating system and Google chrome or Firefox. But Google chrome guarantees you the best user experience. But you can use Canvas in most of the operating systems and most of the web browsers which support HTML 5. But I must say that Canvas is bit slow when rendering the image. If you are using complex shapes you are advised to use WebGL renderer.
You can download three.js framework from http://threejs.org/ All you need to do is import three.js JavaScript file to your HTML page. If you need custom functionality, you have to add relevant JavaScript files that is needed.
Then you have to add a JavaScript to your HTML page. This may include two functions. init for initialization and animation for custom animations like handling the keyboard inputs.
In your HTML code add
<div id="output"></div>
Then in the JavaScript add this code.(You have to add jQuery to ease some implementations)

var scene = new THREE.Scene();
var container = $('#output');

Then get the detector.js from https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js and import it also to the page. Then,

var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var renderer;
if (Detector.webgl)
       renderer = new THREE.WebGLRenderer({antialias: true});
else
       renderer = new THREE.CanvasRenderer();
renderer.setClearColorHex(0xffffff, 1);
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container.append(renderer.domElement);
will detect whether you have WebGL renderer or not and create the necessary renderer for you will add it to the div you have previously created.

Then create the camera like this
var VIEW_ANGLE = 80, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 50, FAR = 200000;
camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.y = 0;
camera.position.z = RACK_THICKNESS*RACKS*3;
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);

Now you have done the basic initialization. Then you have to add the objects you need to the scene. If you need to a box with a hole in the middle,

var object = new THREE.Object3D();
var shape1 = new THREE.Shape();
shape1.moveTo(50, 50);
shape1.lineTo(-50, 50);
shape1.lineTo(-50, -50);
shape1.lineTo(50, -50);
shape1.lineTo(50, 50);

var hole1 = new THREE.Path();
hole1.moveTo(40, 40);
hole1.lineTo(-40, 40);
hole1.lineTo(-40, -40);
hole1.lineTo(40, -40);
hole1.lineTo(40, 40);
shape1.holes.push(hole1);

 var extrusionSettings = {
         amount: 100,
         bevelEnabled: true,
         bevelThickness: 0.5,
         bevelSize: 0.5,
         bevelSegments: 8,
         material: 0,
         extrudeMaterial: 1
};
var geometry1 = new THREE.ExtrudeGeometry(shape1, extrusionSettings);
var materialFront = new THREE.MeshLambertMaterial({
        color: 0xffff00,
        ambient: 0xffff00
});
var materialSide = new THREE.MeshLambertMaterial({
        color: 0xff8800,
        ambient: 0xff8800
});
var materials = [materialFront, materialSide];
var material = new THREE.MeshFaceMaterial(materials);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 50, 0);
object.add(mesh1);
scene.add(object);

This will create the object and add it to the scene. All this have to be done in the init function. Then in the animate function,

function animate() {
                requestAnimationFrame(animate);

                var delta = clock.getDelta();
                var moveDistance = 200 * delta;
                var rotateAngle = Math.PI / 2 * delta;

                if (keyboard.pressed("right")) {
                    object.position.x -= moveDistance;
                }
                if (keyboard.pressed("left")) {
                    object.position.x += moveDistance;
                }
                if (keyboard.pressed("up")) {
                    object.position.y -= moveDistance;
                }
                if (keyboard.pressed("down")) {
                    object.position.y += moveDistance;
                }

                var rotation_matrix_object = new THREE.Matrix4().identity();
                if (keyboard.pressed("A")) {
                    rotation_matrix_object = new THREE.Matrix4().makeRotationY(rotateAngle);
                }
                if (keyboard.pressed("D")) {
                    rotation_matrix_object = new THREE.Matrix4().makeRotationY(-rotateAngle);
                }
                if (keyboard.pressed("W")) {
                    rotation_matrix_object = new THREE.Matrix4().makeRotationX(rotateAngle);
                }
                if (keyboard.pressed("S")) {
                    rotation_matrix_object = new THREE.Matrix4().makeRotationX(-rotateAngle);
                }
                if (keyboard.pressed("A") || keyboard.pressed("D") || keyboard.pressed("W") || keyboard.pressed("S"))
                {
                    object.matrix.multiply(rotation_matrix_object);
                    object.rotation.setEulerFromRotationMatrix(object.matrix);
                }
}

This will repeatedly render the scene and add the basic keyboard functionality. You have to import THREEx.KeyboardState.js to the page. As you have created the 2 functions, all you have to do is to call these 2 functions at the start of the JavaScript.

Most of these are self explanatory. So if you know the basics of programming, you will find it easy to understand what is happening in the code.



This a sample image created using three.js framework. Combining these simple shapes you can create lot more complex shapes.


You can find more examples from http://stemkoski.github.io/Three.js/

No comments:

Post a Comment