400 likes | 617 Views
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
E N D
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 • Per-vertex lighting (Gouraud Shading), … • With vertex and pixel shader • Per-pixel lighting (Phong Shading), … • With geometry shader • Level of Detail, Subdivision, …
Qualifiers in pipeline (x,y,z) (x’,y’,z’) Vertex Shader FragmentShader attribute rasterizer Buffer Op… varying varying uniform
Qualifiers • Used to management the input and output of shaders. • attribute • Communicate frequently changing variables from the application to a vertex shader. • uniform • 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) Geometry Shader Vertex Shader FragmentShader attribute rasterizer varying in varying out uniform
Geometry Shader Resterization Info. gl_PointSizeIn[gl_VerticesIn]; gl_ClipVertexIn[gl_VerticesIn]; Vertex Color gl_FrontColorIn[gl_VerticesIn]; gl_BackColorIn[gl_VerticesIn]; gl_FrontSecondaryColorIn[gl_VerticesIn]; gl_BackSecondaryColorIn[gl_VerticesIn]; gl_FogFragCoordIn[gl_VerticesIn]; Vertex Coord. gl_TexCoordIn[gl_VerticesIn][]; gl_PositionIn[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 Integer • float Floating-point • bool Boolean (true or false). • vec2 Vector with two floats. • vec3 Vector with three floats. • vec4 Vector with four floats. • mat2 2x2 floating-point matrix. • mat3 3x3 floating-point matrix. • mat4 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 • sampler{1,2}DShadow • samplerCube • sampler{1,2,3}D • Texture unit to access the content of texture. • sampler*DShadow • 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
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.
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(); }