About me

full-stack software engineer

member of kottans.org

Two-dimensional space

Cartesian

Polar

Coordinate systems

Cartesian

Cylindrical

Coordinate systems

Spherical

Three-dimensional space

Projections

Perspective

Orthographic

*Human's FOV is 190 degrees

Operations with matrices

Translation

Scalen

Rotationn

2D, 2.5D vs 3D

Pseudo-3D games:

1994 — Doom 2
1997 — Fallout
2002 — Heroes of Might and Magic IV
2003 — The Sims

Back to history

1972

1975

1994

1984

1994

Tools & Technologies

https://unity3d.com
https://www.microsoft.com/silverlight
https://support.microsoft.com/kb/179113
http://www.adobe.com/ru/products/flashplayer.html

 

OpenGL, Unity, Silverlight (deprecated), VRML, X3D, Flash (deprecated), DirectX, O3D (deprecated) etc.

OpenGL

General:

- OpenGL is specification created by Kurt Akeley and Mark Segal (current version is OpenGL 4.6);

- Reviewed by ARB (Architecture Review Board) from 1992;

- Windows, Unix, MacOS, PlayStation are released specification.

 

Benefits:

- Common API (cross-platform), open standard, well specified and documented;

- Hide differences of hardware by programming simulation;

- 25 years of compatibility (!!!).

OpenGL language bindings

C#:

Open Toolkit, Tao Framework, OpenGL4Net etc.

 

Java:

Java OpenGL (JOGL), Lightweight Java Game Library etc.

 

Ada, Common LISP, Delphi, Haskell, Lua, OCaml, Perl, Python, Ruby and a lot of others our lovely languages...

 

*Alternative docs https://open.gl

OpenGL example

void initGL() {
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
   glClearDepth(1.0f);                   // Set background depth to farthest
   glEnable(GL_DEPTH_TEST);   // Enable depth testing for z-culling
   glDepthFunc(GL_LEQUAL);    // Set the type of depth-test
   glShadeModel(GL_SMOOTH);   // Enable smooth shading
   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Nice perspective corrections
}
void display() {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
   glMatrixMode(GL_MODELVIEW);     // To operate on model-view matrix
 
   // Render a color-cube consisting of 6 quads with different colors
   glLoadIdentity();                 // Reset the model-view matrix
   glTranslatef(1.5f, 0.0f, -7.0f);  // Move right and into the screen
 
   glBegin(GL_QUADS);                // Begin drawing the color cube with 6 quads
      // Top face (y = 1.0f)
      // Define vertices in counter-clockwise (CCW) order with normal pointing out
      glColor3f(0.0f, 1.0f, 0.0f);     // Green
      glVertex3f( 1.0f, 1.0f, -1.0f);

   ...
   glEnd(); 
}

OpenGL shaders (GLSL)

#version 120
void main(void)
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Example of fragment shader (red fragment):

- Use GPU;

- Vertex, geometry, fragment shaders;

- C syntax.

 

WebGL

Canvas (HTML5) + OpenGL ES = WebGL.

WebGL evolved out of the Canvas 3D experiments started by Vladimir Vukićević at Mozilla. Vukićević first demonstrated a Canvas 3D prototype in 2006. By the end of 2007, both Mozilla and Opera had made their own separate implementations.

 

In 2011 it was criticised by Microsoft. Development of the WebGL 2 specification started in 2013. This specification is based on OpenGL ES 3.0.

 

WebGL libraries:

Three.js, Babylon.js, PhyloGL, GLGE, J3D.

Not always you need WebGL

WebGL support

Test WebGL:

http://get.webgl.org

 

Add support for WebGL to IE: 

https://github.com/iewebgl/iewebgl

WebGL experiments

WebGL example

var gl; // A global variable for the WebGL context

function start() {
  var canvas = document.getElementById("glcanvas");

  // Initialize the GL context
  gl = initWebGL(canvas);
  
  // Only continue if WebGL is available and working
  if (gl) {
    // Set clear color to black, fully opaque
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    
    // Enable depth testing
    gl.enable(gl.DEPTH_TEST);

    // Near things obscure far things
    gl.depthFunc(gl.LEQUAL);
   
    // Clear the color as well as the depth buffer.
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  }
}

Three.js

Three.js is a cross-browser JavaScript library/API used to create and display animated 3D computer graphics in a web browser. Three.js uses WebGL.

 

Three.js was first released by Ricardo Cabello to GitHub in April 2010. There are over 800 contributors in total (!!!).

Three.js examples

Generic terms in Three.js

Scene

Camera

Light

Mesh

Geometry

Material

Texture

Vertex

Face

Setting up

- 'npm install three' or 'yarn add three'

- add <script src="js/three.min.js"></script>

Scene, renderer, camera

var scene = new THREE.Scene();
var renderer = window.WebGLRenderingContext ? 
               new THREE.WebGLRenderer({alpha: true}) : 
               new THREE.CanvasRenderer();
var camera = new THREE.PerspectiveCamera(35, 
             window.innerWidth / window.innerHeight, 1, 1000);

