Assignment 8
Assignment 8
A
79%
Assignment 9
Assignment 10
Load a .PLY/.OBJ/.STL file and convert it to a valid .GLTF file
Load the armadillo and add multiple lights and materials (incl. toon)
Due 11/27
Due 12/02
Includes Final Project Choice
40% of your grade
chance to pair your learned skills
with your creative ideas
can be done as a team or solo
Final Project
Fast Forward (30-60 seconds)
Final Project Presentation
Report on Overleaf
Code on Github
Wed 12/04
Mon 12/09 Wed 12/11
Fri 12/13
Fri 12/20
Fri 12/20
11/22
11/25
11/27
12/02
12/06
Recap II
glTF II
Fieldtrip
Skybox
Final Recap
Fri
Mon
Fri
Mon
Wed
Lecture 1
GPU Access!
Lecture 2
<canvas></canvas>
var c = document.createElement("canvas");
document.body.appendChild(c);
*.html
*.js
Lecture 3
Browser
Editor
Lecture 4
Web Developer Tools
Spector.js is a Web Developer Tool for WebGL
Lecture 5
Frustum
zNear
zFar
Viewport
Camera
(Eye)
Perspective Projection
Camera
Eye
Position (0,0,100)
Focus (0,0,0)
Scene
Center
Up (0,1,0)
Translate (Move in x,y)
Zoom (Move in z)
Rotate
X
Y
Z
c = new X.cube();
c2 = new X.cube();
c.center = [0, 0, 0];
c.lengthX
c.lengthY
c.lengthZ
gap
= 20
c2.center = [25, 0, 0];
= 5
c.color = [0, 0, 1];
c2.color = [1, 1, 1];
25, 0, 0
0, 0, 0
Z-Fighting
Lecture 6
easy
hard
XTK
Three.js
WebGL
limited
freedom
Complexity
Functionality
XTK
X.renderer3D
Renderer
Scene
Interaction
Loop
Three.js
THREE.WebGLRenderer
THREE.Scene
THREE.TrackballControls
Loop
Canvas
Canvas
Camera
THREE.PerspectiveCamera
Lighting
THREE.AmbientLight
THREE.DirectionalLight
ambientlight = new THREE.AmbientLight()
geometry = new THREE.BoxBufferGeometry
                         ( 20, 20, 20 )
lengthX, lengthY, lengthZ
Geometry defines the shape!
material = new THREE.MeshStandardMaterial
                       ( { color: 0xffffff } )
Material defines the appearance!
 new THREE.Mesh( geometry, material )
 cube =
