Top Banner
1 Shaders, Viewing & Perspective CS 234 Jeff Parker
103

1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Dec 20, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

1

Shaders, Viewing & Perspective

CS 234

Jeff Parker

Page 2: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

2

Objectives

Shader ProgramsPerspective

What it looks likeHow we make it happenThe limitations of the zBuffer

Debugging with –gldebug and glGetError()

Gallery – Screen Shots (at end of this document)

Page 3: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

3

Shader Outline

What is a GPU?Why perform GPU processing?Challenges of Parallel ProcessingBasics of GPU

Vertex ShaderFragment Shader

Programming ParadigmExamples

Page 4: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

4

What is a GPU?

Specialized silicon for offloading graphics processing from CPU

While there have been GPUs going back at least to the Commodore Amiga, the term currently implies the ability to program the GPU

Page 5: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

5

What Languages?

Offline RenderingRenderMan – the first shader languageHoudini and Gelato – modeled on RenderMan

Real-time shadersARB Shaders – low level shading GLSL (OpenGL Shading Language) Cg – NVIDIADirectX HLSL (High Level Shader Language)

Page 6: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

6

NVIDIA G70

Page 7: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

7

Parallelism

Computer Scientists have been looking for a way to use multiple CPUs to speed up calculations

Obstacles include Sequential nature of many computations Fighting over shared data

a[i] = a[i-1] + i;There have been isolated areas of success

Numerical SimulationsSQL

Page 8: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

8

Graphics

Shading polygoins is another place for parallelism

I can tranform v1 and v2 independentlyMany scan lines with many fragmentsI can scan line x + y = 2 without affecting x - y = 3I can also scan x + y = 2, x < 50

without affecting x + y = 2, x > 50Both write to frame buffer and z buffer, but update

different spots.

Page 9: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

9

Two models

SIMDSingle Instruction, Multiple DataOne code path, multiple processors working in

parallelData Driven streams

Sea of data washes over bed of computational unitsData module has all relevant informationWhen a complete data unit meets a free

computational unit, the data is transformedFlows down stream for the next operation

Page 10: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

10

Graphics Languages

Unlike CPU, GPU architecture details hiddenOpenGL or DirectX provide a state machine that

represents the rendering pipeline.Early GPU programs used properties of the state

machine to “program” the GPU.Tools like Renderman provided sophisticated

shader languages, but these were not part of the rendering pipeline.

Page 11: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

11

Prior Art

One “programmed” in OpenGL using state variables like blend functions, depth tests and stencil tests

glClearColor(0.0, 0.0, 0.0, 0.0);glClearStencil(0); glStencilMask(1); // Can only write LSBitglEnable(GL_STENCIL_TEST);

glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glStencilFunc(GL_ALWAYS, 1, 1);glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

Page 12: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

12

Programmable Shaders, v1

As rendering pipeline became more complex, new functionality was added to the state machine via extensions.

The introduction of vertex and fragment programs provided full programmability to the pipeline.

With fragment programs, one could write general programs to process each fragmentMUL tmp, fragment.texcoord[0], size.x;

FLR intg, tmp;FRC frac, tmp;SUB frac_1, frac, 1.0;

Writing (pseudo)-assembly code is clumsy and error-prone.

Page 13: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

13

GLSL

Current GPU languages, such as Cg and GLSL allow programmer to work in something resembling C

uniform float time; /* in milliseconds */void main(){

float s; vec4 t = gl_Vertex; t.y = 0.1*sin(0.001*time+ 5.0*gl_Vertex.x) *sin(0.001*time+5.0*gl_Vertex.z);

gl_Position = gl_ModelViewProjectionMatrix * t; gl_FrontColor = gl_Color;

}

Page 14: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

14

Model

All the language models share basic properties:1. They view the pipeline as an array of “pixel

computers”, with the same program running at each computer

In fact, there are two types of computers: vertex computers and fragment computers

2. Data is streamed to each pixel computer3. The pixel programs have limited state.Issues – communication between components

Between CPU and pixel computersBetween Vertex and Fragment ShadersBetween different Vertex (Fragment) Shaders

