Upload
gwen-gregory
View
229
Download
0
Embed Size (px)
DESCRIPTION
ANOTHER LOOK AT THE PIPELINE Vertex Processing Clipping/Assembly Rasterization Fragment Processing OpenGL Application Attributes (ins) Client-side Server-side
Citation preview
CS 4363/6353
SHADERS/GLSL
ANOTHER LOOK AT THE PIPELINE
Vertex Processing
Clipping/Assembly
Rasterization
Fragment Processing
ANOTHER LOOK AT THE PIPELINE
Vertex Processing
Clipping/Assembly
Rasterization
Fragment Processing
OpenGL Application
Attributes (ins)
Client-side
Server-side
ATTRIBUTES• Remember, these are values that are per vertex!
• Denoted with keyword in
• Are read-only
• Maximum of 16 attributes per shader program
• Always stored as a vec4, even if you declare it as a single float!
• Examples:
• Raw vertex positions
• Normals
• Texture coordinates
• Could also be other things?
ANOTHER LOOK AT THE PIPELINE
Vertex Processing
Clipping/Assembly
Rasterization
Fragment Processing
OpenGL Application
Attributes (ins)
Uniforms
Uniforms
UNIFORMS• Uniforms are not individualized
• Apply to all vertices/fragments
• Denoted by the uniform keyword
• Examples:
• Matrices (ModelView, Perspective)
• Light positions
ANOTHER LOOK AT THE PIPELINE
Vertex Processing
Clipping/Assembly
Rasterization
Fragment Processing
OpenGL Application
Attributes (ins)
Uniforms
Uniforms
Texture data
Texture data
TEXTURE DATA• Remember, these are set up in hardware units
• Textures can be in 1, 2 and 3 dimensions
• Can also be in cube maps
• Accessed in the fragment shader using sampler2D
ANOTHER LOOK AT THE PIPELINE
Vertex Processing
Clipping/Assembly
Fragment Processing
OpenGL Application
Attributes (ins)
Uniforms
Uniforms
Texture data
Texture data
outs New vertex positions
ins
GLSL• Must have a minimum of two shaders
• Syntax is similar to C (it has a main)
• Supports functions
• Doesn’t support pointers!
• Has variables similar to C
• bool finished = false;
• int myInt = -6;
• uint = 567u;
• float value = 42.0;
VECTORS• GLSL supports vectors with 2, 3 and 4elements
• vec2, vec3, vec4
• ivec2, ivec3, ivec4
• uvec2, uvec3, uvec4
• bvec2, bvec3, bvec4
• Initialize with a “constructor”
• vec4 color = vec4 (1.0f, 0.0f, 1.0f, 1.0f);
• Common operations
• result = myVec + yourVec;
• myVec += vec4 (1.0f, 0.5f, 0.4f, 0.2f);
• myVec *= 3.0f;
INDIVIDUAL ELEMENTS• Can access individual elements using
• xyzw – typically for positions
• rgba – usually for colors
• stpq – usually for texture coordinates
• … it’s your choice, but you can’t mix them!
• Examples
• myVec.x = 4.0f;
• myVec.xy = vec2 (1.0f, 5.0f);
• myVec.xyz = yourVec.xyz;
• vColor.bgra = vOldColor.rgba; // called “swizzling”
A NOTE ABOUT EFFICIENCY & GOTCHAS• Vector operations are supported by hardware
• Performed all at once!
• Inefficient:
• vPos.x = vPos2.x + 1.0f;
• vPos.y = vPos2.y +3.0f;
• vPos.z = vPos2.z + 2.0f;
• Efficient:
• vPos.xyz = vPos2.xyz + vec3 (1.0f, 3.0f, 2.0f);
• Gotcha:
• If you don’t use an attribute or uniform, OpenGL “optimizes” by removing it!
MATRICES!• Several types in columns and rows:
• mat2x2 (or simply mat2)
• mat3x3 (or mat3)
• mat4x4 (or mat4)
• mat2x3 and mat2x4
• mat3x2 and mat3x4
• mat4x2 and mat4x3
MATRICES• Organized as an array of column vectors
• mMV[3] = vec4(1.0f, 0.0f, 1.0f, 1.0f);
• vec3 myVec = mMV[3].xyz;
• Matrices can be multiplied by other matrices and vectors
• Matrices have one nasty “constructor” and one good one
mat4 theMatrix = mat4 (1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
mat4 theMatrix = mat4(1.0f);
STORAGE QUALIFIERS• in – passed in from a previous stage
• out – going to the next stage
• const – a read-only variable (one that doesn’t change)
• uniform – does not change across vertices
• inout – only used in functions (it’s essentially a pointer)
• in centroid/out centroid – used in multisampled buffers (interpolation)
• noperspective – don’t use perspectively-correct interpolation
• flat – don’t interpolate (colors) at all; declared in both vertex and frag shaders
• smooth – the default interpolation
EXAMPLE
http://wwwx.cs.unc.edu/~sud/courses/236/a6/
Perspectively interpolated noperspective
A SIDE-BY-SIDE COMPARISON• Show the relationship between client code and shader code
• Assume you loaded a sphere, plane, or monkey face…
• numVertices – the number of vertices (duh!)
• vVerts – the position information of each vertex
• vNorms – the normal information of each vertex
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
buffer
Note: buffer “lives” on the graphics card in a nice, two-bedroom loft…
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer (GL_ARRAY_BUFFER, buffer);
buffer
Hey – I’m active now
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer (GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, numVertices*6*sizeof(GLfloat), NULL, GL_STATIC_DRAW);
buffer
Now I know how big I am!
Why 6?
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer (GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, numVertices*6*sizeof(GLfloat), NULL, GL_STATIC_DRAW);
glBufferSubData (GL_ARRAY_BUFFER, 0, numVertices*3*sizeof(GLfloat), vVerts);
glBufferSubData (GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), numVertices*3*sizeof(GLfloat), vNorms);
buffer
Now I’m putting vVerts at the beginning
vVerts
Put vVerts at 0… it’s pretty bigthough…
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer (GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, numVertices*6*sizeof(GLfloat), NULL, GL_STATIC_DRAW);
glBufferSubData (GL_ARRAY_BUFFER, 0, numVertices*3*sizeof(GLfloat), vVerts);
glBufferSubData (GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), numVertices*3*sizeof(GLfloat), vNorms);
buffer
I’m putting vNormals next
vVerts
Put vNormals startingright after that!
It’s pretty big
too…
vNorms
WHAT WE HAVE SO FAR…• We have a buffer with an ID
• That buffer lives on the graphics card
• That buffer is full of vertex position/normal data
• How do we get that info to our shader?
• Immediately after this code, we put the following…
GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition");
#version 150
in vec4 vPosition; // This will be referenced in your OpenGL program!!in vec3 vNormal; // The normal of the vertexout vec4 color; // Out to fragment shader
uniform mat4 p; // This is perpsective matrixuniform mat4 mv; // This is the model-view matrixuniform vec4 light_pos; // This is the light position
void main () {gl_Position = p*mv*vPosition;
vec3 L = normalize (light_pos.xyz);vec3 N = normalize (vNormal);color = vColor*max(0.2f, dot(N, L));
}
GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition");glEnableVertexAttribArray(loc);glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
#version 150
in vec4 vPosition; // This will be referenced in your OpenGL program!!in vec3 vNormal; // The normal of the vertexout vec4 color; // Out to fragment shader
uniform mat4 p; // This is perpsective matrixuniform mat4 mv; // This is the model-view matrixuniform vec4 light_pos; // This is the light position
void main () {gl_Position = p*mv*vPosition;
vec3 L = normalize (light_pos.xyz);vec3 N = normalize (vNormal);color = vColor*max(0.2f, dot(N, L));
}
buffer
Guys! I’m still active, remember?
vVerts vNorms
GLuint loc2 = glGetAttribLocation(shaderProgramID, "vNormal");glEnableVertexAttribArray(loc2);glVertexAttribPointer(loc2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertices*3*sizeof(GLfloat)));
#version 150
in vec4 vPosition; // This will be referenced in your OpenGL program!!in vec3 vNormal; // The normal of the vertexout vec4 color; // Out to fragment shader
uniform mat4 p; // This is perpsective matrixuniform mat4 mv; // This is the model-view matrixuniform vec4 light_pos; // This is the light position
void main () {gl_Position = p*mv*vPosition;
vec3 L = normalize (light_pos.xyz);vec3 N = normalize (vNormal);color = vColor*max(0.2f, dot(N, L));
}
buffer
Tell vNormal where to look in me…
vVerts vNorms
GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition");glEnableVertexAttribArray(loc);glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
GLuint loc2 = glGetAttribLocation(shaderProgramID, "vNormal");glEnableVertexAttribArray(loc2);glVertexAttribPointer(loc2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertices*3*sizeof(GLfloat)));
#version 150
in vec4 vPosition; // This will be referenced in your OpenGL program!!in vec3 vNormal; // The normal of the vertexout vec4 color; // Out to fragment shader
uniform mat4 p; // This is perpsective matrixuniform mat4 mv; // This is the model-view matrixuniform vec4 light_pos; // This is the light position
void main () {gl_Position = p*mv*vPosition;
vec3 L = normalize (light_pos.xyz);vec3 N = normalize (vNormal);color = vColor*max(0.2f, dot(N, L));
}
THE FRAGMENT SHADER• For every vertex shader out, there’s a fragment shader in
• Value is smoothly interpolated from vertex shader
• Fragment shaders have an out as well
• Called “output zero”
• Sent to color buffer
• Represents the color of the fragment
COMPILING AND LINKING SHADERSGLint fShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource (fShaderID, 1, (const GLchar**)&shaderSource1, NULL);
glCompileShader(fShaderID);
GLint vShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource (vShaderID, 1, (const GLchar**)&shaderSource2, NULL);
glCompileShader(vShaderID);
GLuint programID = glCreateProgram(); // KEEP THIS!
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram (programID);
USING/DELETING• To use the shader:
• glUseProgram (GLuint progID);
• Any subsequent draw calls will use that shader
• There are only a limited number of shaders on the graphics card (16)
• When you’re done with one:
• glDeleteShader( GLuint progID);
#version 150
in vec4 vPosition; // This will be referenced in your OpenGL program!!in vec3 vNormal; // The normal of the vertexout vec4 color; // Out to fragment shader
uniform mat4 p; // This is perpsective matrixuniform mat4 mv; // This is the model-view matrixuniform vec4 light_pos; // This is the light position
void main () {gl_Position = p*mv*vPosition;
vec3 L = normalize (light_pos.xyz);vec3 N = normalize (vNormal);color = vColor*max(0.2f, dot(N, L));
}
#version 150
out vec4 fColor;in vec4 color; // from the vertex shader
void main () {fColor = color;
}
A NOTE ABOUT VERSIONS• Version number – minimum version supported
• Version numbers changed!
• OpengGL 3.0 – GLSL version 1.3 (#version 130)
• OpenGL 3.1 – GLSL version 1.4 (#version 140)
• OpenGL 3.2 – GLSL version 1.5 (#version 150)
• OpenGL 3.3 – GLSL version 3.0 (#version 300)
• OpenGL 4.0 – GLSL version 4.0 (#version 400)
UNIFORMS• Persistent across all vertices
• Can’t be marked as in/out
• Can’t be interpolated
• Always read-only
• Find uniform variables using:• glGetUniformLocation (GLuint progID, const GLchar* varName);
SETTING UNIFORMS• Scalars and vectors (glUniformXY – where Y is the data type):
• glUniform1f (GLuint location, GLfloat v0);
• glUniform2f (GLuint location, GLfloat v0, GLfloat v1);
• glUniform3f (GLuint location, GLfloat v0, GLfloat v1, GLfloat v2);
• glUniform4f (GLuint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
• Example:
GLunit lightID = glGetUniformLocation (progID, “light_pos”);
glUniform4f (lightID, light_x, light_y, light_z, 1.0f);
SETTING UNIFORMS• Arrays are similar:
• glUniform1fv (GLuint location, GLuint count, GLfloat* v);
• glUniform2fv (GLuint location, GLuint count, GLfloat* v);
• glUniform3fv (GLuint location, GLuint count, GLfloat* v);
• glUniform4fv (GLuint location, GLuint count, GLfloat* v);
• What’s the difference? Format of glUniformXYv
• X is how many elements are in each array
• count is how many of those arrays you have
• Y is the type
• Example:
GLunit lightID = glGetUniformLocation (progID, “light_pos”);
GLfloat* myLightPosition[4] = {10.0f, 10.0f, 10.0f, 1.0f);
glUniform4fv (lightID, 1, myLightPosition);
SETTING UNIFORMS• Set uniform matrices by their dimension:
• glUniformMatrix2fv (GLunit loc, GLuint count, GLboolean transpose, GLfloat* m);
• glUniformMatrix3fv (GLunit loc, GLuint count, GLboolean transpose, GLfloat* m);
• glUniformMatrix4fv (GLunit loc, GLuint count, GLboolean transpose, GLfloat* m);
• count represents the number of matrices (almost always 1)
• transpose is used to indicate if the matrix is stored in column order
BUILT-IN GLSL FUNCTIONS• Tons of different mathematical functions
• Scalars
• Vectors
• Matrices
• Robust trig functions:
• float x = sin (1.0); // Also have cos, tan, atan, asin…
• vec4 y = sin (vec4(1.0f, 0.5f, 0.25f, 0.0f)); // Overloaded function
• float z = radians (45.0f); // Convert from degrees to radians
• float z = degrees (0.6f); // Convert from radians to degrees
BUILT-IN GLSL FUNCTIONS• Robust exponentials:
• vec2 results = pow (vec2(2, 3), vec2 (2, 2)); // 2^2, 3^2
• log( ) – natural log
• exp( ) - ex
• log2( ) – log base 2
• exp2( ) – 2 to the power of…
• sqrt( )
BUILT-IN GLSL FUNCTIONS• Geometric functions (generic “vec”)
• float length (vec x);
• float distance (vec p0, vec p1);
• float dot (vec x, vec y);
• vec3 cross (vec x, vec y);
• vec normalize (vec x);
• vec reflect (vec I, vec N); // I is incident vector (light/view) and N is normal
• vec refract(vec I, vec N, float eta);
• vec faceForward (vec N, vec I, vec nRef);// if dot(Nref, I) < 0, return N, else return -N
BUILT-IN GLSL FUNCTIONS• Matrices
• transpose( )
• determinant( )
• inverse( )
• outerProduct( )
• Relational functions
• vec lessThan (vec x, vec y); && vec lessThanEqual (vec x, vec y);
• vec greaterThan (vec x, vec y);
• vec equal (vec x, vec y); && vec notEqual (vec x, vec y);
• bool any (bvec x); // returns true if any booleans in x are true
• bool all (bvec x); // returns true if all booleans in x are true
BUILT-IN GLSL FUNCTIONS• Common functions
• abs, sign, floor, ceil, mod, min, max... yeah, yeah…
• trunc(x) – nearest whole number not larger than the absolute value of x
• round(x) – based on 0.5
• roundEven(x) – “returns a value equal to the nearest integer to x.The fractional part of 0.5 will round toward the nearest even integer. For example, both 3.5 and 4.5 will round to 4.0.”
• fract (x) – returns the fractional part
• clamp(x, y, z) – returns x if it’s between y and z, else returns y or z
• mix (x, y, a) – returns the linear blend of x and y, as a varies from 0 to 1
• step (edge, x) – returns 0.0 if x < edge, 1.0f otherwise
• smoothstep (edge0, edge1, x) – 0 if x < edge0, 1 if x > edge1, interpolated otherwise
LAST OF THE BUILT-INS• isnan(x) – true is x is not a number (NAN)
• isinf(x) – returns true is x is +∞ or -∞
• floatBitsToInt(x) – converts floating point values to ints
• intBitstoFloat(x) – converts integers to floating points