Lecture 7
Wireframe
12 Triangles
V1
V2
V3
V4
V6
V5
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
Vertex
/ Vertices
Face
Face
Frame Buffer
Screen Space
width x height Pixels
Rasterization
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(-10, 10, 0),
new THREE.Vector3(-10, -10, 0),
new THREE.Vector3(10, -10, 0)
);
geometry.faces.push( new THREE.Face3(0, 1, 2));
GPU
Vertex Shader
Fragment Shader
Viewport
From 3D..
..to 2D
Lecture 8
0, 0
width, height
renderer.domElement.onclick = function(e) {
pixel_coords = new THREE.Vector2(e.clientX, e.clientY);
};
400, 200
400 Â Â , Â Â 200
Screen Space Coordinates
-1, -1
renderer.domElement.onclick = function(e) {
pixel_coords = new THREE.Vector2( e.clientX, e.clientY );
vp_coords = new THREE.Vector2(
( pixel_coords.x / window.innerWidth ) * 2 - 1, // X
- ( pixel_coords.y / window.innerHeight ) * 2 + 1 ); // Y
};
-0.2, 0.3
-0.2
Viewport Coordinates
1, 1
0, 0
0.3
THREE.Raycaster
zNear
zFar
Ray
Position (x,y,z)
needs 2 points to define Ray
raycaster = new THREE.Raycaster();
raycaster.setFromCamera(vp_coords_near, camera);
Fragment Shader
Vertex Shader
gl_Position
gl_FragColor
for every vertex
for every pixel
Lecture 9
XTK
X.renderer3D
X.cube
Three.js
THREE.WebGLRenderer
THREE.Scene
THREE.TrackballControls
THREE.PerspectiveCamera
THREE.AmbientLight
THREE.DirectionalLight
WebGL
gl.viewport
gl.createShader
gl.shaderSource
gl.compileShader
gl.getShaderInfoLog
gl.createProgram
gl.attachShader
gl.linkProgram
gl.useProgram
gl.createBuffer
gl.bindBuffer
gl.BufferData
gl.getAttribLocation
gl.vertexAttribPointer
gl.enableVertexAttribArray
gl.clearColor
gl.clear
gl.drawArrays
Â
THREE.Geometry
THREE.Material
THREE.Mesh
V0
V1
V2
V3
V4
V5
Viewport Coordinates
-1, -1
1, 1
-0.5, -0.5
-0.5, 0.5
0.5, 0.5
0.5, -0.5
vertices = new Float32Array( [
-0.5, 0.5, 0.0, // V0
-0.5, -0.5, 0.0, // V1
0.5, 0.5, 0.0, // V2
0.5, 0.5, 0.0, // V3
-0.5, -0.5, 0.0, // V4
0.5, -0.5, 0.0 // V5
] );
1. Initialize WebGL
2. Shaders
3. Create Geometry
4. Connect Shader with Geometry
5. Draw!
setup Canvas
setup GL Context
compile vertex shader
compile fragment shader
attach and link shaders
create vertices
create and bind buffer
put data in
unbind buffer
bind buffer
find vertex attribute in shader source
configure vertex attribute
enable vertex attribute array
clear viewport
clear color buffer
draw vertex arrays
Lecture 10
V0
V1
V2
V3
V4
V5
vertices = new Float32Array( [
-0.5, 0.5, 0.0, // V0
-0.5, -0.5, 0.0, // V1
0.5, 0.5, 0.0, // V2
0.5, 0.5, 0.0, // V3
-0.5, -0.5, 0.0, // V4
0.5, -0.5, 0.0 // V5
] );
gl.TRIANGLES
V0
V1
V2
V3
V4
V5
vertices = new Float32Array( [
-0.5, 0.5, 0.0, // V0
-0.5, -0.5, 0.0, // V1
0.5, 0.5, 0.0, // V2
0.5, 0.5, 0.0, // V3
-0.5, -0.5, 0.0, // V4
0.5, -0.5, 0.0 // V5
] );
gl.POINTS
V0
V1
V2
V3
V4
V5
vertices = new Float32Array( [
-0.5, 0.5, 0.0, // V0
-0.5, -0.5, 0.0, // V1
0.5, 0.5, 0.0, // V2
0.5, 0.5, 0.0, // V3
-0.5, -0.5, 0.0, // V4
0.5, -0.5, 0.0 // V5
] );
gl.LINES
Rendering Primitives
V0
V1
V2
V3
V4
V5
vertices = new Float32Array( [
-0.5, 0.5, 0.0, // V0 // 0
-0.5, -0.5, 0.0, // V1, V4 // 1
0.5, 0.5, 0.0, // V2, V3 // 2
0.5, -0.5, 0.0 // V5 // 3
] );
var indices = new Uint8Array( [ 0, 1, 2, // Triangle 1
2, 1, 3 ] ); // Triangle 2
0
1
2
3
Indexed Geometry
Before: 6 x 32 bits, Now: 4 x 32 bits
6 x 8 bits == 48 bits
We still save 16 bits.
We save 2 x 32 bits.
Lecture 11
Uniforms
createRectangle()
Rendering Loop
And, they move!
Fragment Shader
Vertex Shader
attribute vec3 position;
different data for each vertex
uniform vec3 offset;
different data for each gl.drawArray or gl.drawElements call
uniform vec4 color;
Lecture 12
Lecture 13
Transformations
Translate
Rotate
Scale
Matrix
1 Â 0 Â 0 Â t_x
0 Â 1 Â 0 Â t_y
0 Â 0 Â 1 Â t_z
0 Â 0 Â 0 Â 1 Â Â
x, y, z
x, y, z
new
Translation
Matrix
s_x  0  0  t_x
0  s_y  0  t_y
0  0  s_z  t_z
0 Â 0 Â Â Â 0 Â Â 1 Â
x, y, z
x, y, z
new
Scaling
Matrix
r  r  r  t_x
r  r  r  t_y
r  r  r  t_z
 0  0  0   1 Â
x, y, z
x, y, z
new
Rotation
var m = new Float32Array( [
r, r, r, 0,
r, r, r, 0,
r, r, r, 0,
t_x, t_y, t_z, 1
]);
column-major ordering!
Lecture 14
0.5 Â 0 Â 0 Â 0
0 Â 0.5 Â 0 Â 0
0 Â 0 Â 0.5 Â 0
0 Â 0 Â 0 Â 1
2, 2, 2
?
cos(T) Â -sin(T) Â 0 Â 0
sin(T) Â cos(T) Â 0 Â Â 0
  0      0     1   0
  0      0     0   1