Page 15: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

15

Programmable Pipeline Elements

We will define vertex shader and fragment shader programs

There are predefined:variables, holding position, color, etcOpenGL state, such as

matrices: Model and View transformationOrder of operations is implicitWe can define new variables and functions

We need to declare the scope of these variables

Page 16: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

16

Communication

For CPU to communicate to ShadersCan used predefined attributesCan define uniform variablesCan use textures (called samplers)

Page 17: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

17

Pass Through Vertex Shader

void main()

{

gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

}

Vertex shader does not know anything about connectivity of verticesThere is a Geometry Processor – we won't say more about this

The job of the vertex shader is to take the attributes provided by the CPU:the projection Matrix and the View matrix gl_Vertex - the position of the vertex in world space

And produce something for the Rasterizer, which feeds the fragment shaders:gl_Position

Page 18: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

18

Pass Through Vertex Shader

void main()

{

gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

}

// Simpler version

void main()

{

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

Page 19: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

19

Fragment Shader

// fPassThrough.glsl// Pass through fragment shader.

void main(){

gl_FragColor = gl_Color;}

The job of fragment shader is to take attributes provided by the vertex shader and define the color that will be stored in the frame buffer

Page 20: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

20

Wave example

Page 21: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

21

Non-trivial Vertex Shader

// We walk through this in the next slideuniform float time; /* in milliseconds */

void main(){

float s;vec4 t = gl_Vertex;t.y = 0.1*sin(0.001*time+5.0*gl_Vertex.x) * sin(0.001*time+5.0*gl_Vertex.z);

gl_Position = gl_ModelViewProjectionMatrix * t;gl_FrontColor = gl_Color;

}

Page 22: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

22

Variable Scope

const: compile time constantuniform: parameter is fixed over a glBegin/glEnd

pairattribute: per-vertex information send from CPU:

coordinates, texture coords, normals, color, …Predefined and user defined

varying: interpolated data that a vertex shader sends to the fragment shaders

Page 23: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

23

Datatypes

Singletons -float, bool, int – no bitmaps

float a,b; int c = 2;bool d = true;

Vectorsvec{2, 3, 4} – vector of floats

vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex;vec2 a = vec2(1.0, 2.0);vec2 b = vec2(3.0, 4.0);vec4 c = vec4(a,b) // c = vec4(1.0, 2.0, 3.0, 4.0);

bvec{2, 3, 4} – boolean vectorivec{2, 3, 4} – integer vector

Page 24: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

24

Vertex Shader

// The CPU modifies the value of time in the update routine

uniform float time; /* in milliseconds */

void main()

{

float s;

// gl_Vertex is pre-vertex attributed passed by CPU

vec4 t = gl_Vertex;

// t is a vector: we will modified the vertex position

t.y = 0.1*sin(0.001*time+5.0*gl_Vertex.x) * sin(0.001*time+5.0*gl_Vertex.z);

// Use new value of vertex to update gl_Position

gl_Position = gl_ModelViewProjectionMatrix * t;

// Pass through color

gl_FrontColor = gl_Color;

}

Page 25: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

25

Vertex builtins

Per Vertix attributes

in int gl_VertexID;

in int gl_InstanceID;

out gl_PerVertex {

vec4 gl_Position;

float gl_PointSize;

float gl_ClipDistance[];

};

Global Attributes

in vec4 gl_Color;

in vec4 gl_SecondaryColor;

in vec3 gl_Normal;

in vec4 gl_Vertex;

in vec4 gl_MultiTexCoord0;…

in vec4 gl_MultiTexCoord7;

in float gl_FogCoord;

Page 26: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

26

Sending time from CPU

// wave.c program running in CPU

GLint timeParam;

GLuint program = 0; /* program object id */

/* GLSL initialization */

static void initShader(const GLchar* vShaderFile, const GLchar* fShaderFile)

{

...

program = glCreateProgram();

...

timeParam = glGetUniformLocation(program, "time");

}

static void draw(void)

{

/* send elapsed time to shaders */

glUniform1f(timeParam, glutGet(GLUT_ELAPSED_TIME));

...

Page 27: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

27

Read Shader Source

// These routines can be used to read any pair of shaders

static char* readShaderSource(const char* shaderFile)

{

FILE* fp = fopen(shaderFile, "rb");

char* buf;

long size;

if (fp==NULL)

return NULL;

fseek(fp, 0L, SEEK_END);

size = ftell(fp);

fseek(fp, 0L, SEEK_SET);

buf = (char*) malloc((size+1) * sizeof(char));

fread(buf, 1, size, fp);

buf[size] = '\0';

fclose(fp);

return buf;

}

Page 28: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

28

initShader

static void initShader(const GLchar* vShaderFile, const GLchar* fShaderFile)

{

GLint status;

GLchar *vSource, *fSource;

GLuint vShader, fShader;

/* read shader files */

vSource = readShaderSource(vShaderFile);

if (vSource==NULL)

{

printf( "Failed to read vertex shader\n");

exit(EXIT_FAILURE);

}

fSource = readShaderSource(fShaderFile);

if (fSource==NULL)

{

printf("Failed to read fragment shader");

exit(EXIT_FAILURE);

}

Page 29: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

29

initShader (cont)

/* create program and shader objects */

vShader = glCreateShader(GL_VERTEX_SHADER);

fShader = glCreateShader(GL_FRAGMENT_SHADER);

program = glCreateProgram();

/* attach shaders to the program object */

glAttachShader(program, vShader);

glAttachShader(program, fShader);

/* read shaders */

glShaderSource(vShader, 1, (const GLchar**) &vSource, NULL);

glShaderSource(fShader, 1, (const GLchar**) &fSource, NULL);

Page 30: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

30

initShader (cont)

Page 31: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

31

initShader (cont)

glCompileShader(vShader);

/* error check */

glGetShaderiv(vShader, GL_COMPILE_STATUS, &status);

if (status==GL_FALSE)

{

printf("Failed to compile the vertex shader.\n");

glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &elength);

ebuffer = malloc(elength*sizeof(char));

glGetShaderInfoLog(vShader, elength, NULL, ebuffer);

printf("%s\n", ebuffer);

exit(EXIT_FAILURE);

}

/* compile fragment shader shader */

glCompileShader(fShader);

/* error check */

glGetShaderiv(fShader, GL_COMPILE_STATUS, &status);

if (status==GL_FALSE) // Blah, Blah, Blah...

Page 32: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

32

initShader (cont)

/* link and error check */

glLinkProgram(program);

glGetProgramiv(program, GL_LINK_STATUS, &status);

if (status==GL_FALSE)

{

printf("Failed to link program object.\n");

glGetProgramiv(program, GL_INFO_LOG_LENGTH, &elength);

ebuffer = malloc(elength*sizeof(char));

glGetProgramInfoLog(program, elength, &elength, ebuffer);

printf("%s\n", ebuffer);

exit(EXIT_FAILURE);

}

/* use program object */

glUseProgram(program);

/* set up uniform parameter */

timeParam = glGetUniformLocation(program, "time");

}

Page 33: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

33

mesh – build mesh

void mesh()

{

int i,j;

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(2.0, 2.0, 2.0, 0.5, 0.0, 0.5, 0.0, 1.0, 0.0);

for(i=0; i<N; i++) for(j=0; j<N;j++)

{

glColor3f(1.0, 1.0, 1.0);

glBegin(GL_POLYGON);

glVertex3f((float)i/N, data[i][j], (float)j/N);

glVertex3f((float)i/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j)/N);

glEnd();

glColor3f(0.0, 0.0, 0.0);

glBegin(GL_LINE_LOOP);

glVertex3f((float)i/N, data[i][j], (float)j/N);

glVertex3f((float)i/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j)/N);

glEnd();

}

}

