CS460 Computer Graphics - University of Massachusetts Boston

Assignment 2

Remember to give credit!

My quick'n'dirty solution: https://cs460.org/shortcuts/01/

CS460 Computer Graphics - University of Massachusetts Boston

Assignment 3

``````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

Viewport

From 3D..

..to 2D

The Rendering Pipeline

Rasterization

Vertices

Face

From 3D to 2D

From 2D to 3D?

Unprojecting...

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

zNear

zFar

Ray

2D Click can be mapped to any

point on the 3D Ray

zNear

zFar

Ray

2D Click can be mapped to any

point on the 3D Ray

But we know the exact

position on zNear!

``````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

vp_coords_3d_near = new THREE.Vector3(vp_coords.x,
vp_coords.y,
0); // for zNear

};``````

Towards 3D Coordinates

This is not 3D yet!

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);``````

zNear

Ray

Position (x,y,z)

Invisible Plane

``intersects = raycaster.intersectObject(           );``

zNear

Ray

Position (x,y,z)

Invisible Plane

``intersects = raycaster.intersectObject(           );``
``````geometry = new THREE.PlaneBufferGeometry( 10000, 10000 );
material = new THREE.MeshBasicMaterial( {
visible: false
});

invisible_plane = new THREE.Mesh( geometry, material );

``intersects = raycaster.intersectObject( invisible_plane );``

( 0, 0, 0 )

``````<html>
<meta charset="UTF-8" />
<style>
html, body {
background-color:#000;
margin: 0;
height: 100%;
overflow: hidden !important;
}
</style>
<script src="https://threejs.org/build/three.min.js" type="text/javascript"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js" type="text/javascript"></script>
<script>

// Three.js code goes here

scene = new THREE.Scene();

fov = 75;
ratio = window.innerWidth / window.innerHeight;
zNear = 1;
zFar = 10000;
// console.log(ratio);
camera = new THREE.PerspectiveCamera(fov, ratio, zNear, zFar);
camera.position.set( 0, 0, 100);

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

renderer.domElement.onclick = function( e ){

console.log('Yay! We clicked!');

pixel_coords = new THREE.Vector2( e.clientX, e.clientY );

console.log('Pixel coords', pixel_coords);

vp_coords = new THREE.Vector2(
( pixel_coords.x / window.innerWidth ) * 2 - 1,  //X
-( pixel_coords.y / window.innerHeight ) * 2 + 1) // Y

console.log('Viewport coords', vp_coords);

vp_coords_near = new THREE.Vector3( vp_coords.x, vp_coords.y, 0);

};

ambientLight = new THREE.AmbientLight( 0x404040 );

light = new THREE.DirectionalLight( 0xffffff, 5.0);
light.position.set( 10, 100, 10 );

// now we add the cube
geometry = new THREE.BoxBufferGeometry( 20, 20, 20);
material = new THREE.MeshStandardMaterial({ color: 0xffffff });
cube = new THREE.Mesh( geometry, material);

controls = new THREE.TrackballControls( camera, renderer.domElement );

animate();

};

function animate() {

requestAnimationFrame( animate );

// console.log('check');

controls.update();

// and here...
renderer.render( scene, camera);

};
</script>
<body></body>
</html>``````
``````<html>
<meta charset="UTF-8" />
<style>
html, body {
background-color:#000;
margin: 0;
height: 100%;
overflow: hidden !important;
}
</style>
<script src="https://threejs.org/build/three.min.js" type="text/javascript"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js" type="text/javascript"></script>
<script>

scene = new THREE.Scene();

fov = 75;
ratio = window.innerWidth / window.innerHeight;
zNear = 1;
zFar = 10000;
// console.log(ratio);
camera = new THREE.PerspectiveCamera(fov, ratio, zNear, zFar);
camera.position.set( 0, 0, 100);

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

ambientLight = new THREE.AmbientLight( 0x404040 );

light = new THREE.DirectionalLight( 0xffffff, 5.0 );
light.position.set( 10, 100, 10 );

// now we add the cube
// geometry = new THREE.BoxBufferGeometry( 20, 20, 20);
// material = new THREE.MeshStandardMaterial({ color: 0xffffff });
// cube = new THREE.Mesh( geometry, material);

//
// The invisible plane
//
geometry = new THREE.PlaneBufferGeometry( 10000, 10000 );
material = new THREE.MeshBasicMaterial( {
visible: false
});

invisible_plane = new THREE.Mesh( geometry, material );

//
//
//

controls = new THREE.TrackballControls( camera, renderer.domElement );

animate();

//
// ACTION!
//

renderer.domElement.onclick = function(e) {

if (!e.shiftKey) {
e.preventDefault();
return false;
}

console.log('yes! you clicked!');

pixel_coords = new THREE.Vector2( e.clientX, e.clientY );

console.log('Pixel coordinates', pixel_coords);

vp_coords = new THREE.Vector2( ( pixel_coords.x / window.innerWidth ) * 2 - 1,
-( pixel_coords.y / window.innerHeight ) * 2 + 1);

console.log('Viewport coordinates', vp_coords);

vp_coords_near = new THREE.Vector3( vp_coords.x, vp_coords.y, 0);

raycaster = new THREE.Raycaster();
raycaster.setFromCamera(vp_coords_near, camera);
intersects = raycaster.intersectObject(invisible_plane);

console.log('Ray to Invisible Plane', intersects[0].point);

// update cube position
// cube.position.set(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z);

};

};

function animate() {

requestAnimationFrame( animate );

controls.update();
renderer.render( scene, camera );

};

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

This is also Assignment 03 starter code!

GLSL

A rather complex example of shaders:

``````attribute vec4 a_position;

void main() {
gl_Position = a_position;
}``````

This shader does nothing besides passing through positions.

``````attribute vec4 a_position;

void main() {
gl_Position = a_position;
}``````

This shader does nothing besides passing through positions.

data is different for each vertex!

(x, y, z, w)

(x, y, z, 1.)

name

``````attribute vec4 a_position;

void main() {
gl_Position = a_position;
}``````

This shader does nothing besides passing through positions.

gl_Position is the output of any vertex shader

``````precision mediump float;

void main() {
gl_FragColor = vec4(1., 1., 1., 1.);
}``````

This shader colors every fragment (pixel) white.

``````precision mediump float;

void main() {
gl_FragColor = vec4(1., 1., 1., 1.);
}``````

This shader colors every fragment (pixel) white.

defines the number of decimals for every value

``````precision mediump float;

void main() {
gl_FragColor = vec4(1., 1., 1., 1.);
}``````

This shader colors every fragment (pixel) white.

every fragment shader outputs a color for

the current fragment / pixel.

gl_Position

gl_FragColor

for every vertex

for every pixel