2, 2, 2
?
with T = Pi/2
 = 90°
X
Y
Z
Scene
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
1 Â 0 Â 0 Â 0
0 Â 1 Â 0 Â 0
0 Â 0 Â 1 Â 0
0 Â 0 Â 0 Â 1
Scene Graph is a Tree-like Hierarchy!
*
*
*
Lecture 15
cos(T) Â -sin(T) Â 0 Â 0
sin(T) Â cos(T) Â 0 Â Â 0
  0      0     1   0
  0      0     0   1
2, 2, 2
with T = Pi/2
0
0
1
2 Pi
Pi
Pi/2
1.5 Pi
90°
1
1
-2
2
2
-1
Frame of Reference
X
Y
Z
World Frame
Frame of Reference
X
Y
Z
Object Frame
Frame of Reference
X
Y
Z
Eye Frame
Camera
(Eye)
cos(T) Â Â Â Â 0 Â Â Â Â sin(T) Â Â 0 Â
  0      1        0   0
-sin(T) Â Â 0 Â Â Â cos(T) Â Â 0
  0      0        0   1
rotation around Y
cos(T/2)
sin(T/2) * 0
sin(T/2) * 1
sin(T/2) * 0
Matrix
Quaternion
Lecture 16
cos(T) Â -sin(T) Â 0 Â 0
sin(T) Â cos(T) Â 0 Â Â 0
  0      0     1   0
  0      0     0   1
2, 2, 2
with T = Pi/2
0
0
1
2 Pi
Pi
Pi/2
1.5 Pi
-1
-2, 2, 2
cos(T/2)
sin(T/2) * 0
sin(T/2) * 0
sin(T/2) * 1
Quaternion
w
x
y
z
~0.7
~0.7
0
0
~0.7
0
0
~0.7
0
2
2
2
w
x
y
z
*
Quaternion
?
~0.7
0
0
~0.7
0
2
2
2
*
~0.7
- 0
- 0
- ~0.7
Inverse
page 64, Gortler: 3D Computer Graphics
Rigid Body Transformation
Quaternion
Translation Vector
w
x
y
z
x
y
z
0
Arcball
Trackball
Controls
Natural Feeling
Spins twice as fast
Completely path independent
Lecture 17
var q = new THREE.Quaternion( sin( T / 2 ) * x ,
sin( T / 2 ) * y ,
sin( T / 2 ) * z ,
cos( T / 2 ) );
0
0
1
2 Pi
Pi
Pi/2
1.5 Pi
-1
90°
180°
270°
360°
180°
around Y-axis
T is the angle
x y z is the axis
 T = Math.PI
0, 1, 0
var q = new THREE.Quaternion( Math.sin( Math.PI / 2 ) * 0 ,
Math.sin( Math.PI / 2 ) * 1 ,
Math.sin( Math.PI / 2 ) * 0 ,
Math.cos( Math.PI / 2 ) );
zNear
Ray
Position (x,y,z)
Invisible Plane
raycaster = THREE.Raycaster();
raycaster.setFromCamera(vp_coords_near, camera);
intersects = raycaster.intersectObject( invisiblePlane );
Raycasting
Framebuffer (hidden)
1
2
3
4
( 1, 0, 0, 1 )
( 0, 1, 0, 1 )
( 1, 1, 0, 1 )
( 0, 0, 1, 1 )
( 0, 0, 0, 1 )
gl.readPixels
(r, g, b, a)
map to object ID
( 0, 1, 0, 1 )
2
Object Picking
Object Picking
Raycasting
More complex
Quick'n'Dirty
Very precise (Face picking)
Object precision
Occlusion not a problem
Objects can be hidden
Lecture 18
Lecture 19
Assignment 5
r   g   b   a
alpha
0: fully transparent
   ....
255: fully opaque
0: minimum
   ....