Page 34: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

34

mesh – build mesh

void mesh() {

int i,j;

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(2.0, 2.0, 2.0, 0.5, 0.0, 0.5, 0.0, 1.0, 0.0);

for(i=0; i<N; i++)

for(j=0; j<N;j++)

{

glColor3f(1.0, 1.0, 1.0);

glBegin(GL_POLYGON);

glVertex3f((float)i/N, data[i][j], (float)j/N);

glVertex3f((float)i/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j)/N);

glEnd();

glColor3f(0.0, 0.0, 0.0);

glBegin(GL_LINE_LOOP);

glVertex3f((float)i/N, data[i][j], (float)j/N);

glVertex3f((float)i/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j+1)/N);

glVertex3f((float)(i+1)/N, data[i][j], (float)(j)/N);

glEnd();

}

}

Page 35: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

35

Main Programint main(int argc, char** argv) {

int i,j;

/* flat mesh */

for(i=0;i<N;i++)

for(j=0;j<N;j++)

data[i][j]=0.0;

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

glutInitWindowSize(512, 512);

glutCreateWindow("Simple GLSL example");

glutDisplayFunc(draw);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutIdleFunc(idle);

init();

initShader("vmesh.glsl", "fPassthrough.glsl");

glutMainLoop();

return 0;

}

