Skip to content

How to create a cube

bartekd edited this page Sep 30, 2022 · 27 revisions

Note: Please refer to the Hello Cube demo to see this code at work.

Here's a complete code listing to make a red rotating cube animation with J3D. Place this code in your document's <head> section:

<script type="text/javascript" src="j3d.js"></script>
<script>

var engine, cube, light;

window.onload = function() {

	engine = new J3D.Engine();	
	engine.setClearColor(J3D.Color.white);
	engine.scene.ambient = new J3D.Color(.5, .5, .5, 1);
	
	light = new J3D.Transform();
	light.light = new J3D.Light(J3D.DIRECT);
	light.light.color = new J3D.Color(.5, .5, .5, 1);
	light.light.direction = new v3(1, 0, 1).norm();
	
	cube = new J3D.Transform();
	cube.geometry = J3D.Primitive.Cube(1, 1, 1);		
	cube.renderer = J3D.BuiltinShaders.fetch("Phong");
	cube.renderer.uColor = new J3D.Color(1,0,0,1);
	
	camera = new J3D.Transform();
	camera.camera = new J3D.Camera();
	camera.position.z = 4;
	engine.camera = camera;

	engine.scene.add(camera, cube, light);

	draw();
}

function draw() {
	cube.rotation.x += Math.PI * J3D.Time.deltaTime / 6000;
	cube.rotation.y += Math.PI/2 * J3D.Time.deltaTime / 3000;
	engine.render();
	requestAnimationFrame(draw);
}

</script>

Engine

The main element of any J3D application is the engine object - you need to create and instance of J3D.Engine before you can do anything else. By default, the engine constructor function will take care of creating a full-window canvas element in your document and getting it's webgl context into a global variable called gl. If you wish to use a specific canvas you can pass is a the first argument, like this:

var canvas = document.getElementsById("mycanvas");
var engine = new J3D.Engine(canvas);

Once initialized, the engine exposes a scene property to which you can add the objects that populate your 3d world.

Before we do this however, we can define a background color called 'clear color' in WebGL. We also set the scene's ambient light property to a color value. This way, if a 3d object is not lit by any other light source it will not be entirely black. J3D uses the class J3D.Color class to define colors - the arguments are red, green, blue and alpha values in range [0-1] and some basic colors have predefined constants.

Transforms

In J3D every object in the scene is a transform. A transform is an invisible point in space that has a position, rotation and scale. You can manipulate it's properties like position, rotation or scale to move it around in 3d space. Transforms can also be nested, to form hierarchies.

We start by creating an instance of J3D.Transform and later attach different elements to it to specify it's function: whether it's a solid object, a particle system or a light source. Sometimes empty transforms make sense, if they are part of a larger hierarchy. In this tutorial, our simple scene has a light, a cube and a camera - all of them are transforms.

Light sources

Ambient light, as defined above, will allow us to see colors but everything will be flat. Since it simulates light coming from any direction at any angle, all the objects lit with ambient light will have a uniform color. To add depth to the scene we need a directional light as well. Directional light is used for distant light sources - like the sun. Because they are so far, we can approximate that all the rays coming from this source are parallel. Directional light is the only light type currently supported by J3D.

Going back to our transform that will be the light source: it has a light property to which we assign an instance of J3D.Light. This way we inform the engine that this is a light source. Note that in case of directional light, it's position and rotation in space don't matter - only the direction of the light does.

3D Objects - geometries and renderers

The cube transform that we create next will hold our 3d cube object. A 3d object needs to have two properties: geometry that defines it's shape and renderer that defined how it will look. For the shape we use the build in J3D.Primitive.Cube function to create a cube of size 1. As the renderer we use one of the built-in shaders called "Phong". Phong is a shader that can be either flat colored or use a texture and it reacts to light. In this simple case we will use just a flat red color, as defined by assigning an instance of J3D.Color to the color property of the renderer.

Cameras

Next we need to create a camera - this is our point of view in the 3d world. Same as with everything else in J3D, the camera is also a transform.

We start by creating a new instance of J3D.Transform. By default all transforms have the position of 0,0,0. In this case it means that our camera is located right in the center of the cube. That is why we move it 4 units along the z-axis, to see the cube from the outside. Now we need to attach an actual camera object - of type J3D.Camera. With no parameters passed, the constructor it will create a default perspective camera with 45 degree field of view - useful for most simple cases.

We also need to instruct the engine that this is our point of view when rendering. We do that by assigning the camera transform to the camera property of the engine object.

Finally, using scene.add we add ALL the transforms to the scene, including the light and the camera. Our setup is now ready, we can start rendering.

Rendering & animation

Thanks to the call to requestAnimationFrame the draw function will be called repeatedly. Each time it is invoked we slightly rotate the cube along it's x and y axes and call engine.render to update the rendered view.

Note how the rotation values are multiplied by J3D.Time.deltaTime. The deltaTime gives us the time elapsed since draw was called last time. This way our animation is frame-rate independent.

Back to wiki Home page.