GLSL: OpenGL Shading Language Stefan Bruckner GLSL: Intro OpenGL - - PowerPoint PPT Presentation
GLSL: OpenGL Shading Language Stefan Bruckner GLSL: Intro OpenGL - - PowerPoint PPT Presentation
GLSL: OpenGL Shading Language Stefan Bruckner GLSL: Intro OpenGL Shading Language (GLSL) Current version 4.2 Specification: http://www.opengl.org/documentation/specs/ High level shading language Compiles directly to the available GLSL
GLSL: Intro
OpenGL Shading Language (GLSL)
Current version 4.2
Specification:
http://www.opengl.org/documentation/specs/
High level shading language
Compiles directly to the available hardware Previously: program in assembly for every vendor
GLSL Version OpenGL Version 1.10.59 2.0 1.20.8 2.1 1.30.10 3.0 1.40.08 3.1 1.50.11 3.2 3.30.6 3.3 4.00.9 4.0 4.10.6 4.1 4.20.6 4.2
GLSL: Intro
GLSL Version OpenGL Version Changes Year 1.10.59 2.0
Vertex Arrays
2004 1.20.8 2.1
Added PBO
2006 1.30.10 3.0
New render targets/FBO/VBO
2008 1.40.08 3.1
New matrix standards
- No ftransform()!
2009 1.50.11 3.2
GS/layout
2009 3.30.6 3.3
Occlusion queries/sampler objects
2010 4.00.9 4.0
Individual blend equations for each color output/texture buffers/TS
2010 4.10.6 4.1
Atomic counters/bind programs individually to programmable stages/viewport arrays
2010 4.20.6 4.2
Read and write images/binding points from GLSL/TFO with instanced rendering
2011
GLSL: Intro
Shader programs are programs that run in parallel
- n the
graphics card to render graphics
Newest cards (NVIDIA 560, 2011) has 512 stream processors that are divided between the different shader types In theory 512 pixels can be colored at the same time
GLSL
Shader stream processors are grouped by pairs of 8 (8x2)
GLSL
Graphics Pipeline
VS TS GS FS
GLSL: Shader Programs
GLSL: Shader Programs
Types of shader programs
Vertex Program Tessellation Program (latest addition) Geometry Program Fragment Program
Output from vertex program is used as input to tessellation/geometry program Output from geometry program is used as input to fragment program
Vertex Tessellation Geometry Fragment
GLSL: Vertex Program
Operates on vertices
Input: vertex Output: vertex
Used for
Moving/Displacing vertices Defining/Modifying normals Texture coordinates Changing color of vertices Note: vertices/texture coord./normals arrive untransformed (in object coordinate system)
in vec4 position; void main(void) { gl_Position = position; }
[2D Wave map displacement]
GLSL: Tesselation Program
Operates on vertices
Input: a patch (quads, triangles, lines) Output: subdivide the patch into (thousands of) primitives of the patch type
Used for
Subdivision of primitives/patches LOD primitives Terrain rendering Parametric surfaces
control: layout(vertices = 4) out; uniform float inner_level; uniform float outer_level; #define id gl_InvocationID void main(){ gl_TessLevelInner[0] = inner_level; gl_TessLevelInner[1] = inner_level; gl_TessLevelOuter[0] = outer_level; gl_TessLevelOuter[1] = outer_level; gl_TessLevelOuter[2] = outer_level; gl_TessLevelOuter[3] = outer_level; gl_out[id].gl_Position = gl_in[id].gl_Position; } eval: layout(quads, equal_spacing, ccw) in; uniform mat4 projection; uniform mat4 modelview; void main(){ float u = gl_TessCoord.x; float v = gl_TessCoord.y; float omu = 1-u; float omv = 1-v; gl_Position = projection * modelview * *Func (omu, omv gl_in[0].gl_Position, gl_in[1].gl_Position ,gl_in[2].gl_Position,gl_in[3].gl_Position);}
[Triangle tessellation]
GLSL: Geometry Program
Operates on vertices
Input: vertices (a fixed number) Output: vertices/lines/polygons
Used for
Creating new vertices/lines/polygons Changing color for each primitive Defining/Modifying normals for each primitive Texture coordinates for each primitive
geometry: layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; void main(){ gl_Position = gl_in[0].gl_Position; EmitVertex(); gl_Position = gl_in[1].gl_Position; EmitVertex(); gl_Position = gl_in[2].gl_Position; EmitVertex(); EndPrimitive(); }
VS GS [Sphere splatting]
GLSL: Fragment Program
Operates on fragments
Input: fragment location/color/normal/texturecoord Output: fragment color, opacity (+fragment depth)
Used for
Setting the color of pixels Calculating depth values Note: no automatic lighting or texturing
fragment:
- ut vec4 fragment;
void main(){ fragment = CalcShading(); }
[Depth of field]
GLSL: Program Chain Example
OpenGL draws one vertex
Vertex program chooses a color according to a texture
GLSL: Program Chain Example
Geometry program takes the vertex and uses it as a center for a sphere
Emits triangles for this sphere with color and correct normals and texture coordinates
GLSL: Program Chain Example
Fragment program fills the triangles using texturing and phong shading
GLSL: Setting up
Create a program
glCreateProgram()
Returns a program object reference Shader objects will be attached to this program
You can create several programs and attach the same shader to multiple programs
Create a Shader
glCreateShader(type)
GL_VERTEX_SHADER GL_GEOMETRY_SHADER GL_FRAGMENT_SHADER GL_TESS_CONTROL_SHADER GL_TESS_EVALUATION_SHADER
Returns a shader object reference
GLSL: Setting up
Upload the source
glShaderSource(sid, n, *src, *srclen)
Attaching a shader to a program
glAttachShader(pid, sid)
Compiling
glCompileShader(sid)
Linking the program
glLinkProgram()
Starting a program is done like this:
glUseProgram(pid) glUseProgram(0) //no program’s used
GLSL: Setting up
Detaching shaders
glDetachShader(pid, sid)
Deleting shaders and programs
glDeleteShader(sid) glDeleteProgram(pid)
GLSL: Uniforms and Attributes
A shader program can receive data through uniforms and attributes Uniforms
Variables that apply to all vertices and does not change over a primitive
Attributes
Variables that can change from vertex to vertex Similar to glColor(…) and glNormal(…) Interpolated between vertices
GLSL: Data Types
GLSL supports many different data types
Single value
bool, int, float
2 element vectors
bvec2, vec2, ivec2
3 element vectors
bvec3, vec3, ivec3
4 element vectors
bvec4, vec4, ivec4
GLSL: Data Types
Matrices
mat2, mat3, mat4
Textures
sampler1D, sampler2D, sampler3D
Structs
struct name {…};
Others
Texture arrays, texture buffers and depth textures
GLSL: Variables
Defining variables
bvec2 b = bvec2(true, false); vec3 n = vec3(1.0, 0.0, 0.0); mat2 m = mat2(1.0, 0.0, 0.0, 1.0);
struct light { vec3 position; vec3 color; };
GLSL: Vectors
There are different ways of accessing the values of a vector
vec4 v = vec4(…); float a = v.x; or v.r; or v.s; float b = v.y; or v.g; or v.t; float c = v.z; or v.b; or v.p; float d = v.w; or v.a; or v.q;
Swizzling
vec4 v = vec4(a, b, c, d); vec4 n = v.xxyy; //n = {a, a, b, b} vec2 j = v.zw; //j = {c, d}
GLSL: Matrices
Matrices also have different ways of accessing the values
mat4 m = … float m00 = m[0][0]; //column 0, row 0 vec4 clm = m[1]; // column 1
GLSL: Qualifiers
GLSL has several qualifiers to define the type variable
const – a compile time constant attribute – a variable that changes per vertex. Only applies to vertex shaders uniform – a variable that may change per vertex. Can only be changed outside of a glBegin/glEndblock varying – interpolated data. A value that has been defined in a vertex shader will be interpolated over the primitive.
GLSL: Setting Attributes and Uniforms
- ut vec2 coord; //varying attribute
uniform mat4 projmat; //uniform attribute attribute float weight; //per vertex attribute uniform sampler2D depth; //texture2D In OpenGL we need to do this to set a uniform
GLuint glGetUniformLocation(pid, “projmat”)
Returns a location to the variable
To set a value
glUniform<1234><fi>(GLint loc, GLfloat v0, …) glUniform<1234><fi>v(GLint loc, GLsizei n, GLfloat v) glUniformMatrix<234>fv(GLuint loc, GLsizei count, GLboolean transpose, GLfloat *v)
GLSL: Setting Attributes and Uniforms
The procedure for setting an attribute is similar
GLint glGetAttribLocation(GLuint program, char *name)
Setting the attribute
glVertexAttrib<1234><fi>(GLint loc, GLfloat v0, …) glVertexAttrib<1234><fi>v(GLint loc, GLfloat v)
Texture
In GLSL you refer to a texture using a sampler but in OpenGL you define them using integers
glUniform1i(ul, n)
n is the number of the texture unit the texture is bound to
GLSL: Setting Attributes and Uniforms
Setting structs in our program
ul = glGetUniformLocation(pid, “lighting.position”) glUniform3f(ul, x, y, z) ul = glGetUniformLocation(pid, “lighting.color”) glUniform3f(ul, r, g, b)
GLSL: Operators
Most math functions are available and valid for the built in data types
vec4 v; vec4 w; mat4 m; vec4 q = v * w + v / 2.0 + w * 3.0; mat4 c = q * m
Also special methods such as sin, cos, log, sqrt, abs, min, max, dot, length, cross, normalize, ftransform
GLSL: Built-in variables
OpenGL < 3.1
OpenGL has several built-in attributes
gl_Vertex – vertex defined by glVertex gl_Color – color defined by glColor gl_Normal – normal defined by glNormal …
And built-in uniforms
gl_ModelViewMatrix gl_ProjectionMatrix gl_TextureMatrix …
OpenGL > 3.1
layout(location=0) in vec4 vertices; layout(binding=1) uniform mat4 projmat;
GLSL: Language
The basic C language with a few extensions and limitations
discard;
Discard this fragment without writing to the color buffer
- r depth buffer
void main()
Main function in every shader
You can define your own functions
Your can return all types except for arrays Function parameters has qualifiers
in (default) – the parameter is for in data
- ut – the parameter is for outputting data
inout – both for input and output
No dynamic arrays
GLSL: Language
To access a texture
texture<123>D(sampler, p)
Where p has the same number of dimensions as the texture type
Currently plenty of specialized functions!
Look into the manual
Google “OpenGL shading language”
[Normal displacement texture]
GLSL: Draw Buffers
Fragment shaders support output to several drawbuffers
Instead of writing to gl_FragColor Write to gl_FragData[x]
x is from 0 to the number of drawbuffers – 1
The drawbuffers have been configured in OpenGL
GLenum buffers[] = {GL_COLORATTACHMENTx_EXT, …) glDrawBuffers(n, buffers) Since GLSL v1.50
- ut vec4 MyFragColor;
[Shadow mapping]
GLSL: Hello World
//Minimal vertex program #version 140 void main() { gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; gl_Position = ftransform(); } //Minimal fragment program void main() { gl_FragColor = vec4(…); }
GLSL: Hello World
//Minimal vertex program #version 150 uniform mat4 proj; uniform mat4 view; layout (location = 0)in vec3 inPosition; void main() { gl_Position = proj * view * vec4(inPosition,1.0); } //Minimal fragment program layout(location=0) out vec4 fragment; void main() { fragment = vec4(…); } // Vertex position
glGenBuffers(1, &buffer[0]); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBufferData(GL_ARRAY_BUFFER, vertices. size() * 3*sizeof(float), &vertices[0], GL_STATIC_DRAW); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
Geometry and Tessellation Shader
GLSL: Geometry Vs. Tessellation
Geometry Shader
Conversion between different geometries Example
From triangles to points, lines From points to a triangles, quads, etc.
Tesselation Shader
More geometry of the same sort
From a line to lines From a triangle patch to triangles From a quad patch to (isolines or) quads
No primitives with adjacency!
[Level of details]
GLSL: Geometry
Geometry shader
Input: vertices in a primitive from VS or TS Output: new set of vertices and primitives In data
vec4 gl_in[ ].gl_Position; layout(points) in; layout(triangle_strip, max_vertices = 3) out;
Out data
gl_Position = func1(gl_in[0].gl_Position); EmitVertex(); gl_Position = func2(gl_in[0].gl_Position); EmitVertex(); gl_Position = func3(gl_in[0].gl_Position); EmitVertex(); EndPrimitive();
GLSL: Geometry
Example: sphere splatting [Lampe,07]
Fast rendering of spheres in the image space Input: points + radiuses
VS GS FS
GLSL: Geometry
Example: sphere splatting [Lampe,07]
Fast rendering of spheres in the image space Input: points + radiuses
//GS layout(points) in; layout(triangle_strip, max_vertices = 4) out;
- ut vec2 coord;
void main() { float radius = gl_in[0].gl_Position.a; vec4 p = gl_in[0].gl_Position; p.a = 1.0; coord = vec2( -1,-1 ); gl_Position = projmod * (p + vec4(-radius,-radius,0,0)) ; EmitVertex(); coord = vec2( -1,1 ); gl_Position = projmod * (p + vec4(-radius,radius,0,0)) ; EmitVertex(); coord = vec2( 1,-1 ); gl_Position = projmod * (p + vec4(radius,-radius,0,0)) ;EmitVertex(); coord = vec2( 1,1 ); gl_Position = projmod * (p + vec4(radius,radius,0,0)) ;EmitVertex(); EndPrimitive(); } // in C glBegin(GL_POINTS); glVertex4f(…); glVertex4f(…); glVertex4f(…);…. glEnd();
//FS void main() { float len = length( coord ); if (len>1.0) discard; … }
GLSL: Tessellation
Tesselation uses a new graphics primitive GL_PATCHES
glBegin(GL_PATCHES); glVertex3f(…); glVertex3f(…); glEnd()
Vertex values do not need to be coordinates glPatchParameteri(GL_PATCH_VERTICES, num);
How many vertices per patch
GLSL: Tessellation
Tessellation control shader
Input: num of vertices in a patch from VS Output: Prepare control points and how much to tessellate (tessellation level) Input vertices (coordinates) are transformed to surface coordinates Tesselation level can be specified according to
Surface curvature, eye-object distance, screen-space spanning, etc.
GLSL: Tessellation
Tessellation control shader In data
vec4 gl_in[0..num-1].gl_Position; float gl_in[0..num-1].gl_PointSize; size in pixels float gl_in[0..num-1].gl_ClipDistance[ ]; vertex distance from clipping planes 0.0 lies on the plane int gl_InvocationID Output vertex we are working on gl_out[gl_InvocationID] int gl_PatchVerticesIn; Number of vertices in a patch int gl_PrimitiveID; Current patch ID; Up to the number of patches sent
GLSL: Tessellation
Tessellation control shader
Out data
Number of control points
layout(vertices = N) out;
vec4 gl_out[0..N-1].gl_Position; float gl_out[0..N-1].gl_PointSize; float gl_out[0..N-1].gl_ClipDistance[ ]; patch out float gl_TessLevelOuter[4];
Tessellation of outer edges
patch out float gl_TessLevelInner[2];
Tessellation of inner edges
Another patch variables
patch out float patch_area;
GLSL: Tessellation
Tessellation control shader
TCS instances run independently TCS[i] can read data from TCS[j] They can be synchronized via barrier()
Must not be called from loops, switch, if, .. Ex: compute locale curvatures and store it in
GLSL: Tessellation
Tessellation primitive generator
Cannot be programmed Looks at tessellation levels and outputs lines, triangles, quads in barycentric coordinates (u,v,w)
u,v for lines and quads u,v,w for triangles
GLSL: Tessellation
Tessellation evaluation shader
Reads (u,v,w) coordinates and the output coordinates from TCS and
Creates output coordinates (x,y,z) Interpolates attributes Applies displacement
One instance of TES per output vertex from TCS
If No TCS is used
glPatchParameterfv(GL_DEFAULT_OUTER_LEVEL, float level[4]); glPatchParameterfv(GL_DEFAULT_INNER_LEVEL, float level[2]);
GLSL: Tessellation
Tessellation evaluation shader
Reads (u,v,w) coordinates and the output coordinates from TCS and
Creates output coordinates (x,y,z) Interpolates attributes Applies displacement
Ex: layout(triangles, equal_spacing, cw) in;
What to form? Spacing? Orientation? Points at output vertex?
GLSL: Tessellation
Tessellation evaluation shader
In data
layout(triangles, equal_spacing, cw) in; gl_in[] = gl_out[] from TCS
vec4 gl_in[0..N-1].gl_Position; float gl_in[0..N-1].gl_PointSize; float gl_in[0..N-1].gl_ClipDistance[ ];
in int gl_PatchVerticesIn; in int gl_PrimitiveID in vec3 gl_TessCoord;
Out data
vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[ ];
GLSL: Tessellation
Example: Cubic Bezier Curve
GLSL: Tessellation
Example: Cubic Bezier Curve
TCS can determine the tessellation level TPG produces u, from (u,v,w) TES computes position (x,y,z) based on u
GLSL: Tessellation
Example: Cubic Bezier Curve
OpenGL call for input patch
GLSL: Tessellation
Example: Cubic Bezier Curve
TCS
GLSL: Tessellation
Example: Cubic Bezier Curve
TCS
GLSL: Tessellation
Example: Cubic Bezier Curve
TES
GLSL: Tessellation
Example: Cubic Bezier Curve
gl_TessLevelOuter[1] = 3 gl_TessLevelOuter[1] = 10 gl_TessLevelOuter[1] = 100