Page 36: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

36

Recap

Program loads vertex and fragment shadersShaders take standard attributes and any program

specific additions, such as time in this exampleand compute standard results, and additional variablesWe have only seen use of standard attributes to

communicate between vertex and fragment shader.Per-vertex attributes for velocity in the Angel's

Particle exampleVarying data in toon example to pass information

from vertex shader to fragment shader

Page 37: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

37

Teapot Colors

Example with pass-through vertex shader, with work done in fragment shader

Page 38: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

38

Trivial Vertex Shader

void main()

{

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

gl_FrontColor = gl_Color;

}

Page 39: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

39

Fragment Shader

uniform float time;

void main()

{

float d = length(gl_FragCoord.xy);

gl_FragColor.r = 0.5*(1.0+sin(0.001*time))*gl_FragCoord.x/d;

gl_FragColor.g = 0.5*(1.0+cos(0.001*time))*gl_FragCoord.y/d;

gl_FragColor.b = gl_FragCoord.z;

gl_FragColor.a = 1.0;

}

Fragment shader is in charge of color – easy thing for it to changeThe rest of the program is as before: the main program opens and reads

the shaders, and passes in the current time.

Page 40: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

40

Fragment Shader

uniform float time;

void main()

{

float d = length(gl_FragCoord.xy);

gl_FragColor.r = 0.5*(1.0+sin(0.001*time))*gl_FragCoord.x/d;

gl_FragColor.g = 0.5*(1.0+cos(0.001*time))*gl_FragCoord.y/d;

gl_FragColor.b = gl_FragCoord.z;

gl_FragColor.a = 1.0;

}

(From GLSL Spec) The built-in special variables that are accessible from a fragment shader are intrinsically declared as follows:in vec4 gl_FragCoord;in bool gl_FrontFacing;in float gl_ClipDistance[];out vec4 gl_FragColor; // deprecatedout vec4 gl_FragData[gl_MaxDrawBuffers]; // deprecatedout float gl_FragDepth;

Page 41: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

41

Fragment Shader

uniform float time;

out vec4 gl_FragColor;

void main()

{

float d = length(gl_FragCoord.xy);

gl_FragColor.r = 0.5*(1.0+sin(0.001*time))*gl_FragCoord.x/d;

gl_FragColor.g = 0.5*(1.0+cos(0.001*time))*gl_FragCoord.y/d;

gl_FragColor.b = gl_FragCoord.z;

gl_FragColor.a = 1.0;

}

Fragment shaders output values to the OpenGL pipeline using the built-in variables gl_FragColor, gl_FragData, and gl_FragDepth, unless the discard statement is executed.

Both gl_FragColor and gl_FragData are deprecated; the preferred usage is to explicitly declare these outputs in the fragment shader using the out storage qualifier.

Page 42: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

42

Example

So far, we have limited ourselves to standard graphics

Can we think outside the Frustum?Angel gives one example: Problem is normalizing vectorsHave (x, y, z), and need a normalized versionHe proposes uses a texture map to speed up the

computation (!?!$!!)

Page 43: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

43

