32
Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved...

Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Embed Size (px)

Citation preview

Page 1: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals and Lighting

Vectors

Normals

Lighting

Shading models

Backface culling

The world is curved...

Page 2: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

Vector: A point in space.Space can be one-dimensional...

Two-dimensional...

Three-dimensional...

Or four--or more!

(but only at 8:14AM exactly!)

Page 3: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

Vectors are points in space; points in space are vectors. We usually use the term point to refer to a location in space. We usually use the term vector to refer to the arrow that goes

there from the origin. They mean the same thing.

A one-dimensional vector is called a scalar. P=[x, y, z] is a vector. N=12 is a scalar. [-2, 16] is a vector. π is a scalar.

Page 4: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math: Sample code

class Vec

{

private:

float m_x, m_ y, m_ z;

public:

Vector(void) { x = y = z = 0; }

Vector(float x, float y, float z)

{ m_x = x; m_y = y; m_z = z; }

Vector(const Vector &V)

{ m_x = V.x(); m_y = V.y(); m_z = V.z(); }

float x() { return m_x; }

float y() { return m_y; }

float z() { return m_z; }

};

Page 5: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

The length of a vector is found using the Pythagorean Theorem. P = [x, y, z] length(P) = sqrt(x2+y2+z2)

Putting that in code:public:

float length(void)

{ return sqrt(m_x*m_x + m_y*m_y + m_z*m_z); }

Page 6: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

If you multiply a vector by a scalar, you change the length of the vector but keep the same direction: P = [ x, y ] P*2 = [ x*2, y*2 ] P*3 = [ x*3, y*3 ] P*-42 = [ x*-42, y*-42 ]

If you divide a vector by its own length, that’s called normalising the vector.

A normalised vector has length=1; it’s called a unit vector.

Page 7: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

If you subtract one point from another, you get the vector which goes between them. If you have two points in space, A and B:

then the vector V = B-A is the vector from A to B:

A

B

A

B

Page 8: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math: Sample code

More handy code:public:

Vec operator +(const Vec &V)

{ return Vec(m_x+V.x(), m_y+V.y(), m_z+V.z()); }

Vec operator -(const Vec &V)

{ return Vec(m_x-V.x(), m_y-V.y(), m_z-V.z()); }

Vec operator *(float f)

{ return Vec(m_x*f, m_y*f, m_z*f); }

Vec operator /(float f)

{ return (f!=0) ? (*this)*(1.0/f) : (*this)/0.000001; }

Using length() to normalize:public:

Vec normalized(void) { return (*this)/length(); }

Page 9: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

Multiplying vectors A vector times a scalar is a new vector in the same direction as the

old vector. A vector times another vector is...?

There are two ways to multiply two vectors: Dot Product:

f = A * B

f = A.x*B.x + A.y*B.y + A.z*B.z; Cross Product:

N = A x B

N.x = A.y*B.z - A.z*B.y

N.y = -A.x*B.z + A.z*B.x

N.z = A.x*B.y - A.y*B.x

Page 10: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

Dot Products A dot product takes two vectors and returns a scalar. In one-dimensional numbers, a dot product /is/ multiplication

as we know it; x*y=z, all scalars.

A few of the properties of a dot product: The dot product of two unit vectors is equal to the cos() of the

angle between them. If the dot product of two unit vectors is positive, the angle

between them is less than ninety degrees. If the dot product is zero, the angle is exactly ninety. If the dot product is less than zero, the angle between the two

vectors is greater than ninety degrees.

C

A

B

θ

Page 11: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

A cross product finds a vector which is exactly perpendicular to the two vectors being crossed.

A single vector lies on a line. Three points define a plane. The cross product of two vectors is a vector parallel to the normal of their plane. (And oddly enough, the length of the resulting vector is

exactly the area of the parallelogram whose two sides are formed by the two vectors.)

Page 12: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math: Sample code

The dot product:float operator *(const Vec &V)

{ return m_x*V.x() + m_y*V.y() + m_z*V.z(); }

The cross product:Vec operator ^(const Vec &V)

{

Vec crossProduct;

crossProduct.m_x = m_y*V.m_z - m_z*V.m_y;

crossProduct.m_y = m_z*V.m_x - m_x*V.m_z;

crossProduct.m_z = m_x*V.m_y - m_y*V.m_x;

return crossProduct;

}

Page 13: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Vector Math

Working with points in space: To find the angle between two vectors, you dot the vectors and

take the inverse cosine ( acos() ) of the dot.

You can find the angle between two intersecting lines by subtracting the intersection point from points on the lines, normalising the vectors, and taking the acos() of the dot.

To find the line perpendicularto the two lines, subtract the points, normalise the vectorswhich result, then cross them.

V=B-A goes from A to B!

Page 14: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals

Using the techniques just covered, you can find the normal to a polygonal surface at any point. Remember, 3D objects are made of polygons. Polygons are planar, made of points in space. You can find the normal to a polygon by picking any three

points on the poly, subtracting one of them from each of the other two, and crossing the vectors that result.

Normal

P2

P3

P4 P5

P1Normal =

(P2-P1) x (P5-P1)

Page 15: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals

Sometimes your data isn’t stored as a set of polygons. If you’re working with an implicit surface, you can still find the

surface normal. You just need to calculate the nearby points on the surface by nudging u and v a tiny bit.

Take a look at the GL_QUADS code on week 6’s optional handout for an example.

Normal

P2

P3

P1Normal =

(P2-P1) x (P3-P1)

