Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL...

27
CITS3003 Graphics & Animation Lecture 5: Vertex and Fragment Shaders-1 E. Angel and D. Shreiner: Interactive Computer Graphics 6E © Addison-Wesley 2012

Transcript of Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL...

Page 1: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

CITS3003 Graphics & Animation

Lecture 5:Vertex and Fragment Shaders-1

E. Angel and D. Shreiner: Interactive Computer Graphics 6E © Addison-Wesley 2012

Page 2: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Objectives

• The rendering pipeline and the shaders

• Data types, qualifiers, built-in variables, and functions in shaders

• Applications that can be done on– Vertex shader

– Fragment shader

• Vertex and fragment shaders examples

• How the application program and vertex shader work together

2

Page 3: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

GLSL – A Quick Review

• OpenGL Shading Language

• Part of OpenGL 2.0 and up

• High level C-like language

• New data types are provided, e.g.o Matrices

o Vectors

• As of OpenGL 3.1, application programs must provide shaders (as no default shaders are available)

3

Page 4: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Rendering Pipeline and the shaders

Where the vertex and fragment shaders are on the rendering pipeline:

• The goal of the vertex shader is to provide the final

transformation of mesh vertices to the rendering pipeline.

• The goal of the fragment shader is to provide the colour to

each pixel in the frame buffer.

4

application

program display

(Vertex shader) (Fragment shader)

Page 5: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Data Types in Shaders

• C types: int, float, bool• Vectors:

– vec2, vec3, vec4;– Also int (ivec) and boolean (bvec)

• Matrices: mat2, mat3, mat4– Stored by columns– Standard referencing m[row][column]

• C++ style constructors– vec2 a = vec2(3.0, 2.0);– vec3 b = vec3(a, 1.0);

Each element is a float

5

Page 6: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Pointers

• There are no pointers in GLSL

• We can use C structs which can be copied back from functions

• Because matrices and vectors are basic types, they can be passed into and output from GLSL functions, e.g.

mat3 func(mat3 a);

6

Page 7: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

GLSL Qualifiers• GLSL has many of the same qualifiers such as const as C/C++

• In GLSL, we need other qualifiers due to the nature of the rendering pipeline

• Qualifiers that can be used in shader programs (GLSL code) include:– attribute, uniform, varying (these are storage qualifiers)

– highp, medium, lowp, precision (these are precision qualifiers)

– in, out (these are parameter qualifiers)

• We consider variables that can changeo Once per primitive

o Once per vertex

o Once per fragment

o At any time in the application

• Reminder: vertex attributes are interpolated by the rasterizer into fragment attributes

7

Page 8: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Storage Qualifiers

Page 9: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Qualifier Constant

• The qualifier const is used the same as in Java. It specifies that the value

assigned to a variable is constant and cannot be changed. The variable is

read only. Here are a legal and illegal statement.

// a vector assigned a value const

vec4 point = vec4(1.0, 2.0, 3.0, 1.0);

// illegal statement because the variable must be assigned a value

const float time;

• The qualifier const is used for variables that are compile-time constants or

for function parameters that are read-only.

9

Page 10: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifier attribute• The qualifier attribute is used to declare variables that are shared

between a vertex shader and the application program; typically, vertex coordinates passed to the vertex shader, e.g.,

attribute vec4 vPosition;

• Vertex attributes are used to specify per vertex data. They typicallyprovide data such as the object space position, the normaldirection and the texture coordinates of a vertex.

• Variables declared using the attribute qualifier are not changeablein the vertex shader, i.e., they are read only

• Variables declared using this qualifier must be initialized in the application program.

10

display

(Vertex shader) (Fragment shader)

application

program

Attribute

Page 11: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifier uniform• The qualifier uniform is used to declare variables that are shared

between a shader and the application program.

• Variables declared using this qualifier can appear in the vertex shader and the fragment shader and they must have a global scope. Since both shaders share the same name space, if a uniform variable is used in both shaders, its declaration must be identical in both.

11

display

(Vertex shader) (Fragment shader)

application

program

Uniform

Page 12: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifier uniform (cont.)

• uniform variables are used to describe global properties that affect the scene to be rendered, e.g. projection matrix, light source position, etc. They can be used to describe properties (e.g., colour, materials) of the object. E.g.,

uniform mat4 projection;uniform float temperature;

• Similar to the qualifier attribute, variables declared as uniform are not changeable within the vertex shader or the fragment shader. However, their values can change in the application program. For each frame to be rendered, their new values are passed to the shader(s).

12

Page 13: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifier varying• The qualifier varying is used to declare variables that are

shared between the vertex shader and the fragment shader.

• varying variables are used to store data calculated in the vertex shader and to pass down to the fragment shader. Again, because of the sharing of name space of the two shaders, varying variables must be declared identically in both shaders.

13

display

(Vertex shader) (Fragment shader)

application

program

Varying

Page 14: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifier varying (cont.)

• The varying qualifier can only be used with floating point scalar, floating point vectors and (floating point) matrices as well as arrays containing these types.

• Example: the vertex shader can compute the colour of the incoming vertex and then pass the value to the fragment shader for interpolation. In both shaders:

