990 likes | 1.16k Views
CS 234 Jeff Parker. 3D Transformations. Objectives. Notifications Homework Gallery Pen and Paper Review transformations Apply these ideas to 3D movement. Notifications. I've figured out how to get notified by iSite:. Notifications. I've figured out how to get notified by iSite:.
E N D
CS 234 Jeff Parker 3D Transformations
Objectives • Notifications • Homework • Gallery • Pen and Paper • Review transformations • Apply these ideas to 3D movement
Notifications • I've figured out how to get notified by iSite:
Notifications • I've figured out how to get notified by iSite:
Notifications • I've figured out how to get notified by iSite:
Gallery & Three Requests • We will look at three examples: I have posted the code for each • Please include a .jpg of your project • A jpg makes it easy for me to include your screenshot • We do like .pdfs, but don't want to tear them apart • Please include your name in all your files • Makes it easier for us to match you to your work • Please mimic Angel's organization • Create a folder with your name on it. • Develop your source in folder. Zip the folder and submit. • Root • Common • JohnDoeHw4 • <Your .html and .js files>
Gallery Charles
Gallery Dan
Dan • // set up the tic tac toe board • drawRectP(0.32, 1, 0.34, -1); • drawRectP(-0.32, 1, -0.34, -1); • drawRectP(-1, 0.32, 1, 0.34); • drawRectP(-1, -0.32, 1, -0.34); • canvas.addEventListener("mousedown", function(e) • { • if ( moves >8) return; • // we'll say that the first player is X, then O • // Get the x/y index of where the user clicked • ... • var clickedBox = getClickedBox(e);
Dan • function getClickedBox(e) • { • var x = e.offsetX==undefined?e.layerX:e.offsetX; • var y = e.offsetY==undefined?e.layerY:e.offsetY; • var p = vec2(2*x/canvas.width-1, • 2*(canvas.height-y)/canvas.height-1); • var yIndex; • var xIndex; • if (p[0] < -0.32) { • xIndex = 0; • } • else if (p[0] > -0.34 && p[0] < 0.32) { • xIndex = 1; ...
Dan • // we'll say that the first player is X, then O • // first we get the x/y index of where the user • ... • var clickedBox = getClickedBox(e); • var xIndex = clickedBox[0]; • var yIndex = clickedBox[1]; • // if user clicked in a box • if (typeof xIndex != 'undefined' && • typeof yIndex != 'undefined') { • var boxIndex = (xIndex * 3) + yIndex; • if (usedBoxes.indexOf(boxIndex) > -1) • return; • usedBoxes.push(boxIndex);
Dan • // we draw in that location, 0,0 bottom left, 2,2 • moves++; • var xCenter = -1 + ((xIndex * 0.66) + .165); • var yCenter = -1 + ((yIndex * 0.66) + .165); • if (first) { • // draw "X" as first player • drawX(xCenter, yCenter); • first = false; • } • else { • // draw "O" as second player • first = true; • drawO(xCenter, yCenter); • }
Gallery Polina Note the instructions The checkers are lovely
Gallery Polina Note the instructions The checkers are lovely
Gallery Polina • Two colors • Selected & User • Selected is • Black or white • Interpolate between Note the instructions The checkers are lovely
Gallery Alexander Multiple instances of same shape Move the object before rasterizing Output of the program: caught and missed
Alex • <!DOCTYPE html> • <html> • <head> • <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > • <title>2D Sierpinski Gasket</title> • <script id="vertex-shader" type="x-shader/x-vertex"> • attribute vec3 vPosition; • attribute vec3 vColor; • uniform float dgrs; • uniform vec3 trnsX; • varying vec4 color;
Alex • <!DOCTYPE html> • <html> • <head> • <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > • <title>2D Sierpinski Gasket</title> • <script id="vertex-shader" type="x-shader/x-vertex"> • attribute vec3 vPosition; • attribute vec3 vColor; • uniform float dgrs; • uniform vec3 trnsX; • varying vec4 color; Please include your name in all files Check title
Alex • <script id="vertex-shader" type="x-shader/x-vertex"> • ... • uniform float dgrs; • uniform vec3 trnsX; • ... • void • main(){ • mat4 rotateMat = mat4( 1, 0, 0, 0, • 0, cos(dgrs), sin(dgrs), 0, • 0, -sin(dgrs), cos(dgrs), 0, • 0, 0, 0, 1); • mat4 translationMat = mat4( 1, 0, 0, 0, • 0, 1, 0, 0, • 0, 0, 1, 0, • trnsX[0], trnsX[1], trnsX[2], 1); • gl_Position = translationMat * rotateMat * vec4(vPosition, 1.0); • color = vec4(vColor, 1.0); • } </script>
Alex's JS • // Renders the circle which represents the hole • function renderHole(){ • gl.uniform1f(rotateDegrees, 0.95); • gl.uniform3fv(translateVector, [holePosition[0], • holePosition[1], holePosition[2]]); • gl.drawArrays( gl.TRIANGLE_FAN, spherePoints, circlePoints ); • } • // Renders the sphere(s) • function renderCphere(){ • gl.uniform1f(rotateDegrees, 0.55); • for(var i = 0; i < spheresPositions.length; i++){ • gl.uniform3fv(translateVector, spheresPositions[i]); • gl.drawArrays( gl.TRIANGLE_STRIP, 0, spherePoints ); • } • } Draw multiple copies of same thing
Gallery Derrick Thoughts?
Gallery Derrick "I downloaded a picture of a go board from the internet and then used an eye dropper tool from Pixelmator to choose the color with the rgb values." - Derrick
Gallery Derrick var baseColors = [ vec4(0.77, 0.64, 0.39, 1.0), //background vec4(0.0, 0.0, 0.0, 1.0), //black vec4(1.0, 1.0, 1.0, 1.0) //white ]; Multiple instances of same shape Move the object before rasterizing
Derrick • function render() • { • gl.clear( gl.COLOR_BUFFER_BIT ); • // board grid lines • for (var i=0; i < 80; i=i+2) • gl.drawArrays(gl.LINE_LOOP, i, 2); • // render go stones • for (var i=80; i < index; i=i+numOfCirclePoints) • gl.drawArrays(gl.TRIANGLE_FAN, i, numOfCirclePoints); • window.requestAnimFrame(render); • } Uses same buffer to hold lines and triangles
Derrick • for (var j=0; j < boardDimension; j++) • { • for (var i=0; i < boardDimension; i++) • { • vertPos=((j*boardDimension) + i)*4; • if ((i % 2)==(j % 2)) • { • square (vertices[vertPos], vertices[vertPos+1], vertices[vertPos+2], vertices[vertPos+3], 0); • } • else • { • square (vertices[vertPos], vertices[vertPos+1], vertices[vertPos+2], vertices[vertPos+3], 1); • } • if ((i==(boardDimension-1)) && (j != (boardDimension-1))) • { • triangle (vertices[vertPos+2], vertices[vertPos+3], vertices[vertPos+3], 0 ); • triangle (vertices[vertPos+3], vertices[vertPos+3], vertices[vertPos+4], 0 ); • } • } • }
Review: Pipeline Implementation v T frame buffer u T(u) transformation rasterizer T(v) T(v) T(v) v T(u) u T(u) vertices pixels vertices
Affine Transformations • We want our transformations to be Line Preserving • Characteristic of many physically important transformations • Rigid body transformations: • Rotation, Translation • Non-Rigid transformations: Scaling, Shear • We need only transform endpoints of line segments • Let GPU connect transformed endpoints
Rotations • Matrices provide a compact representation for rotations, and many other transformation • T (x, y) = (x cos(a) - y sin(a), x sin(a) + y cos(a)) • To multiply matrices, multiply the rows of first by the columns of second
Euler Angles • Rotations about x, y, or z axis • Perform the rotations in fixed order • Any rotation is the produce of three of these rotations • Euler Angles • Not unique • Not obvious how to find the angles • Different order would give different angles Euler Angles Wikipedia
Determinant • If the length of each column is 1, the matrix preserves the length of vectors (1, 0) and (0, 1) • We also will look at the Determinant • Determinant of a rotation is 1 • But determinant == 1 does not imply a rotation
Scaling Expand or contract along each axis (fixed point of origin) S = S(sx, sy, sz) = x’=sxx y’=syx z’=szx p’=Sp user.xmission.com/~nate/tutors.html
Reflection Reflection corresponds to negative scale factors Has determinant == -1 Example below sends (x, y, z) (-x, y, z) Note that the product of two reflections is a rotation sx = -1 sy = 1 original sx = -1 sy = -1 sx = 1 sy = -1
Order of Transformations • Note that matrix on the right is the first applied to the point p • Mathematically, the following are equivalent p’ = ABCp = A(B(Cp)) • We use column matrices to represent points. In terms of row matrices p’T = pTCTBTAT • That is, the "last" transformation is applied first. • We will see that the implicit transformations have the same order property
Rotation About a Fixed Point other than the Origin Move fixed point to origin Rotate Move fixed point back M = T(pf) R(q) T(-pf)
Instancing • In modeling, we often start with a simple object centered at the origin, oriented with the axis, and at a standard size • We apply an instance transformation to its vertices to Scale Orient (rotate) Locate (translate) TRS
Shear • Helpful to add one more basic transformation • Equivalent to pulling faces in opposite directions
Shear Matrix Consider simple shear along x axis x’ = x + y cot q y’ = y z’ = z H(q) =
Translations • We cannot define a translation in 2D space with a 2x2 matrix • No choice for a, b, c, and d that moves the origin, (0, 0), to some other point, such as (5, 3) in the equation above
Translation • To address this, we consider 2D movements in 3D • We pick a representative – we let (x, y, 1) represent (x, y) • Like coasters on glass coffee table one unit above the floor • Track the movement of these representatives
Translation • We use a shear transformation T(x, y, z) in 3D • Note that T(0, 0, 0) = (0, 0, 0) • However, T(0, 0, 1) = (5, 3, 1) • Combines with scaling, reflection, and rotation
Translation • We use a shear transformation T(x, y, z) in 3D • Note that T(0, 0, 0) = (0, 0, 0) - Vector • However, T(0, 0, 1) = (5, 3, 1) - Point • Combines with scaling, reflection, and rotation
Projective Space • What happens if transformation moves point (x, y, 1) off the plane z = 1? • We rescale - divide by the z value • For example, the point (9, 21, 3) (3, 7, 1) • We may reduce to "lowest form" – when z = 1 • Project onto the plane z = 1 • We have many representatives of the form: (3t, 7t, t) • There are all equivalent in our Projective Model
Projective Space • The same trick works to perform 3D Translations • Represent triples (x, y, z) as (x, y, z, 1) in 4D • Harder to visualize this • Mathematicians reason by analogy to lower dimensions
GLSL uses col major form • <script id="vertex-shader" type="x-shader/x-vertex"> • ... • uniform float dgrs; • uniform vec3 trnsX; • ... • void • main(){ • mat4 rotateMat = mat4( 1, 0, 0, 0, • 0, cos(dgrs), sin(dgrs), 0, • 0, -sin(dgrs), cos(dgrs), 0, • 0, 0, 0, 1); • mat4 translationMat = mat4( 1, 0, 0, 0, • 0, 1, 0, 0, • 0, 0, 1, 0, • trnsX[0], trnsX[1], trnsX[2], 1); • gl_Position = translationMat * rotateMat * vec4(vPosition, 1.0); • color = vec4(vColor, 1.0); • } </script>
Inverses • We can find inverses for all of our transformations • Focus on the basic moves we have studied – • Translation – translate back in the opposite direction • Rotation – rotate the the same angle, backwards • Reflection – reflect a second time in the same plane • Scale – rescale by the reciprocal: If you doubled x, halve x.
Rotating Cube • Angel gives us two versions • They look the same • Difference is in how we send traingles to GPU • "All problems in computer science can be solved by another level of indirection" – David Wheeler
HTML files • $ diff cube.html cubev.html • 43c43,45 • < precision mediump float; • --- • > #ifdef GL_ES • > precision highp float; • > #endif • 57c59 • < <script type="text/javascript" src="cube.js"></script> • --- • > <script type="text/javascript" src="cubev.js"></script> • ...
HTML files • The first difference can be removed • The versions on iSite have been edited to align them • Changes to html and js files • $ diff cube.html cubev.html • 57c59 • < <script type="text/javascript" src="cube.js"></script> • --- • > <script type="text/javascript" src="cubev.js"></script>
cube.js • var NumVertices = 36; • var points = []; • var colors = []; • var xAxis = 0; • var yAxis = 1; • var zAxis = 2; • var axis = 0; • var theta = [ 0, 0, 0 ];
cube.js // Euler Angles • var axis = 0; • var theta = [ 0, 0, 0 ]; • function render() • { • gl.clear( gl.COLOR_BUFFER_BIT | • gl.DEPTH_BUFFER_BIT); • theta[axis] += 2.0; • gl.uniform3fv(thetaLoc, theta); • gl.drawArrays( gl.TRIANGLES, 0, NumVertices ); • requestAnimFrame( render ); • }