Normalize

Store a 3D Texture NormFor each value (x, y, z), store 1/sqrt(x2 + y2 + z2)Take (x, y, z) * T(x, y, z)Issues –

We need to precompute in the CPUThe solution is an estimate, due to aliasing

Page 44: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

44

Example: Voronoi

You need to mail a letter – where is the closest Post Office?

Given a set of points S in the plane (3 space) The Voronoi diagram splits the plane (3 space) into sets of points closest to a member of S.

Page 45: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

45

Voronoi

Page 46: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

46

Example: Voronoi

How can we compute Voronoi Diagrams quickly?They are an important datastructure – much studied http://www.cs.cornell.edu/info/people/chew/oldDelaunay.htmlhttp://www.pi6.fernuni-hagen.de/GeomLab/VoroGlide/index.html.enhttp://www.diku.dk/hjemmesider/studerende/duff/Fortune/

Can we use parallel computation to help?

Page 47: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

47

Example: Voronoi

Can we use parallel computation to help?Hint: Use an additional dimension

Page 48: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

48

Voronoi Computation

Each point in S is given a unique colorIn order to compute the lower envelope, we need to

determine, at each pixel, the fragment with the smallest depth value.

This can be done with a simple depth test. Allow a fragment to pass only if it is smaller than the

current depth buffer value, and update the buffer accordingly.

The fragment that survives has the correct color.

Page 49: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

49

Variable Scope

const: compile time constantuniform: parameter is fixed over a glBegin/glEnd

pairattribute: per-vertex information send from CPU:

coordinates, texture coords, normals, color, …Predefined and user defined

varying: interpolated data that a vertex shader sends to the fragment shaders

Page 50: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

50

toon vertex shader

// simple toon vertex shader

// www.lighthouse3d.com

varying vec3 normal, lightDir;

void main()

{

lightDir = normalize(vec3(gl_LightSource[0].position));

normal = normalize(gl_NormalMatrix * gl_Normal);

gl_Position = ftransform(); // Deprecated... - jdp

}

Page 51: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

51

toon fragment shader

varying vec3 normal, lightDir;

void main()

{

...

if (intensity > 0.98)

color = vec4(0.8,0.8,0.8,1.0);

else if (intensity > 0.5)

color = vec4(0.4,0.4,0.8,1.0);

else if (intensity > 0.25)

color = vec4(0.2,0.2,0.4,1.0);

else

color = vec4(0.1,0.1,0.1,1.0);

gl_FragColor = color;

}

Page 52: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Architectural Perspectives

Page 53: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Projections

How many angles on the corner are the same?none: trimetrictwo: dimetricthree: isometric

Isometric is particularly easy to fake: see next slide

Page 54: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

What is going on?

v

Sim City, Electronic Arts

Orthogonal Isometric ProjectionOrthogonal Isometric Projection

Page 55: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Perspective and Geometry

Where is the eye for each of these elevations?Let's review the geometry of the cubeWhere is the eye for one point, two point, and three point perspective?

Page 56: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Projections

Assume the cube is the set of points such that|x| <= ½|y| <= ½|z| <= ½

Where do we put the eye to see only one face?Where do we put the eye to see two faces?Where do we put the eye for isometric view?How can we rotate that axis to the z-axis?

Page 57: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

57

Perspective Projection

Orthogonal vs Perspective Projection

Page 58: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

58

Perspective Projection

Discovered in Renaissance

Albrecht DurerAlbrecht Durer

Page 59: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

59

Perspective Projection

Page 60: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

60

Perspective Projection

15th century illustration from William of Tyre's Histoire d'Outremer. 15th century illustration from William of Tyre's Histoire d'Outremer.

Page 61: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

61Giotto, Exorcism of the demons at ArezzoGiotto, Exorcism of the demons at Arezzo

Page 62: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

62

Perspective Projection

Pietro Perugino, Christ Handing the Keys to St. PeterPietro Perugino, Christ Handing the Keys to St. Peter

Page 63: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

63 Carpaccio, The Disputation of St StephenCarpaccio, The Disputation of St Stephen