varying vec4 colour;

14

Page 15: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Precision Qualifiers

Page 16: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifiers highp, mediump, lowp, and precision

• The highp, mediump, and lowp qualifiers are used tospecify the highest, medium, and lowest precisionavailable for a variable. All these qualifiers can appear inthe vertex and fragment shaders.

• In the fragment shader, the precision qualifier mustprecede the three qualifiers above. e.g.

uniform mediump vec4 lightPos;

precision lowp vec3 indices;

• In the vertex shader the use of a precision qualifier isoptional. If no qualifier is given all variables are of highestprecision. In the fragment shader a precision qualifier hasto be used when declaring a variable unless a defaultprecision has been defined for the specific type. 16

Page 17: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifiers highp, mediump, lowp, and precision

• The default precision for int, float, and vectors of these types is highp.

• The actual range corresponding to a precision qualifier isdependent on the specific application.

• Using a lower precision might have a positive effect onperformance (frame rates) and power efficiency but might alsocause a loss in rendering quality. The appropriate trade-off canonly be determined by testing different precisionconfigurations.

17

Page 18: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Parameter Qualifiers

Page 19: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifiers in, out & inout• The qualifier in is used to mark a parameter as read-only

when a function is declared.

• The qualifier out is used to mark a parameter as write-only

when a function is declared.

• The qualifier inout is used to mark a parameter as read-write

when a function is declared.

int newFunction(in bvec4 aBvec4, // read-only

out vec3 aVec3, // write-only

inout int aInt); // read-write

• The above function declaration shows the three possible

parameter qualifiers. The usage of the read-only qualifier is

not necessary since this is the default if no qualifier is

specified.

19

Page 20: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

The Qualifiers in and out

• The in and out qualifiers supersede the attribute and varying qualifiers in GLSL version 4.20 onward:

– attribute is replaced by in in the vertex shader

– varying in the vertex shader is replaced by out

– varying in the fragment shader is replace by in

20

Page 21: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Built-in variables in shaders• gl_Position

o Its value must be defined in the vertex shader

in vec4 vPosition;

void main()

{

gl_Position = vPosition;

}

• The input vertex’s location is given by the four-dimensionalvector vPosition whose specification includes the keyword into signify that its value is input to the shader when the shaderis initiated.

• There is one special state variable in our shader: gl_Position,which is the position that will be passed to the rasterizer andmust be output by every vertex shader. Because gl_Position isknown to OpenGL, we need not declare it in the shader. 21

Page 22: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Built-in variables in shaders

• gl_FragColor

o Used only on the Mac (in Lab2.03)

o Its value must be defined in the fragment shader

• Each invocation of the vertex shader outputs a vertex

• Each fragment invokes an execution of the fragment shader.

• each execution of the fragment shader must output a color for the fragment

void main()

{

gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);

} (R, G, B, Opacity)

22

(Vertex shader) (Fragment shader)

Page 23: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Operators and Functions

• Standard C functionso Trigonometric

o Arithmetic

o Normalize, reflect, length

• Overloading of vector and matrix typesmat4 A;

vec4 b, c, d;

c = b*A; // not implemented in Angel.h

d = A*b; // a column vector stored as a 1d array

23

Page 24: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

GLSL Functions : Examples

• float length(TYPE x) %TYPE is float, vec2, vec3, OR vec4

• float distance(TYPE x)

• TYPE normalize(TYPE x)

• Other examples are dot, cross, reflect, refract, faceforward

• If you are performing an operation in GLSL that is somewhat graphics specific, check the documentation if there is an inbuilt function for it

Page 25: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Swizzling and Selection

• Can refer to array elements by their indices using [] or by selection operator (.) with – x, y, z, w % 3D coordinates and perspective scale

– r, g, b, a % Color values and opacity

– s, t, p, q % texture coordinates (lecture 18, 19)

– vec4 m;

– m[2], m.b, m.z, and m.p are the same

• Swizzling operator lets us manipulate components easily, e.g.,vec4 a;

a.yz = vec2(1.0, 2.0);

vec4 newColour = v.bgra; // swap red and blue

25

Page 26: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

Swizzling with Matrices

• Swizzling does not work with matrices. You can instead access a matrix's fields with array syntax:

mat3 theMatrix;theMatrix[1] = vec3(3.0, 3.0, 3.0); // Sets the 2nd columntheMatrix[2][0] = 16.0; // Sets the 1st entry of 3rd column

• However, the result of the first array accessor is a vector, so you can swizzle that:

mat3 theMatrix;theMatrix[1].yzx = vec3(3.0, 1.0, 2.0);

Page 27: Lecture 5: Vertex and Fragment Shaders-1 · Lecture 5: Vertex and Fragment Shaders-1 ... • GLSL has many of the same qualifiers such as constas C/C++ • In GLSL, we need other

References

“Interactive Computer Graphics – A Top-Down Approach with Shader-Based OpenGL” by Edward Angel and Dave Shreiner, 6th Ed, 2012

• Sec2. 2.8.2-2.8.5 The Vertex Shader …The InitShaderFunction

A good reference on OpenGL shaders: http://antongerdelan.net/opengl/shaders.html