255: maximum
red
green
blue
#000000
#ffffff
minimum
maximum
Hex
#00000000
#ffffffff
minimum
maximum
Hex8
alpha
alpha
HSL
H:
S:
L:
Hue
Saturation
Lightness
0/360°
180°
240°
65%
40%
0%
100%
0%
100%
hsl(240, 65%, 40%)
rgb(36, 36, 168)
#2424a8
Gamut
range of colors in an imaging system
Lecture 20
Lecture 21
Scene Graph
Quaternions
Skeletons
Object Oriented
Slerp
Animations
Textures
Anaglyph
6
Robot
Head
Neck
Torso
Lower Arm
Upper Arm
Hand
Upper Arm
Lower Arm
Hand
Upper Leg
Upper Leg
Lower Leg
Lower Leg
Foot
Foot
L
L
L
R
R
R
L
L
L
R
R
R
Head
Y
X
Object Frame
Neck
Torso
Upper Arm
Lower Arm
Hand
neck.position.y = -10;
torso.position.y = -30;
-10
-40
left_upper_arm.position.y = -5;
left_upper_arm.position.x = 5;
left_lower_arm.position.y = -15;
left_lower_arm.position.x = 5;
left_hand.position.y = -5;
left_hand.position.x = 5;
Position is relative to parent!
Head
Upper Arm
q
q (0, 0, 0, 1)
Identity
X
q2 (Math.sin(T/2),
0,
0,
Math.cos(T/2))
Rotate 180° in X
T = Math.PI
q
q2
Arm down
Arm up
Time
Frames
Keyframe 2
Keyframe 1
slerp Interpolation
Lecture 22
Skinning
Skeleton -> Mesh
Rigging
Mesh -> Skeleton
Kinematics
Forward Kinematics
Inverse Kinematics
Move down the scene graph
Move up in the scene graph
q
Upper Arm
Hand
q
Upper Arm
Hand
q
Upper Arm
Hand
Multiple Solutions!
Lecture 23
Time
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CS460 Computer Graphics at the University of Massachusetts Boston</title>
<script type="text/javascript" src="../../js/xtk_edge.js"></script>
<link rel="stylesheet" type="text/css" href="../../styles/fonts.css"/>
<style>
html, body {
background-color:#000;
margin: 0;
padding: 0;
height: 100%;
overflow: hidden !important;
font-family: din_condensed;
font-size: 18pt;
}
</style>
<script type='text/javascript'>
window.onload = function() {
// create a new test_renderer
r = new X.renderer3D();
r.init();
// UMASS BOSTON
//
// create a cube
umassboston = new X.cube();
// skin it..
umassboston.texture.file = 'umassboston.png';
// hide it for now!
umassboston.visible = false;
r.add(umassboston);
// BOSTON GFX
//
// create a cube
bostongfx = new X.cube();
// skin it..
bostongfx.texture.file = 'bostongfx.png';
// hide it for now!
bostongfx.visible = false;
r.add(bostongfx);
// setup the camera
r.camera.position = [00, 00, 60];
// .. and render it
r.render();
};
clicked = false;
window.onclick = function() {
if (clicked) return; // sometimes you click again by accident,
// and restart the animation.. let's not!
// we need user feedback, to allow the music to play..
// let's do it on click!
clicked = true;
animation();
}
function animation() {
// start the music
var music = document.getElementById('music');
music.autoplay = true;
music.load();
setTimeout(function() {
umassboston.visible = true;
}, 400);
setTimeout(function() {
umassboston.visible = false;
r.camera.position = [0, 0, -25];
bostongfx.visible = true;
}, 3200);
setTimeout(rotate_bostongfx, 6200);
};
function rotate_bostongfx() {
var rotateCounter = 0;
var spinner1 = setInterval(function(){
rotateCounter += 1;
// console.log(rotateCounter*2);
if (rotateCounter*2 >= 90) {
clearInterval(spinner1); // this is not time-based now...
bostongfx.visible = false;
// now the real CS460 logo..
create_cs460_logo();
return;
}
bostongfx.transform.rotateY(rotateCounter*2);
},100);
};
function create_cs460_logo() {
document.getElementById('caption').style.display = 'block';
// create a new X.object
cs460logo = new X.object();
// add the points, normals and colors
//
// this means 648000 / 3 == 216000 vertices
// on my work machine I could set 24000000 / 3 == 8 mio vertices
cs460logo.points = new X.triplets(648000);
cs460logo.normals = new X.triplets(648000);
cs460logo.colors = new X.triplets(648000);
// and set the type to POINTS
cs460logo.type = 'POINTS';
// create the points, normals and colors
for ( var x = 0; x < 60; x++) {
for ( var y = 0; y < 60; y++) {
for ( var z = 0; z < 60; z++) {
cs460logo.points.add(x, y, z);
cs460logo.normals.add(1, 1, 1);
cs460logo.colors.add(x/60, y/60, z/60);
}
}
}
// add the object
r.add(cs460logo);
// setup the camera
r.camera.position = [500, 500, 500];
setTimeout(zoom_into_cs460logo, 2000);
};
function zoom_into_cs460logo() {
var zoomer = setInterval(function() {
// we can stop once we are far away enough
if (r.camera.view[14] > 1000) {
clearInterval(zoomer);
// console.log('zooming done');
setTimeout(function() {
document.getElementById('caption').style.display = 'none';
start_content();
}, 2000);
return;
}
// zoom in
r.camera.zoomIn();
}, 10);
};
function start_content() {
// reduce music volume
var music = document.getElementById('music');
music.volume = .1;
// activate speech
var voice = document.getElementById('voice');
voice.autoplay = true;
voice.volume = 1;
voice.load();
frames = ['content1', 'content2', 'content3', 'content4', 'content5', null];
times = [0, // Today...
1000, //
4200, // And
6000, //
10000, // this is lecture 19
14000];
//
// this is (like the whole animation concept), a little hacky!!
//
for (var f in frames) {
setTimeout(function(f) {
if (f > 0) {
document.getElementById(frames[f-1]).style.display = 'none';
}
if (frames[f] != null) {
document.getElementById(frames[f]).style.display = 'block';
} else {
music.volume = .1;
setTimeout(function(f) {
fadeout = setInterval(function(f) {
if (music.volume <= 0.) {
clearInterval(fadeout);
return;
}
music.volume -= .05;
}, 500);
},3000);
}
}.bind(this,f), times[f]);
}
};
</script>
</head>
<body>
<div style="visibility:hidden">
<audio id='music'>
<source src="bensound-evolution.mp3">
</audio>
<audio id='voice'>
<source src="lecture23.mp3">
</audio>
</div>
<div id='caption' style='display:none;position: absolute;color:white;top:45%;left:50%;margin-left:50px;font-size:440%'>CS460</div>
<div id='content1' style='display:none;position: absolute;color:white;top:25%;left:30%;margin-left:50px;font-size:440%'>Today...</div>
<div id='content2' style='display:none;position: absolute;color:white;top:30%;left:20%;margin-left:50px;font-size:440%'>We will learn more about animations..</div>
<div id='content3' style='display:none;position: absolute;color:white;top:20%;left:10%;margin-left:50px;font-size:440%'>And...</div>
<div id='content4' style='display:none;position: absolute;color:white;top:35%;left:20%;margin-left:50px;font-size:440%'>We will talk to an emmy winning prime-time animator!</div>
<div id='content5' style='display:none;position: absolute;color:white;top:45%;left:40%;margin-left:50px;font-size:440%'>This is lecture 23.</div>
</body>
</html>
1. Setup
2. UMB
400 ms
3. GFX
3200 ms
3. rotate
6200 ms
4. CS460
180°
5. zoom
2000 ms
6. content
camera.z > 1000
7. end
XXX ms
Lecture 24
Lecture 25
Texture Mapping
X
Y
0
0
width
height
U
V
0
0
1
1
Fragment Shader
Fragment Shader
Vertex Shader
vec2( Â Â Â )
vec2( Â Â Â )
vec2( Â Â Â )
vec3 a_Position;
vec2 a_TexCoord;
vec2 v_TexCoord;
0, 0
1, 1
0, 1
u, v
varying
vec2 v_TexCoord;
varying
sampler2D u_Sampler;
Sampling
Nearest Neighbor
Linear
Interpolation
Lecture 26
Assignment 6
Normals
V1
V2
V3
V4
V6
V5
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
Vertex
/ Vertices
Face
Face
N1 (x, y, z)
N2 (x, y, z)
Face
Normals
V1
V2
V3
V4
V6
V5
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
(x, y, z)
Vertex
/ Vertices
Face
Face
N1 (x, y, z)
N2 (x, y, z)
Vertex
N3 (x, y, z)
N6 (x, y, z)
N5 (x, y, z)
N4 (x, y, z)
No Shading
Normals
used for Material
used for Lighting
No Normals
Face Normals
Vertex Normals
V1
V2
V3
Bump Map
Normals
Pixel
var mesh = new THREE.SkinnedMesh( geometry, material );
var skeleton = new THREE.Skeleton( bones );
mesh.add( bones[ 0 ] );
mesh.bind( skeleton );
5 Skinned Meshes
5 Cylinder Geometries
Lecture 27
GLTF
.gltf
.glb
STL
OBJ
PLY
Collada
.dae
.stl
.ply
.obj
And more:
Stereo Lithography (STL)
solid SOMENAME
facet normal 1 0 0
outer loop
vertex 0 0 1
vertex 1 0 0
vertex 0 1 0
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 0 0 1
vertex 1 1 0
vertex 1 1 1
endloop
endfacet
...
endsolid
Face 1
Face 2
Stanford Polygon File (PLY)
ply
format ascii 1.0
comment i love cs460
element vertex 4
property float x
property float y
property float z
element face 3
property list uchar int vertex_index
end_header
0 0 0
0 0 1
0 1 1
0 1 0
3 0 1 2
3 1 2 3
3 1 2 4
Vertices
Faces
Header
Wavefront Object (OBJ)
Vertices
Faces
v -0.5 -0.5 0.5
v 0.5 -0.5 0.5
v -0.5 0.5 0.5
v 0.5 0.5 0.5
v -0.5 0.5 -0.5
v 0.5 0.5 -0.5
v -0.5 -0.5 -0.5
v 0.5 -0.5 -0.5
f 1 2 4
f 1 4 3
f 3 4 6
f 3 6 5
f 5 6 8
f 5 8 7
f 7 8 2
f 7 2 1
f 2 8 6
f 2 6 4
f 7 1 3
f 7 3 8
f 7 3 5
Lecture 28
Light Simulations
N (x, y, z)
Material
Scattering
controls the physical appearance
magic mode uses (x, y, z) as color
Lecture 29
Assignment 7
Light Simulations
N (x, y, z)
Material
Scattering
controls the physical appearance
+ Light
Material
Light
+
Color
Direction
Color
Orientation
Two things control the color of an object
Physically Based Rendering
var color = 0xFFFFFF;
var intensity = 1;
var light = new THREE.PointLight(color, intensity);
light.position.set(0, 10, 0);
scene.add(light);
//...
gui.add(light, 'distance', 0, 40)
Lecture 30
Mike Halle, PhD
medical and scientific visualization
openanatomy.org
Image Volumes
2D
3D
Slice-based Volume Rendering
Volume Rendering with Ray Casting
Cinematic Volume Rendering
Lecture 31
Marching Cubes creates 3D Meshes
Bill Lorensen 1987
Label Maps
Marching Cubes in 3D
Create triangles to approximate the shape
Inside
Outside
glTF
Graphics Layer Transmission Format
glTF can be:
JSON - based (.gtlf)
JSON - based (.gtlf) + external binary data (.bin)
only binary (.glb)
{
// Functions are not allowed in JSON!
// 'dance': function() {
//...
// },
'head': 123,
'parameter1': 456,
'nested objects': {
'another object': {
'property1': true,
'list of stuff': [1, 2, 'hello']
}
}
}
JSON
For Data Description
{
"nodes": [
{
"mesh": 0
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0
}
{
// ...
"meshes": [
{
"primitives": [
"mode": 4,
"attributes": {
"POSITION": 0
},
"indices": 1
]
}
]
"nodes": [
{
"mesh": 0
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0
}
Accessors
{
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": HOWMANY,
"type": "VEC3",
"max": [MAX_X, MAX_Y, MAX_Z],
"min": [MIN_X, MIN_Y, MIN_Z]
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5123,
"count": HOWMANY,
"type": "SCALAR",
"max": [MAX],
"min": [MIN]
}
],
// ...
}
Vertices
Indices
Float
U_Short
U_Int
{
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": HOWMANY,
"type": "VEC3",
"max": [MAX_X, MAX_Y, MAX_Z],
"min": [MIN_X, MIN_Y, MIN_Z]
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5123,
"count": HOWMANY,
"type": "SCALAR",
"max": [MAX],
"min": [MIN]
}
],
// ...
}
Vertices
Indices
{
// ...
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": HOWMANYBYTES,
"target": 34962
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": HOWMANYBYTES,
"target": 34963
}
],
"buffers": [
{
},
{
}
]
// ...
}
ELEMENT_ARRAY_BUFFER
ARRAY_BUFFER
Lecture 32
Vulkan, OpenGL, and OpenGL ES renderers for the Source 2 engine used by games such as Dota 2, Artifact, and Dota Underlords
Quiz today!