Note that the vanishing point is off the canvas

Page 64: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

64

Perspective Projection

Paolo Uccello, Battle of San RomanoPaolo Uccello, Battle of San Romano

Page 65: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Street painting by Kurt Wenner

Perspective Projection

Page 66: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Defining Perspective

It is often simplest to define Model View transformations in terms of translations, rotations, scaling, etc.

We can also define Projection View this way: move the camera back, rotate to pan over a scene

However, it is most natural to use some special callsTwo parts: position camera, and define perspective

glLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz)

glOrtho(left,right,bottom,top,near,far)glFrustum(left,right,bottom,top,near,far)gluPerpective(fovy, aspect, near, far)

Page 67: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Perspective Projection

glOrtho(left,right,bottom,top,near,far)glFrustum(left,right,bottom,top,near,far)gluPerpective(fovy, aspect, near, far)

Page 68: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Perspective

Angel presents three programs that cover the same territoryHe modifies the Color Cube program as follows

Cube is fixed, but eye and frustum can changeHe uses three different ways to specify the viewing frustumLookAt() and Ortho()LookAt() and Frustum()LookAt() and Perspective()

Page 69: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

69

Variations

// Version 1mat4 p = Ortho(left, right, bottom, top, zNear, zFar);glUniformMatrix4fv( projection, 1, GL_TRUE, p );

// Version 2mat4 p = Frustum(left, right, bottom, top, zNear, zFar);

// Version 3mat4 p = Perspective( fovy, aspect, zNear, zFar );

Page 70: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Current Transformation Matrix

The following are combined to define a 4x4 matrix called the Current Transformation Matrix (CTM)glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_PROJECTION);

We can manipulate them independently, but all vertices go through both

Page 71: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Transformations

OpenGL keeps track of these matrices as part of the stateModel-View (GL_MODELVIEW)Projection (GL_PROJECTION)Texture (GL_TEXTURE) (ignore for now)Color(GL_COLOR) (ignore for now)

Single set of functions for manipulationSelect which to manipulated by

glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_PROJECTION);

CTMvertices vertices

p p’=CpC

Page 72: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Handling Raw Matrix

Can load and multiply by matrices defined in the application programglLoadMatrixf(m)glMultMatrixf(m)

The matrix m is a one dimensional array of 16 elements which are the components of the desired 4 x 4 matrix stored by columns

In glMultMatrixf, m multiplies the existing matrix on the right

We can save the current state with push, restore it with popCan also query the current matrix

double m[16];glGetFloatv(GL_MODELVIEW, m);

Page 73: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Orthographic Projection

Let's define these projections by handWe will look at simple examples before looking at the most

general exampleThe simplest is an orthographic: (x, y, z, 1) (x, y, 0, 1)Singular – sends non-zero items, such as (0, 0, 1, 0) to zero

Singular matrices have a determinate of 0

1 0 0 0

0 1 0 0

0 0 0 0

0 0 0 1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

x

y

z

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

=

x

y

0

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

Page 74: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

74

Pinhole Camera

xp= -x/z/d yp= -y/z/d

Use similar trianges to find projection of point at (x,y,z)

These are equations of simple perspective

zp= d

Page 75: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Review perspective

Look at xz and yz planes

xp =x

z /dyp =

y

z /dz = d

Page 76: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

Perspective Divide

How do we express that with a matrix? Remember that (tx, ty, tz, t) = (z, y, z, 1)

1 0 0 0

0 1 0 0

0 0 1 0

0 0 1/d 0

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

x

y

z

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

=

x

y

z

z /d

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

x

z /dy

z /dd

1

⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥

xp =x

z /dyp =

y

z /dz = d

Page 77: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

77

In practice

Rather than derive a projection matrix for each type of projection, convert all projections to orthogonal projections with default view volume

Allows us to use standard transformations in the pipeline and makes for efficient clipping

Delay projection to preserve z-depth for z-Buffer computation

Page 78: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

78

Orthographic Projection

Convert clipping box to standard cubeTwo steps –

