Transcript Document
OpenGL Shading Language (GLSL)
OpenGL Rendering Pipeline
Vertex Shader
Vertex transformation
Normal transformation
& normalization
Texture coordinate
generation &
transformation
Per-vertex lighting
Geometry Shader
Add/remove primitives
Add/remove vertices
Edit vertex position
Supported by OpenGL
Extension(Glew 1.4+) or
DX10
Fragment (pixel) Shader
Operations on
interpolated values
Texture access
Texture application
Fog
Color sum
What can we do with shader?
Without shader
With vertex and pixel shader
Per-vertex lighting (Gouraud Shading), …
Per-pixel lighting (Phong Shading), …
With geometry shader
Level of Detail, Subdivision, …
Qualifiers in pipeline
(x,y,z)
attribute
uniform
(x’,y’,z’)
Vertex
Shader
rasterizer
varying
varying
Fragment
Shader
Buffer Op…
Qualifiers
Used to management the input and output of
shaders.
attribute
uniform
Communicate frequently changing variables from the
application to a vertex shader.
Communicate infrequently changing variables from the
application to any shader.
varying
Communicate interpolated variables from a vertex shader
to a fragment shader
Qualifiers in pipeline NEW!
(x,y,z)
attribute
Vertex
Shader
Geometry
Shader
varying in
uniform
rasterizer
varying out
Fragment
Shader
Vertex Shader
Fragment Shader
Geometry Shader
Vertex Color
Vertex Coord.
Resterization Info.
gl_FrontColorIn[gl_VerticesIn];
gl_BackColorIn[gl_VerticesIn];
gl_FrontSecondaryColorIn[gl_VerticesIn];
gl_BackSecondaryColorIn[gl_VerticesIn];
gl_FogFragCoordIn[gl_VerticesIn];
gl_TexCoordIn[gl_VerticesIn][];
gl_PositionIn[gl_VerticesIn];
gl_PointSizeIn[gl_VerticesIn];
gl_ClipVertexIn[gl_VerticesIn];
Geometry
processor
Number of Vertices
gl_VerticesIn
Color
gl_FrontColor;
gl_BackColor;
gl_FrontSecondaryColor;
gl_BackSecondaryColor;
gl_FogFragCoord;
Coord.
gl_Position
gl_TexCoord[];
GLSL Language Definition
Data Type Description
int
float
bool
vec2
vec3
vec4
mat2
mat3
mat4
Integer
Floating-point
Boolean (true or false).
Vector with two floats.
Vector with three floats.
Vector with four floats.
2x2 floating-point matrix.
3x3 floating-point matrix.
4x4 floating-point matrix.
Vector
Vector is like a class
You can use following to access
.r .g .b .a
.x .y .z .w
.s .t .p .q
Example:
vec4 color;
color.rgb = vec3(1.0 , 1.0 , 0.0 ); color.a = 0.5
or color = vec4(1.0 , 1.0 , 0.0 , 0.5);
or color.xy = vec2(1.0 , 1.0); color.zw =vec2(0.0 , 0.5);
Addition data type : Texture
Sampler
sampler{1,2,3}D
Texture unit to access the content of texture.
sampler*DShadow
sampler{1,2,3}D
sampler{1,2}DShadow
samplerCube
The depth texture for shadow map.
samplerCube
The cube map.
Addition data type
struct, array
Similar to C.
No union, enum, class
Phong Shading
Use varying variable to save the vertex
normal or other information.
Compute the Phong lighting in pixel
shader with the information.
Vertex Shader Code Example
varying vec3 normal, lightDir, eyeDir;
void main()
{
normal = gl_NormalMatrix * gl_Normal;
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
lightDir = vec3(gl_LightSource[0].position.xyz - vVertex);
eyeDir = -vVertex;
}
gl_Position = ftransform();
Fragment Shader Code Example
varying vec3 normal, lightDir, eyeDir;
void main (void)
{
vec4 final_color =
(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
(gl_LightSource[0].ambient * gl_FrontMaterial.ambient);
vec3 N = normalize(normal);
vec3 L = normalize(lightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * lambertTerm;
}
}
vec3 E = normalize(eyeDir);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), gl_FrontMaterial.shininess );
final_color += gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
gl_FragColor = final_color;
Result
OpenGL Gouraud Shading
GLSL Phong Shading
Geometry Shader
It can change the primitive.
Add/remove primitives
Add/remove vertices
Edit vertex position
Application
Geometry Shader Example Code
void main(void)
{
int i;
for(i=0; i< gl_VerticesIn; i++){
gl_Position = gl_PositionIn[i];
EmitVertex();
}
EndPrimitive();
for(i=0; i< gl_VerticesIn; i++){
gl_Position = gl_PositionIn[i];
gl_Position.xy = gl_Position.yx;
EmitVertex();
}
EndPrimitive();
}
Result
Original input primitive
Output primitive
New input primitives
GL_LINES_ADJACENCY_EXT
GL_LINE_STRIP_ADJACENCY_EXT
GL_TRIANGLES_ADJACENCY_EXT
GL_TRIANGLE_STRIP_ADJECENCY_EXT
Applications
Applications
Use GLSL in OpenGL
You need those head and library files
glew.h
wglew.h
glew32.lib
glew32s.lib
glew32.dll
Use the shader code in C/C++
Initialize the shader.
Use the shader you made.
Draw what you want.
Shader Initialization
Part of Example Code (C++)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("GPU");
.
.
.
glewInit();
setShaders();
glutMainLoop();
return 0;
}
void setShaders()
{
//a few strings
// will hold onto the file read in!
char *vs = NULL, *fs = NULL, *gs = NULL;
//First, create our shaders
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
g = glCreateShader(GL_GEOMETRY_SHADER_EXT);
//Read in the programs
vs = textFileRead("../GeometryShader/ShaderCode/shader.vert");
fs = textFileRead("../GeometryShader/ShaderCode/shader.frag");
gs = textFileRead("../GeometryShader/ShaderCode/shader.geom");
//Setup a few constant pointers for below
const char * ff = fs;
const char * vv = vs;
const char * gg = gs;
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
glShaderSource(g, 1, &gg, NULL);
free(vs);free(fs);free(gs);
glCompileShader(v);
glCompileShader(f);
glCompileShader(g);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glAttachShader(p,g);
glProgramParameteriEXT(p,GL_GEOMETRY_INPUT_TYPE_EXT,GL_LINES);
glProgramParameteriEXT(p,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_LINE_STRIP);
int temp;
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp);
glProgramParameteriEXT(p,GL_GEOMETRY_VERTICES_OUT_EXT,temp);
glLinkProgram(p);
glUseProgram(p);
}
Send texture to shader
Bind the texture
Get location of the variable in shader
Set the value
Get location
Glint glGetUniformLocationARB(GLhandleARBprogram,
const GLcharARB *name)
– Return an integer to represent the location of a specific uniform
variable.
– name is the name of the uniform variable in the shader.
– The location of a variable is assigned in link time, so this function
should be called after the link stage.
Set value
Following functions are used to assign values for uniform variables
– Void glUniform{1,2,3,4}{f,i}ARB(Glint location, TYPE v)
– Void glUniform{1,2,3,4}{f,i}vARB(Glint location, Gluint count,
TYPE v)
– Void glUniformMatrix{2,3,4}fvARB(Glint location,GLuint count,
GLboolean transpose, const GLfloat *v)
location is the value obtained using glGetUniformLocationARB().
v is the value to be assigned.
Texture Mapping Vertex Shader Code
void main()
{
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
gl_Position = ftransform();
}
Texture Mapping Pixel Shader Code
uniform sampler2D colorTexture;
void main (void)
{
gl_FragColor = texture2D(colorTexture,gl_TexCoord[0].xy).rgba;
}
Texture Mapping C++ Code
glUseProgramObjectARB(MyShader);
glActiveTextureARB( GL_TEXTURE0_ARB );
glBindTexture(GL_TEXTURE_2D, texObject[0]);
GLint location = glGetUniformLocationARB(MyShader, "colorTexture");
if(location == -1)
printf("Cant find texture name: colorTexture\n");
else
glUniform1iARB(location, 0);
int i,j;
for (i=0;i < object->fTotal;i++){
glBegin(GL_POLYGON);
for (j=0;j<3;j++){
glMultiTexCoord2fv(GL_TEXTURE0_ARB,
object->tList[object->faceList[i][j].t].ptr);
glNormal3fv(object->nList[object->faceList[i][j].n].ptr);
glVertex3fv(object->vList[object->faceList[i][j].v].ptr);
}
glEnd();
}
glutSwapBuffers();
glutPostRedisplay();
}
Result 2