3D Math Primer: CocoaConf Atlanta

Post on 24-Jul-2015

355 views 2 download

Transcript of 3D Math Primer: CocoaConf Atlanta

The Day You Finally Use Algebra!

Janie Clayton

About Me

But math is hard! (Let’s go shopping!)

Math is hard. But math is fun too.

Demo

Normalized Coordinate

Systems

Cartesian Coordinates

320

480

320

480 or 568

1

1

(0,0) (1,0)

(0,1) (1,1)

(0,0) (1,0)

(0,1) (1,1)

(0,0) (1,0)

(0,1) (1,1)

self.size.width

self. size.

height

- Colors, like the screen dimensions, are based on percentages rather than absolute values.

- If you come from a graphic design background, you need to convert your 255 scale to percentages.

Algorithm Rosetta Stone

Rosetta Stone- Had the same text in

Greek, demotic, and hieroglyphics. Was used to translate hieroglyphics

- Going to do similar thing, but with math algorithms, plain English, and code

√-1 2ˆ3 ∑ π

∑5

i = 1

4i

Algoritm

Plain English

I have a starting value of one. I have an end value of five. I want to multiply each value

by four and add them together.

var x = 0

for index in 1…5 {

x += (4 * index)

}

Code

√-1 2ˆ3 ∑ π…and it was delicious!

i 8 sum pi…and it was delicious!

Trigonometry

Triangles

A shape with three sides where the angles add up to 180 degrees

Everything in our world comes back to triangles

The most stable shape

Foundation of 3D graphics

Right Triangles

Pythagorean Theorem

aˆ2 + bˆ2 = cˆ2

Circle Formulas

Circumference: 2πr

Area: πrˆ2

So What Can We Do Knowing This?

Change the direction a character is moving in

Check to see if the user is hitting a target area on the screen

Draw shapes and filters in specific configurations

Linear Algebra

– BetterExplained.com

“The survivors of linear algebra classes are physicists, graphics programmers and other

masochists.”

What is Linear Algebra?

Linear Algebra allows you to perform an action on many values at the same time.

This action must be consistent across all values, such as multiplying every value by two.

What is Linear Algebra?

Values are placed in an object called a matrix and the actions performed on the values are called transforms

Linear algebra is optimized for parallel mathematical operations.

Vector Data Types

vec2, vec3, vec4: 2D, 3D, and 4D floating point vector objects.

vec2: (x, y)

vec3: (x, y, z)

vec4: (r, g, b, a)

Vectors

9

33√10

Demo

Enter the Matrix

Matrix Data Types

mat2, mat3, mat4: 2, 3, and 4 element matrices.

mat2: Holds a 2 X 2 number matrix

mat3: Holds a 3 X 3 number matrix, used for 2D linear algebra

mat4: Holds a 4 X 4 number matrix, used for 3D linear algebra

1.0 1.0 1.0 0 1.0 1.0 1.0 0 1.0 1.0 1.0 0 1.0 1.0 1.0 0

Column

Row

mat4 genericMatrix = mat4(

1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0, 0, 0, 0

);

Column

Row

vec4 firstColumn = vec4(1.0, 1.0, 1.0, 1.0);

vec4 secondColumn = vec4(1.0, 1.0, 1.0, 1.0);

vec4 thirdColumn = vec4(1.0, 1.0, 1.0, 1.0);

vec4 fouthColumn = vec4(0, 0, 0, 0);

mat4 myMatrix = mat4( firstColumn, SecondColumn, thirdColumn, FourthColumn

);

CGAffineTransform

Affine, Wha?? :(A transform is any function that alters the size, position, or rotation of an object on your screen.

Four types: Identity, Translate, Rotation, and Scale.

For a transform to be affine, the lines in your shape must be parallel.

CGAffine Transform Methods

CGAffineTransformMakeRotation (GLFloat angle);

CGAffineTransformMakeScale (CGFLoat sx, CGFloat sy);

CGAffineTransformMakeTranslation (CGFloat tx, CGFloat ty);

struct CGAffineTransform { CGFloat a; GLFloat b; CGFloat c; CGFloat d; CGFloat tx; CGFloat ty

}

[x y 1][a b 0 c d 0 tx ty 0]

X =

[x’ y’ 1]

let pointX = a * x + c * y + tx

let pointY = b * x + d * y + ty

CGAffineTransformMakeRotation(45)

CGAffineTransformMakeScale(2,2)

rotate 45 degrees

Double Size

Refraction Fragment Shader Example

void main() { highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); highp float distanceFromCenter = distance(center, textureCoordinateToUse); lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius); distanceFromCenter = distanceFromCenter / radius; highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); highp vec3 refractedVector = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); refractedVector.xy = -refractedVector.xy; highp vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb; // Grazing angle lighting highp float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25)); finalSphereColor += lightingIntensity; // Specular lighting lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0); lightingIntensity = pow(lightingIntensity, 15.0); finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity; gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere; }

highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));

highp float distanceFromCenter = distance(center, textureCoordinateToUse);

lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);

distanceFromCenter = distanceFromCenter / radius;

highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);

highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));

highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);

 gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;

The End