function initScene() {
   renderer.setSize(window.innerWidth, window.innerHeight);
   document.getElementById("container").appendChild(renderer.domElement);

   scene.add(camera);
   ...
   render();
}

function render() {
   renderer.render(scene, camera);
   requestAnimationFrame(render);
}

Renderers: WebGLRenderer is a standard, CanvasRenderer is become obsolete (not recommend)

Cameras: OrthographicCamera, PerspectiveCamera, StereoCamera, CubeCamera

Meshes & Geometry

var material = new THREE.MeshBasicMaterial({
               wireframe: true,
               color: 0xD45DCA 
});

var box = new THREE.Mesh(new THREE.BoxGeometry(30, 30, 30), material);
scene.add(box);

Geometry = vertices + faces

Types: inbuilt (defined in Three.js), custom (you could create your own geometry), exported (from some format)

 

Geometry (inbuilt): BoxGeometry, CircleGeometry, ConeGeometry, CylinderGeometry, PlaneGeometry, RingGeometry, TorusGeometry​, TorusKnotGeometry etc.

 

Manipulating with meshes (union, subtract etc.): csg.js

Meshes & Geometry

Base class for meshes is THREE.Object3D, so everything could be translated/rotated and scaled.

 

Most important properties: id, uuid, name, position/rotation/scale, userData, parent/children

 

Most important methods: getObjectByName, getObjectById

 

Set position/rotation/scale (under the hood it's multiply to matrix):

Animations with matrices

box.position.x = 10;
box.position.y = 5;
box.position.z = 100;
box.position.set(10, 5, 100);

or

Loaders

var loader = new THREE.JSONLoader();

loader.load("monkey.json", function (geometry) {
    var material = new THREE.MeshBasicMaterial({
        color: 0xC91A58,
        wireframe: true
    });

    var monkey = new THREE.Mesh(geometry, material);

    scene.add(monkey);
    render();
});

Loaders: ​JSONLoader, TextureLoader, ObjectLoader, STLLoader (3D printing), CTMLoader (OpenCTM) etc.

 

Note! Also you can export your mesh from the scene (using THREE.SceneExporter).

Loaders

Materials

var material = new THREE.MeshPhongMaterial({
                color: 0xC91A58,
                ambient: 0xC93A58,
                specular: 0xC92A58,
                emissive: 0xC90A58,
                shininess: 60,
                shading: THREE.FlatShading,
                side: THREE.DoubleSide
            });

Materials: MeshLambertMaterial, MeshBasicMaterial, MeshPhongMaterial etc.

 

Common usage:

MeshLambertMaterial -> non-shiny surface

MeshPhongMaterial -> shiny metallic-like surface

Note! Each material is reacted to specific light.

Materials

MeshLambertMaterial

MeshPhongMaterial

MeshBasicMaterial

Lights

var light = new THREE.AmbientLight(0xffffff);
...
scene.add(light);

Lights: AmbientLight, DirectionalLight, PointLight, SpotLight etc.

 

 

Common usage:

AmbientLight -> affects all objects equality

PointLight -> light that shines in all directions (affects only MeshLambert & MeshPhong materials)

DirectionalLight -> sunlight, all lights come from some direction

SpotLight -> can cast shadow in one direction (like projector, affects only MeshLambert & MeshPhong materials)

Textures

var geometry = new THREE.SphereGeometry(30, 30, 30);
var material = new THREE.MeshBasicMaterial({map: 
               THREE.ImageUtils.LoadTexture('earth.jpg'), overdraw: 0.5});
var earth = new THREE.Mesh(geometry, material);

First way:

Second way (better):

var loader = new THREE.TextureLoader();

loader.load('earth.jpg', function (texture) {
    var geometry = new THREE.SphereGeometry(30, 30, 30);
    var material = new THREE.MeshBasicMaterial({map: texture, overdraw: 0.5});
    var earth = new THREE.Mesh(geometry, material);

    scene.add(earth);
    render();
});

You could define different modes and filters for your textures.

Textures

Where we use Three.js

Demo

Demo

Pros

- Cross-browser JS library

- No need to install proprietary plugins

- Open-source, hosted on GitHub

- Easy API

- Good support (reacting on issues)

- Performance

Cons

- Backward compatibility

- More advanced things are not clear from examples/docs

- Graphical editor is not ready

Wrap-up

- Update Three.js often

- No backward compatibility sometimes is painful

- Read migration guide while upgrade Three.js, follow recommendations, really

- Everything is okay with all browsers, some issues with Safari and Safari on iPad

- Non-trivial things are hard to google, 'learning by doing' approach

- Sometimes errors are not self-described

- Use additional plugins with Three.js (e.g. TrackballControls, OrbitControls, VRControls, Stats)

- Use helpers while developing (AxisHelper, CameraHelper etc.)

Lessons learned

- Support of Leap Motion, WebVR, Google Cardboard

- We tried integrate Leap Motion in our software (POC), it was really cool experience

Additionally

No books, threejs.org is the best resource for learning (IMO)

Books

Links

Thanks! Lunch time ;)

Three.js, Back to the Future

By Julia Savinkova

Three.js, Back to the Future

Three.js talk for kharkiv.js

  • 3,947