Page 16: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals: The Right-Hand Rule

One question is: okay, so you can find the normal to a surface. Which side of the surface does it point away from?

The answer is: use the Right-Hand Rule. Curl your right hand clockwise, from the first vector being crossed towards the second vector being crossed. Your thumb points in the direction of the normal.

The OpenGL default is to assume that the vertices in a polygon are arranged in counterclockwise (anticlockwise) order around the normal.

Page 17: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals

Page 18: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Surface Normals - Why bother?

So what’s the point of finding the normal to the surface at a point or on a face? (1) This is the lynchpin to lighting. (2) It can also be used for backface culling, an optimisation often

used to speed up rendering times.

Lighting uses surface normals to figure out how the light should bounce off of a surface at any particular point.

Backface culling uses normals to test whether the face is visible to the user at all; using this quick test, if the face couldn’t be visible, it won’t be rendered or processed at all. Speedy!

Page 19: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Lighting

Light sources in computer graphics break down into two categories: Point lights Directional lights

Light itself breaks down into three types of light: Ambient light

- The omnidirectional, floating, everywhere lighting Diffuse light

- Light that gets scattered around by the surface Specular light

- Shiny light that bounces to the eye of the viewer

Page 20: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Lighting

Ambient lighting is the light that permeates the world. Directionless, sourceless, omnipresent. Think of the way, when you’re in fog, light seems to be everywhere

at once.

Diffuse lighting is the light that bounces off the surface. Diffuse lighting shows the curve of the surface, wherever you’re

from. Think of how a clay ball shades from the light.

Specular lighting is the light that bounces off the surface directly into your eye. Some surfaces are shinier than others. Consider a steel ball versus

a ball of chalk.

Page 21: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Lighting

Page 22: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Positioning the light

The position of the light is irrelevant in the ambient lighting calculations.

The position of the light is relevant in calculating diffuse lighting, but the position of the camera is not.

The position of the light AND the position of the camera are both used in calculating specular highlights.

Ambient Diffuse Specular

Page 23: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Lighting in OpenGL

The following sample code will set up a simple light:float amb[4] = { 0.3, 0.3, 0.3, 1.0 };

float dif[4] = { 0.5, 0.5, 0.5, 1.0 };

float pos[4] = { 0, 0, -10, 0 };

glLightfv(GL_LIGHT0, GL_AMBIENT, amb);

glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);

glLightfv(GL_LIGHT0, GL_POSITION, pos);

glEnable(GL_LIGHT0);

glEnable(GL_LIGHTING);

glEnable(GL_COLOR_MATERIAL);

GL_LIGHT0 is the first possible light in GL.

Page 24: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Lighting in OpenGL - specular highlights

When using specular lighting in OpenGL, the default ‘shininess’ setting used in the lighting calculations is set to the maximum possible shininess:

To see a clear highlight, you’ll need to turn down the shine:

glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10);

// possible range: 0--128.

Page 25: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Positioning a light in OpenGL

The position of a light in GL is just like the position of a glVertex(), transformed by the current matrix transforms.

That means that to properly position a light in the scene, you need to call glLightfv(GL_LIGHT0, GL_POSITION, pos) after you’ve set your camera’s position with gluLookAt().

Order of operations in your render routine will be: Clear color and depth buffers; load identity matrix Load camera position Load light(s) position(s) Render geometry

Page 26: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Shading Models

There are a couple of different ways to shade your model:

Flat Shading Smooth Shading

Page 27: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Shading Models

In flat shading, the renderer uses the normal of the polygon to shade the entire polygon uniformly, from corner to corner.

P2

P3

P4 P5

P1

Page 28: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Shading models

In smooth rendering, the renderer uses the normal at each corner to calculate the shading of the surface at that exact spot, then interpolates the color across the polygon from corner to corner.

This is called Gouraud shading. An even more advanced technique is Phong shading. In Phong

shading, the normals themselves are interpolated across the polygon, producing an even smoother shading effect--but at the cost of much higher rendering time.

Page 29: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Shading models in OpenGL

To specify the shading model in OpenGL: Smooth shading:

glShadeModel(GL_SMOOTH);

Flat shading: glShadeModel(GL_FLAT);

Note that solid wireframe models look best in flat shading, but most curving surfaces look best in smooth shading.

Page 30: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Backface Culling

Another use of normals is backface culling, an optimisation to speed up rendering.

If you have a solid object, opaque, then you can’t see the back of it because the front is in the way.

So you can optimize rendering and never even process any polygon on the back of the object.

How to tell if it’s on the back? Well, one sure-fire trick is to see if the polygon faces away from the camera. If we see the poly’s back then there must be some other poly between that poly and our camera.

Page 31: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Backface Culling

You can tell whether a polygon faces away from the camera from its normal. If the normal of the polygon doesn’t point towards the camera,

it must point away from us; which means we can cull it. To test whether the normal points towards us or away, take

the dot product of the normal of the polygon with the camera’s view vector. If the dot product is positive, then the two vectors point in the same direction; cull away!

Negative dot products

Positive dot products

Page 32: Surface Normals and Lighting Vectors Normals Lighting Shading models Backface culling The world is curved

Backface Culling in OpenGL

By default, backface culling is enabled in OpenGL.

To enable backface culling: glEnable(GL_CULL_FACE);

To disable backface culling: glDisable(GL_CULL_FACE);

To choose between culling fronts or backs: glCullFace(GL_FRONT); glCullFace(GL_BACK); // (Default)