Wilf LaLonde @2003 Comp 4002 95.4002 Shaders. Wilf LaLonde @2003 Comp 4002 Shaders Shaders are...
-
Upload
chad-booth -
Category
Documents
-
view
222 -
download
3
Transcript of Wilf LaLonde @2003 Comp 4002 95.4002 Shaders. Wilf LaLonde @2003 Comp 4002 Shaders Shaders are...
Wilf LaLonde @2003Comp 4002
95.400295.4002
Shaders
Wilf LaLonde @2003Comp 4002
ShadersShaders
• Shaders are programs that you can download onto the card
• Can be used for manipulating triangle vertices and pixels (you can modify vertices and pixels but not create them).
A NEW KIND OF SHADER (NOT MUCH IN USE YET)
ALLOW VERTICES TO BE CREATED…
Wilf LaLonde @2003Comp 4002
The Programs are in a C-Like LanguageThe Programs are in a C-Like Language
• Those shaders that modify vertices are called vertex shaders.
• Those shaders that modify pixels are called pixel shaders (or fragment shaders).
• Those shaders that create vertices are called geometry shaders (not discussed any further in these notes).
You can’t just have a vertex shader or a pixel shader. You need both.
Wilf LaLonde @2003Comp 4002
How it worksHow it works
• Given a triangle for the card to draw.• 3 vertex shaders are run each producing
output…; e.g., texture coordinate.
• If there are 10,000 pixels in the triangle, 10,000 pixel shaders are run whose input is an interpolated value of the texture coordinate…; each produces a 1 pixel output…
If anything is a bottleneck, it’s the pixel shader.
Wilf LaLonde @2003Comp 4002
Many Steps To Running a ShaderMany Steps To Running a Shader
compile
compile
create program
attach
attach
link use
glCompileShader
glCompileShader
glAttachShader
source
sourceglAttachShader
glCreateShader glShaderSource
source
source
glCreateShader
sample.fragsample.vert
glShaderSource
glCreateProgram
glLinkProgram glUseProgram
Wilf LaLonde @2003Comp 4002
And a Few Steps To Discarding a ShaderAnd a Few Steps To Discarding a Shader
sample.frag
sample.vert detach
detach
program
glDetachShader
glDetachShader
delete
glDeleteShader
glDeleteShader
delete programglDeleteProgram
delete
Wilf LaLonde @2003Comp 4002
Variables: 3 CategoriesVariables: 3 Categories
uniform
in
out
Globals: can be set permanently and changed any time; accessible by both shaders
Vertex shader: vertex information like position, normal, texture coord. Pixel shader: output of vertex shader
Vertex shader: output to pixel shader. Pixel shader: pixel to draw
Wilf LaLonde @2003Comp 4002
Variables: 3 Categories (Another Viewpoint)Variables: 3 Categories (Another Viewpoint)
sample.frag
sample.vert
uniform
Vertex data: position, texture coordinatesin
out
in
out
Transfer data is interpolated; e.g., texture coordinateGlobals
Transfer data which was interpolated
ONE color
3 choices: smooth, noperspective, flat
Wilf LaLonde @2003Comp 4002
Shader versionsShader versions
• We will be using version 130 which permits access to openGL variables.
• Newer versions eliminate those entirely in favor of variables that are ENTIRELY USER DEFINED…
• Source code for vertex and pixel shaders are in SEPARATE FILES.
Soon, we’ll have to switch to version 140 or 40 which is even newer… Then EVERYTHING HAS TO
BE PASSED VIA USER NAMES
Wilf LaLonde @2003Comp 4002
sample.vertsample.vert
#version 130
//Implied in variables: gl_Vertex, gl_Normal, gl_MultiTexCoord0, gl_MultiTexCoord1, gl_Color…//Matrices available: gl_ModelViewMatrix, gl_ProjectionMatrix//Goal of shader: // 1. To compute gl_Position in projection coordinates.// 2. To pass along information needed by pixel shader; e.g., texure coordinates and color
//The globals…uniform float brightness; //For use by the vertex shader…uniform mat4 unused; //But WHAT IF we wanted to use it…//uniform sampler2D texture; //For use by the pixel shader…
//The information passed along. Note: smooth is default rather than noperspective or flat…out vec2 smooth textureCoordinate; out vec4 smooth pixelColor;
void main () {textureCoordinate = gl_MultiTexCoord0.xy; //From vec4 to vec2…gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * gl_Vertex);pixelColor = vec4 (gl_Color.xyz * brightness, gl_Color.a);
}
All matrices are transposed CONCEPTUALLY
Interpolated for pixel shader
Matrices operate right to left
Wilf LaLonde @2003Comp 4002
sample.fragsample.frag
#version 130
//Implied in variables: gl_Vertex, gl_Normal, gl_MultiTexCoord0, gl_MultiTexCoord1, gl_Color…//Matrices available: gl_ModelViewMatrix, gl_ProjectionMatrix//Goal of shader: // 1. To receive information from vertex shader.// 2. To compute final pixel color
//The globals…//uniform float brightNess; //For use by the vertex shader…uniform sampler2D texture; //For use by the pixel shader…
//The information passed along. Note: smooth is default rather than noperspective or flat…in vec2 smooth textureCoordinate; in vec4 smooth pixelColor;
out vec4 finalColor; //Or special built-in variable gl_FragColor
void main () {vec4 textureColor = texture2D (texture, textureCoordinate);//gl_FragColor = textureColor * pixelColor; finalColor = textureColor * pixelColor;
}
Interpolated for pixel shader
Set up in engine by activating the texture on texture unit 0
Available in version 130
Wilf LaLonde @2003Comp 4002
Arithmetic Data TypesArithmetic Data Types
• float, int, uint, bool.
• vec ,ivec , uvec , bvec ,
• mat2, mat3, mat4, matcr• arrays; e.g., vec4 points [10];
Internally, EVERYTHING is a float…
234
234
234
234
1 0 0 tx
mat43 = 0 1 0 ty
0 0 1 tz
To discard perspective
column
Wilf LaLonde @2003Comp 4002
Texture Data Types are called SAMPLERSTexture Data Types are called SAMPLERS
• sampler1D texture0;• sampler2D texture1; //Standard one• samplerCube texture2; //6 Pictures• sampler2DShadow texture3; //Depth texture• samplerBuffer texture4; //Texture Buffer• sampler2DArray texture5 [3]; //???
There are many more…
Wilf LaLonde @2003Comp 4002
ConversionConversion
• No automatic conversion; use swizzling xyzw or rgba or stpq.
vec4 data0; float data1 = data0.x; vec2 data2 = data0.xy; vec3 data3 = data0.xyz; vec4 data4 = data0.xyzw; //Swizzle not
needed
Swizzle can change the order and duplicate; e.g., data0.xzyy
Wilf LaLonde @2003Comp 4002
Constructors are Used To InitializeConstructors are Used To Initialize
• vec4 color = vec4 (1.0, 1.0, 1.0, 0.5);• vec4 data = vec4 (1.0); //Initializes all to 1.0
• mat4 matrix = mat4 (1.0); //Diagonals 1.0; others 0.0
• mat4 test = {1.0, 0.0, 0.0, 0.0,0.0, 1.0, 0.0, 0.0,0.0, 0.0, 1.0, 0.0,tx, ty, tz, 1.0};
• vec4 translation = test [3]; //Can index columns
Matrices are CONCEPTUALLY columns…
column [0]
column [1]
column [2]
column [3]
Wilf LaLonde @2003Comp 4002
A Huge Library Of FunctionsA Huge Library Of Functions
• Operators: +,-,++,--,*,/,&&,||,<<,>>, …• Functions: radians (degrees), degrees (radians),
sin, cos, tan, asin, acos, atan, pow (x,y), exp (x), log, sqrt, inversesqrt, abs, sign, trunc, round, ceil, min, max, clamp (x,min,max), mix (x,y,t) //lerp
Look them up as you need them…
Wilf LaLonde @2003Comp 4002
Making the Connection From Engine To Shader…Making the Connection From Engine To Shader…
• Need to describe vertex layouts in engine.• Need to initialize uniforms in engine.• Need to activate textures with texture and also
map them to samplers in the engine.• Need to tell the card to now use a pair of
specific shaders…
Let’s consider each case one by one…
Wilf LaLonde @2003Comp 4002
Describing Vertex Layouts in the Engine …Describing Vertex Layouts in the Engine …
void activateVertices () {glBindBuffer (GL_ARRAY_BUFFER, verticesBuffer);long stride = sizeof (GamePoint);long doubleSize = sizeof (double);
glVertexPointer (3, GL_DOUBLE, stride, (void *) (0)); glEnableClientState (GL_VERTEX_ARRAY);glTexCoordPointer (2, GL_DOUBLE, stride, (void *) (3 * doubleSize)); glEnableClientState (GL_TEXTURE_COORD_ARRAY);glNormalPointer (GL_DOUBLE, stride, (void *) (5 * doubleSize));glEnableClientState (GL_NORMAL_ARRAY);
}
This is a version 130 technique (OLD WAY);see faceGroup.h
Wilf LaLonde @2003Comp 4002
Describing Vertex Layouts in the Engine: Step 1Describing Vertex Layouts in the Engine: Step 1
• Lookup the names of the components of your vertex in the vertex shader…; e.g., SUPPOSE YOUR SHADER CONTAINS
in vec4 vertexPosition; in vec2 vertexTextureCoordinate0; in vec3 vertexNormal;
This is a version 140 technique (NEW WAY).
Wilf LaLonde @2003Comp 4002
Describing Vertex Layouts in the Engine: Step 2Describing Vertex Layouts in the Engine: Step 2
void activateVertices (Glint shaderProgram, void *vertices) {long stride = sizeof (GamePoint); const bool no = false; //Don’t normalize… Glint p = shaderProgram;
long index;if ((index = glGetAttribLocation (p, "vertexPosition")) != -1) {
glVertexAttribPointer (index, 3, GL_DOUBLE, no, stride, &vertices->x);
glEnableVertexAttribArray (index);}if ((index = glGetAttribLocation (p, "vertexTextureCoordinate0")) != -1) {
glVertexAttribPointer (index, 2, GL_DOUBLE, no, stride, &vertices->tx);
glEnableVertexAttribArray (index);}if ((index = glGetAttribLocation (p, "vertexNormal")) != -1) {
glVertexAttribPointer (index, 3, GL_DOUBLE, no, stride, &vertices->nx);
glEnableVertexAttribArray (index);}}
a component is a vec4
how much of a component to use…
Wilf LaLonde @2003Comp 4002
Initializing Uniforms in the Engine …Initializing Uniforms in the Engine …
void initializeGlobals (Glint shaderProgram) {//Recall: uniform float brightness; //For use by the vertex shader…//Recall: uniform mat4 unused; Glint p = shaderProgram;
long index;if ((index = glGetUniformLocation (p, "brightness")) != -1) {
float brightness = 0.8; glUniform1f (index, brightness); //long howMany = 10; //If we had declared uniform float brightness
[10];//glUniform1f (index, howMany, brightness); //Array version…
if ((index = glGetUniformLocation (p, “unused")) != -1) {const bool noTranspose = GL_FALSE;FloatTransformation transformation =
Transformation::Identity.asFloat(); glUniformMatrix4fv (index, 1, noTranspose, &transformation);}
}
a component is a vec4
how much of a component to use…; 1, 2, 3, or 4.
how many transformations
Needs float transformations
Wilf LaLonde @2003Comp 4002
Activating Textures/Samplers in the Engine …Activating Textures/Samplers in the Engine …
• Textures need to be activated in the normal way…e.g., assuming multiple texture coord…
glActiveTexture (GL_TEXTURE0); //or 1, 2, ..
glBindTexture (textureHandle);
glEnable (GL_TEXTURE_2D); //Ignored
• Tell the shader which texture unit to use…long index;if ((index = glGetUniformLocation (p, “texture")) != -1) { glUniform1i (index, 0);|} texture unit
Wilf LaLonde @2003Comp 4002
Telling the Card To Use A Particular Shader…Telling the Card To Use A Particular Shader…
glUseProgram (shaderProgram);
Wilf LaLonde @2003Comp 4002
DemosDemos
Demos
Wilf LaLonde @2003Comp 4002
“simple” VERTEX Shader (“simple.vert”)“simple” VERTEX Shader (“simple.vert”)
#version 130
//Implied in variables: gl_Vertex, gl_Normal, gl_MultiTexCoord0, gl_MultiTexCoord1, gl_Color…
//Matrices available: gl_ModelViewMatrix, gl_ProjectionMatrix, …
uniform float brightness; //For use by the vertex shader…
//The information passed along. Note: smooth is default rather than noperspective or flat…
out vec2 textureCoordinate;
out vec4 pixelColor;
void main () {
textureCoordinate = gl_MultiTexCoord0.xy; //From vec4 to vec2…
gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
pixelColor = vec4 (gl_Color.xyz * brightness, gl_Color.a);
}
MUST transform position
pass through via out
Wilf LaLonde @2003Comp 4002
“simple” PIXEL Shader (“simple.frag”)“simple” PIXEL Shader (“simple.frag”)
#version 130
uniform sampler2D texture; //For use by the pixel shader…
in vec2 textureCoordinate;
in vec4 pixelColor;
out vec4 finalColor; //Or special built-in variable gl_FragColor
void main () {
vec4 textureColor = texture2D (texture, textureCoordinate);
finalColor = textureColor * pixelColor;
}
MUST output color
pass through via in
Wilf LaLonde @2003Comp 4002
“diffuse” VERTEX Shader (“diffuse.vert”)“diffuse” VERTEX Shader (“diffuse.vert”)
#version 130
uniform vec3 lightDirection;
out vec3 lightDirectionInCameraSpace; out vec3 normalInCameraSpace;
out vec2 textureCoordinate; out vec4 pixelColor; //Like before…
void main () {
//Convert the normal to camera space and pass along
//with the camera light direction also in camera space.
mat3 rotationOnly = mat3 (gl_ModelViewMatrix);
lightDirectionInCameraSpace = lightDirection;
normalInCameraSpace = rotationOnly * gl_Normal; //inverse transpose…
textureCoordinate = gl_MultiTexCoord0.xy; //From vec4 to vec2…
gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
pixelColor = gl_Color;
}
MUST transform position
pass through via out
Should have used
Wilf LaLonde @2003Comp 4002
“diffuse” PIXEL Shader (“diffuse.frag”)“diffuse” PIXEL Shader (“diffuse.frag”)
#version 130
uniform sampler2D texture;
in vec3 lightDirectionInCameraSpace; in vec3 normalInCameraSpace;
in vec2 textureCoordinate; in vec4 pixelColor; //Like before…
out vec4 finalColor; //Or special built-in variable gl_FragColor
void main () {
vec4 textureColor = texture2D (texture, textureCoordinate);
vec4 unlitColor = textureColor * pixelColor; //Like before but renamed…
vec3 normalVector = normalize (normalInCameraSpace);
vec3 lightVector = lightDirectionInCameraSpace; //It's constant...
//Dot product gives 0 when 90 degrees, maximum when 0 degrees...
float diffuse = dot (normalVector, lightVector);
finalColor = unlitColor * diffuse;
}
diffuse scales color
pass through via in
Wilf LaLonde @2003Comp 4002
“specular” VERTEX Shader (“specular.vert”)“specular” VERTEX Shader (“specular.vert”)
#version 130
SAME AS “diffuse.vert”
Wilf LaLonde @2003Comp 4002
“specular” PIXEL Shader (“specular.frag”)“specular” PIXEL Shader (“specular.frag”)
#version 130
//Variables SAME AS “Diffuse” shader
void () {
vec4 textureColor = texture2D (texture, textureCoordinate);
vec4 unlitColor = textureColor * pixelColor;
vec3 normalVector = normalize (normalInCameraSpace);
vec3 lightVector = lightDirectionInCameraSpace; //It's constant...
vec3 eyeVector = vec3 (0.0, 0.0, 1.0); //NEW NEW
float diffuse = dot (normalVector, lightVector);
vec3 halfAngle = normalize (eyeVector + lightVector); //NEW NEW
float specular = max (dot (normalVector, halfAngle), 0.0); //NEW NEW
finalColor =
unlitColor * diffuse +
unlitColor * (4.0 * pow (specular, 32.0));
}
Wilf LaLonde @2003Comp 4002
“wobbler” VERTEX Shader (“wobbler.vert”)“wobbler” VERTEX Shader (“wobbler.vert”)
#version 130
SAME AS “specular.frag” but changed how position is computed
uniform float time; //To control the sin wave…
//Compute a modified vertex before transforming it...
float timeFrequency = 8.0; float spaceFrequency = 4.0;
float amount = 0.5 * (0.75 + sin (time * timeFrequency +
(gl_Vertex.x + gl_Vertex.z) * spaceFrequency));
vec4 position = vec4 (
gl_Vertex.xyz + gl_Normal * amount * 0.215,
gl_Vertex.w);
Wilf LaLonde @2003Comp 4002
“wobbler” PIXEL Shader (“wobbler.frag”)“wobbler” PIXEL Shader (“wobbler.frag”)
#version 130
SAME AS “specular.frag”