shaders in opengl marshall hahn. introduction to shaders in opengl in this talk, the basics of...
Post on 17-Jan-2016
238 Views
Preview:
TRANSCRIPT
Shaders in OpenGL
Marshall Hahn
Introduction to Shaders in OpenGL
In this talk, the basics of OpenGL Shading Language will be covered. This includes topics such as:
vertex shaders, fragment shaders, and how they communicate
useful built-in functions and datatypes an example shader that implements bump
mapping how to compile, initialize and activate a shader
OpenGL 1.5
Per-Vertex Operations
GeometryVertices
Primitive AssemblyProcessed
VerticesPrimitives
Primitive Processing
Primitive Processing
RasterizationProcessed Primitives
Per-Fragment Operations Fragments
Fragment Processing Processed
Fragments
Pix
els
Frame Buffer
Texture Memory
OpenGL 2.0
Per-Vertex Operations
GeometryVertices
Primitive AssemblyProcessed
VerticesPrimitives
Primitive Processing
Primitive Processing
RasterizationProcessed Primitives
Per-Fragment Operations Fragments
Fragment Processing Processed
Fragments
Pix
els
Frame Buffer
Texture Memory
OpenGL Shading Language (GLSL) A C-based language, has similar syntax and flow
control a little more restrictive in some areas
Functions: return by value, pass by value
Has special built-in variables for input\output. Their names always begin with gl_
Has built-in datatypes for matrices and vectors Useful built-in functions: dot, cos, sin, mix, …
OpenGL Shading Language (GLSL): Swizzling The normal structure-member selector (.) is also used to SWIZZLE
components of a vector: select or rearrange components by listing their names after the swizzle operator (.)
vec4 v4; v4.rgba; // is a vec4 and the same as just using v4, v4.rgb; // is a vec3, v4.b; // is a float, v4.xy; // is a vec2, v4.xgba; // is illegal - the component names do not come from // the
same set. The component names can be out of order to rearrange the
components, or they can be replicated to duplicate the components:
The Three Shader Variable Types
Uniform variables: can be changed once per primitive uniform bool bumpon;
Attribute variables: can be changed anytime, they represent attributes that are associated with vertices attribute vec3 tangentVec;
Varying variables: are used communicate between vertex shader and fragment shader. They are automatically interpolated across the polygon. varying vec3 lightVec;
Normal Maps An image where each pixel
represents a normal: R -> x, G -> y, B -> z
Each normal is perturbed a small amount, so normal maps tend to be “bluish” in colour
R, G, and B each range from 0.0 to 1.0
N.x = ( R – 0.5 ) * 2.0, …
Normal Mapping using Tangent Space Np is in tangent space, L and V are in WCS
So we build a frame at the P using N, T (tangent) and N x T
We then transform L and V into this frame
Normal Mapping using Tangent Space
Suppose we have two points: S in Tangent Space and O in World Space
This is the transformation we need:
Normal Mapping Vertex Shader1. uniform bool bumpon;2. attribute vec3 tangentVec;3. varying vec3 lightVec;4. varying vec3 eyeVec;5.6. void main (void)7. {8. vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;9.10. gl_Position = ftransform();11. gl_TexCoord[0] = gl_MultiTexCoord0;//texture mapping stuff12.13. vec3 orgLightVec = ( gl_LightSource[0].position.xyz - ecPosition.xyz);14.15. vec3 n = normalize(gl_NormalMatrix * gl_Normal);16. vec3 t = normalize(gl_NormalMatrix * tangentVec);17. vec3 b = cross(n, t);18.19. lightVec.x = dot( orgLightVec, t);20. lightVec.y = dot( orgLightVec, b);21. lightVec.z = dot( orgLightVec, n);22.23. vec3 position = -ecPosition.xyz;24. eyeVec.x = dot( position, t);25. eyeVec.y = dot( position, b);26. eyeVec.z = dot( position, n); 27. }
Normal Mapping Fragment Shader1. uniform bool bumpon;2. uniform sampler2D normalMap;//must initialize with texture unit integer3. varying vec3 lightVec;4. varying vec3 eyeVec;5.6. void main (void) 7. {8. vec3 N = vec3(0.0, 0.0, 1.0);9. if( bumpon ) N = normalize( ( (texture2D(normalMap, gl_TexCoord[0].xy).xyz) - 0.5) * 2.0 );10.11. vec3 L = normalize(lightVec);12. vec3 V = normalize(eyeVec);13. vec3 R = reflect(L, N);14.15. float pf = pow( dot(R, V), gl_FrontMaterial.shininess );16.17. vec4 GlobalAmbient = gl_LightModel.ambient;18. vec4 Ambient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;19. vec4 Diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * dot(N, L);20. vec4 Specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pf;21.22. vec4 color1 = GlobalAmbient + Ambient + Diffuse;23. vec4 color2 = Specular;24.25. gl_FragColor = clamp( color1 + color2, 0.0, 1.0 );26. }
GLEE(GL Easy Extension library)
GLee (GL Easy Extension library) is a free cross-platform extension loading library for OpenGL
It provides seamless support for OpenGL functions up to version 2.1 and over 360 extensions
http://elf-stone.com/glee.php Microsoft’s OpenGL API only supports up to
OpenGL 1.1
Compilationchar* vertSrc = readShaderToString(vertShader);char* fragSrc = readShaderToString(fragShader);
vs = glCreateShader(GL_VERTEX_SHADER);fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vs, 1, &vertSrc, NULL);glShaderSource(fs, 1, &fragSrc, NULL);
glCompileShader(vs);printOpenGLError(); // Check for OpenGL errorsglGetShaderiv(vs, GL_COMPILE_STATUS, &vertCompiled);printShaderInfoLog(vs);
glCompileShader(fs);printOpenGLError(); // Check for OpenGL errorsglGetShaderiv(fs, GL_COMPILE_STATUS, &fragCompiled);printShaderInfoLog(fs);
if (!vertCompiled || !fragCompiled) exit(-1);
Compilation// Create a program object and attach the two compiled shadersint program = glCreateProgram();glAttachShader(program, vs);glAttachShader(program, fs);
// Link the program object and print out the info logglLinkProgram(program);printOpenGLError(); // Check for OpenGL errorsglGetProgramiv(program, GL_LINK_STATUS, &linked);printProgramInfoLog();
if (!linked) exit(-1)
Initialization and Activation
Call glUseProgram( program ) to activate a shader. The default functionality will be disabled Can switch between multiple shaders while rendering a frame
Initialization example:GLint loc = glGetUniformLocation(program, "bumpon");glUniform1i( loc, GL_TRUE ); GLint loc = glGetUniformLocation(program, "normalMap");glUniform1i( loc, 0 ); GLint loc = glGetUniformLocation(program, "tangentVec");glVertexAttrib3f(loc, v1, v2, v3);
For more information, see the spec
http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf
top related