3D on the Web

by Denis Grigor (denis.grigor@autodesk.com)
for ConFoo Montreal 2017

What is 3D?

There is no spoon 3D on a screen

All you see is just an illusion a projection.

Result of series of transformations
  • from an "imagined" 3D content
  • to a 2D array of pixels

An Ancient Renderer [1525]

from Computer Graphics: Principles and Practice, Third Edition

CPU vs GPU

Why speed is so important?

Interactive vs Realtime graphics

GPU for the Web.

  • Meant for browsers
  • OpenGL ES2.0 port built into the <canvas> DOM element


WebGL report
WebGL2 support

WebGL
programmable

graphics pipeline

WebGL
programmable

graphics pipeline

WebGL 101

Setting up the scene with a canvas and a background

var canvas=document.getElementById('webgl_101');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var gl = canvas.getContext('webgl'); // vs 2D

// background color
gl.clearColor(0.0, 0.4, 0.8, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
WebGL output
What it takes to draw 3 points on the screen?
//2D points with direct screen coordinates
var vertices = new Float32Array([
0, 0.9,
0.9, -0.6,
-0.9, -0.6
]);
        

Vertex Shader

// vertex shader
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, [
  'attribute vec2 position;', // pass in attribute
  'void main() {', // every shader needs a main func
    'gl_Position = vec4(position, 0.1, 1.0);', // set a position
  '}'
].join('\n'));
gl.compileShader(vertexShader);

Fragment Shader

// fragment shader
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, [
  'precision highp float;',
  'uniform vec4 color;',
  'void main() {',
    'gl_FragColor = color;',
  '}'
].join('\n'));
gl.compileShader(fragmentShader);

Bind the shaders together, draw vertices etc

var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

var vertices = new Float32Array([
0, 0.9,
0.9, -0.6,
-0.9, -0.6
]);

var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);

gl.useProgram(program);
program.color = gl.getUniformLocation(program, 'color');
gl.uniform4fv(program.color, [0, 0, 0, 1.0]);

program.position = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(program.position);
gl.vertexAttribPointer(program.position, 2, gl.FLOAT, false, 0, 0);

gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);

Just 99.9 lines of code!


http://webglfundamentals.org/
Khronos Group
Super cool example

WebGL based tools

three.js

Abstracts away triangles and related complexities of GL programming

Into actual objects and things in space

var cylinder = new THREE.Mesh(
  new THREE.CylinderGeometry( 100, 100, 200, 32 ),
  new THREE.MeshBasicMaterial( {color: 0x2194ce} )
);

Getting Started

  • scene, camera, renderer, controls
  • put stuff in the scene
  • animate
setup();
fillScene();
animate();
function setup(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45,
                        window.innerWidth / window.innerHeight,
                        0.1, 1000 );

renderer = new THREE.WebGLRenderer({alpha:true});
var intro_place = document.getElementById("three_js_101");
intro_place.appendChild( renderer.domElement );
renderer.setSize(400,200);
}
function fillScene() {
var material = new THREE.MeshBasicMaterial( { color: 0x3166bc,
                                                wireframe: true } );
var geometry = new THREE.IcosahedronGeometry(20, 4);

sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

camera.position.z = 60;
camera.lookAt(new THREE.Vector3(0,0,0));
}

Animate

  • requestAnimationFrame();
  • Computer rendered animation needs to be 60fps to be seamless for human eye (contrary to 24fps for film)
  • Call animate() every time browser refreshes
function animate() {
sphere.rotation.y += 0.01;
requestAnimationFrame( animate );
renderer.render( scene, camera );
}

Easily add controls

var controls = THREE.OrbitControls(camera, renderer.domElement);
}

What about material?

var material = new THREE.MeshBasicMaterial( { color: 0x3166bc,
                                                wireframe: true } );
}
vertex_shader = `
varying vec2 vUv;
void main()
{
  vUv = uv;
  gl_Position = projectionMatrix*modelViewMatrix*vec4(position, 1.0);
}`
fragment_shader = `
varying vec2 vUv;
void main()
{
  gl_FragColor = vec4( vec3( vUv, 0. ), 1. );
}`
var material = new THREE.ShaderMaterial( {
                    vertexShader: vertex_shader,
                    fragmentShader: fragment_shader, wireframe: true});
What can be achieved

All you need is love three.js

  • support for primitive geometries
  • available loaders for different formats
  • support for lights and shadows
  • support for textures
  • shader access !!!

What it takes to create a 3D viewer?

Pseudocode for creating cool things


Interactive 3D Graphics Course

What other things to take care of?

at least ...

Navigation

Lights and materials

Geometry representation and formats

Metadata

Let us see some cool things!

Sketchfab

"Customizable shopping"

CL3VER

PlayCanvas

Cool BMW i8 example

and some even more useful things

What Amazon could look like with 3D How a realtor website could look with 3D How an assembly instruction could look with 3D

Assembly Instructions

Other "collateral" applications ...

Augumented shopping

Holo-review

Thank you


Check
https://developer.autodesk.com/
and our Blog at https://forge.autodesk.com/blog