Cambria
Cambria

Reputation: 153

How to Interpret the Drawing Lines tutorial from three.js documentation?

I was reading the "Drawing lines" tutorial part on the three.js documentation as shown in the Picture below...

Drawing Lines tutorial

This is the code used to demonstrate drawing lines. The code itself is fine.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
        <script src="///C:/Users/pc/Desktop/threejs_tutorial/build_threejs.html"></script>
        <script>
        
        const scene = new THREE.Scene();
        
        const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );
        camera.position.set( 0, 0, 100 );
        camera.lookAt( 0, 0, 0 );

        const renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );

        //create a blue LineBasicMaterial
        const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );

        const points = [];
        points.push( new THREE.Vector3( - 10, 0, 0 ) );
        points.push( new THREE.Vector3( 0, 10, 0 ) );
        points.push( new THREE.Vector3( 10, 0, 0 ) );

        const geometry = new THREE.BufferGeometry().setFromPoints( points );

        const line = new THREE.Line( geometry, material );


        scene.add( line );
        renderer.render( scene, camera );


        </script>
    </body>
</html>

Let's go over the commands used in the creation of lines as suggested by the three.js documentation.

One by one

First line: the command

const scene = new THREE.Scene()

It says "create scene" but what it really does is to create a 3D space like as shown in the Picture 1.

CreateScene

Second line: the command

const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );

It says create a Camera, given is the field of view, aspect ratio, distance from camera to near viewing plane and distance from camera to far viewing plane as shown in Picture 2

PerspectiveCamera

Third line: the command

camera.position.set( 0, 0, 100 );

It says position the camera on the z-axis as shown in Picture 4. I assume that the orientation of camera is always parallel to x-axis.

CameraPosition

Fourth line: the command

camera.lookAt( 0, 0, 0 );

It says orient the camera in the direction of the point (0, 0, 0) as shown in Picture 5.

CameraLookAt

Fifth line: the command

const renderer = new THREE.WebGLRenderer();

It says the WebGL Renderer shall be ready when it will be summoned by calling its name as shown in Picture 6.

WebGL Renderer is now on alert

Sixth line: the command

renderer.setSize( window.innerWidth, window.innerHeight );

It says the window where the user will see will be adjusted by renderer. This window is your computer screen. Whatever the size of your computer screen, the renderer will adjust accordingly as shown in Picture 7.

RenderSetSize

Seventh line: the command

document.body.appendChild( renderer.domElement );

It says the renderer now exists in 3D space shown in Picture 8.

RendererNowExists

Eighth line: the command

const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );

It says we have to set the properties of the future line first before actually drawing it. In this case, this future line will have a color of blue as shown in Picture 9.

LineBasicMaterial

Ninth line: the command

const points = [];

I don't know the purpose of the array in this context. I guess whatever inside the array will become "real", something that can be put inside the viewing frustrum of the camera where it will be rendered in the near future as shown in Picture 10.

ConstPoints

Tenth line: the command

points.push( new THREE.Vector3( - 10, 0, 0 ) );

points.push( new THREE.Vector3( 0, 10, 0 ) );

points.push( new THREE.Vector3( 10, 0, 0 ) );

It says position the points specified by the Vector3 command and these points will be pushed along the three points positioned in the 3D space. The points doesn't appear yet because the renderer isn't yet summoned as shown in Picture 11.

Vector3

Eleventh line: the command

const geometry = new THREE.BufferGeometry().setFromPoints( points );

It says the points positioned by the Vector 3 will be converted into renderable form by the Buffer Geometry because a Buffer Geometry is a representation of mesh, line, or point geometry as shown in Picture 12.

BufferGeometry

Twelfth line: the command

const line = new THREE.Line( geometry, material );

It says the line will be created based from the geometry and material set beforehand as shown in Picture 13.

Line

Thirteenth line: the command

scene.add( line );

It says the line has been added to the 3D space inside the viewing frustrum of the camera as shown in Picture 14.

SceneAdd

Fourteenth line: the command

renderer.render( scene, camera );

It says the renderer has been ordered to render the scene and the camera. But I wondered why the command isn't

renderer.render( scene, camera, line );

....

RenderAnything

The final output looked like this:

FinalProduct

My question is:

Is anything what I've said is correct?

Thank you! I'm open for learning and dispelling myths surrounding the commands used in this example.

Upvotes: 1

Views: 567

Answers (2)

astro_bear
astro_bear

Reputation: 113

Bravo! I wish I had this when I was first learning!

To understand the 9th and 10th lines, I think it's best to understand a bit of history...

At one time, you were able to use a Geometry object:

let geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(-10, 0, 0))
geometry.vertices.push(new THREE.Vector3(0, 10, 0))
geometry.vertices.push(new THREE.Vector3(10, 0, 0))

So you're adding these points to the vertices attribute of the geometry. Which looks like this:

[{x:-10, y:0, z:0}, {x:0, y:10, z:0}, {x:10, y:0, z:0}]

Eventurally they did away with Geometry. So now you're supposed to use a BufferGeometry. But with the BufferGeometry, there is no more vertices attribute.

So what do we do...?

Well, now we create a points array, and use the setFromPoints function to basically apply these coordinates to your geometry object:

const points = [];
points.push(new THREE.Vector3(-10, 0, 0));
points.push(new THREE.Vector3(0, 10, 0));
points.push(new THREE.Vector3(10, 0, 0));
let geometry = new THREE.BufferGeometry().setFromPoints( points );

What this does is it sets an attribute of type Float32Array...

geometry.attributes.position.array

Which looks like this:

[ -10, 0, 0, 0, 10, 0, 10, 0, 0 ]

And if you do:

geometry.attributes.position.count

You get: 3. Three points.

Hope it helps :)

Upvotes: 0

M -
M -

Reputation: 28462

You've made a few wrong assumptions:

  1. camera.position.set( 0, 0, 100 ); puts the camera at 100 units along the z-axis, parallel to the z-axis because it hasn't been rotated.
  2. document.body.appendChild( renderer.domElement ); adds the <canvas> element to your HTML document. It's one of the few commands that have nothing to do with 3D space.
  3. renderer.render(scene, cam) renders everything that's been added to the scene. You already added the lines with scene.add(line), so there's no reason to specifically target line again.

It says the renderer now exists in 3D space shown in Picture 8.

Some of your screenshots use different axes systems. To get acquainted with the Three.js/WebGL coordinate system, I recommend you visit the Three.js editor and add a camera with Add > PerspectiveCamera (near the bottom). You can then modify its position attributes to see what the axes do. Also keep an eye on the axes widget on the corner:

enter image description here

  • x-axis: +right / -left
  • y-axis: +up / -down
  • z-axis: +toward user / - away

Upvotes: 1

Related Questions