Move center to originT(-(left + right)/2, -(bottom+top)/2, -

(near+far)/2Scale sides

S(2/(left-right), 2/(top-bottom), 2(near-far)P = ST

Page 79: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

79

Orthographic Projection

T(-(left + right)/2, -(bottom+top)/2, -(near+far)/2S(2/(left-right), 2/(top-bottom), 2(near-far)P = ST

2

left − right0 0 0

02

top −bottom0 0

0 02

near − far0

0 0 0 1

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

1 0 0−(left + right)

2

0 1 0−(bottom + top)

2

0 0 1−(near + far)

20 0 0 1

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

P =

2

left − right0 0 −

left + right

left − right

02

top −bottom0 −

top +bottom

top −bottom

0 02

near − far−

near + far

near − far0 0 0 1

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

Page 80: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

80

Perspective Projection

Orthographic vs Perspective

2

left − right0 0 −

left + right

left − right

02

top −bottom0 −

top +bottom

top −bottom

0 02

near − far−

near + far

near − far0 0 0 1

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

2 ⋅near

left − right0 −

left + right

left − right0

02 ⋅near

top −bottom−

top +bottom

top −bottom0

0 0near + far

near − far−

2 ⋅ far ⋅near

near − far0 0 1 0

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

Page 81: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

81

Perspective Projection

Effect on (left, bottom, near)

2 ⋅near

left − right0 −

left + right

left − right0

02 ⋅near

top −bottom−

top +bottom

top −bottom0

0 0near + far

near − far−

2 ⋅ far ⋅near

near − far0 0 1 0

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

left

bottom

near

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

=

near(left − right)

left − rightnear(bottom − top)

top −bottomnear(near − far)

near − farnear

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

=

near

−near

near

near

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

=

1

−1

1

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

Page 82: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

82

z-Buffer

General effect on z

2 ⋅near

left − right0 −

left + right

left − right0

02 ⋅near

top −bottom−

top +bottom

top −bottom0

0 0near + far

near − far−

2 ⋅ far ⋅near

near − far0 0 1 0

⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥

x

y

z

1

⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥

=

...

...z(near + far) − 2 ⋅ far ⋅near

near − farz

⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥

=

...

...z(near + far) − 2 ⋅ far ⋅near

z(near − far)1

⎢ ⎢ ⎢ ⎢ ⎢

⎥ ⎥ ⎥ ⎥ ⎥

Page 83: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

83Z-Buffer

Range for (Zmin, Zmax) = (1, 10)

Range for (Zmin, Zmax) = (0.1, 10)

Uniform distances in z do not give us uniform distances in z'Pick as large a value for near as you can

Page 84: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

84

OpenGL Errors

Finding and fixed problems with OpenGL calls

The manual tells you what to expect

glClear(GLbitfield mask)

The glClear function clears buffers to preset values.

Parameters mask: Bitwise OR operators of masks that indicate the buffers to be cleared. The four masks are as follows.

GL_COLOR_BUFFER_BIT The buffers currently enabled for color writing.

GL_DEPTH_BUFFER_BIT The depth buffer.

GL_ACCUM_BUFFER_BIT The accumulation buffer.

GL_STENCIL_BUFFER_BIT The stencil buffer.

Return Value Returns the following error codes and their conditions.

GL_INVALID_VALUE Any bit other than the four defined bits was set in mask.

GL_INVALID_OPERATION glClear was called between a call to glBegin and the corresponding call to glEnd.

My standard advice is to check the return code for every function call.

Page 85: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

85

gldebug

When you run your program, can pass in command line parameters such as -gldebug

You program must be able to ignore them

main(int argc, char *argv[]){ int i; glutInit(&argc, argv);

-gldebug After processing callbacks and/or events, check if there are any OpenGL errors by calling glGetError. If an error is reported, print out a warning by looking up the error code with gluErrorString.

% ./my_cube_view -gldebug

2009-10-01 10:46:24.067 cube_view[75593:10b] GLUT Warning: GL error: invalid operation

Page 86: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

86

glGetError()

void glGetError(void);The glGetError function returns the value of the error flag. Each detectable

error is assigned a numeric code and symbolic name. When an error occurs, the error flag is set to the appropriate error code value. No other errors are recorded until glGetError is called, the error code is

returned, and the flag is reset to GL_NO_ERROR. If a call to glGetError returns GL_NO_ERROR, there has been no

detectable error since the last call to glGetError, or since OpenGL was initialized.

To allow for distributed implementations, there may be several error flags. If any single error flag has recorded an error, the value of that flag is returned and that flag is reset to GL_NO_ERROR when glGetError is called. If more than one flag has recorded an error, glGetError returns and clears an arbitrary error flag value. If all error flags are to be reset, you should always call glGetError in a

loop until it returns GL_NO_ERROR.

Page 87: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

87

glGetError()

We know there is a problem, but we don't know where it is. We could add a check to every call, or we could sprinkle calls between blocks

of calls that check for an error. For example, let's sprinkle our code with the following

if (glGetError() != GL_NO_ERROR) printf("GL Error: (%s)\n", gluErrorString(glGetError()));

When we run the program, we see the following % ./cube_view GL Error: no error GL Error: no error GL Error: no error GL Error: no error GL Error: no error GL Error: no error

Page 88: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

88

glGetError()

The first call to glGetError returns the error, and clears itif (glGetError() != GL_NO_ERROR)

printf("GL Error: (%s)\n", gluErrorString(glGetError()));

What we should say isGLenum error; if ((error = glGetError()) != GL_NO_ERROR)

printf("GL Error: %s\n", gluErrorString(error));

With this code added, I see the following % ./cube_view GL Error: invalid operation GL Error: invalid operation GL Error: invalid operation…

Page 89: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

89

Define function checkErr

void checkError(char *str) { GLenum error; if ((error = glGetError()) != GL_NO_ERROR)

printf("GL Error: %s (%s)\n", gluErrorString(error), str);

} void polygon(int a, int b, int c , int d {

checkError("Poly 1"); glBegin(GL_POLYGON); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3fv(colors[a]); glVertex3fv(vertices[a]); ...glEnd(); checkError("Poly 2");

}

% ./cube_view GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2)

Page 90: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

90

checkError()

void checkError(char *str) { GLenum error; if ((error = glGetError()) != GL_NO_ERROR)

printf("GL Error: %s (%s)\n", gluErrorString(error), str);

} void polygon(int a, int b, int c , int d {

checkError("Poly 1"); glBegin(GL_POLYGON); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3fv(colors[a]); glVertex3fv(vertices[a]); ...glEnd(); checkError("Poly 2");

}

% ./cube_view GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2) GL Error: invalid operation (Poly 2)

Page 91: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

91

Homework

Pen and Paper – Given line segment, determine if it intersects a line or another line segment.

Project – Create a 3D world, and allow the user to rotate his point of view

Page 92: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

92

Summary

We can offload a great deal of processing to GPUWe cannot depend upon global variables to pass

information aroundHowever, we can augment the standard attributesViewing allows us to change our point of viewPerspective helps make things look more realistic

Page 93: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

93

ResourcesThe OpenGL® Shading Language – The Orange BookSample programs from Angel –

Book examples on my examples pageExamples from his Primer can be found off his webpage

LightHouse tutorialswww.lighthouse3d.com/opengl/glsl/

LightHouse Source www.lighthouse3d.com/opengl/glsl/examples/

OpenGL(R) Shading Language, Randi Rost, John M KessenichThe Cg Tutorial: The Definitive Guide to Programmable Real-Time

Graphics Randima Fernando, Mark KilgardSIGGRAPH GP GPU course

http://gpgpu.org/s2004Journal of Graphics, GPU, and Game tools - http://jgt.akpeters.com/

Page 94: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

94

Gallery

Page 95: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

95

Gallery

Page 96: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

96

Gallery

Page 97: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

97

Gallery

Page 98: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

98

Gallery

Page 99: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

99

Gallery

Page 100: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

100

Gallery

Page 101: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

101

Gallery

Page 102: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

102

Gallery

Page 103: 1 Shaders, Viewing & Perspective CS 234 Jeff Parker.

103

Gallery