Post on 09-Jul-2020
1
CSC 8470
Shaders and GLSL
q Programs that run on the GPU instead of the CPU q Op6onal in older OpenGL versions, but required in modern OpenGL
q Wri=en in OpenGl Shading Language (GLSL)
What are Shaders?
2
A Simplified OpenGL Pipeline
Vertex shader
Rasteriza6on & Interpola6on
Fragment shader
Final fragment processing
(plus some fixed
transforma6on)
q Operates on individual ver6ces, one at a 6me q Has no knowledge of other ver6ces that make up a primi6ve q At a minimum, it calculates projected posi.on of the input vertex
in screen space q Invoked once per vertex
Vertex Shader
Vertex shader
fixed
transform
(perspec.ve divide
and view
port
transforma.on)
3
Understanding Coordinate Spaces
h=p://www.theamazingking.com/ogl-‐matrix.php
Projection Transform
vertex shader output gl_Position!
4
Vertex TransformaCons
vertex shader input
vertex shader output
posi6on the model
posi6on the camera
adjust the zoom
q Here is the GLSL code for a simple vertex shader:
q Line 1: this shader is wri=en in GLSL version 1.5 q Line 2: this shader takes a single vertex as input in variable vert!q gl_Position is a global vec4 variable that stores shader output q The input vertex is sent to the output without any change at all
Simplest Vertex Shader
#version 150!!in vec3 vert;!!void main() {! // does not alter the vertices at all! gl_Position = vec4(vert, 1);!}!
5
From Vertices to Fragments q Note that the output of the vertex shader is not in screen coordinates.
This is because there is a fixed-‐func6on stage aYer the vertex shader and before the rasterizer
q We will discuss the details of this stage later in the semester
Vertex shader
Rasteriza6on & Interpola6on
Fragment shader Final pixels
fixed
transform
gl_Position!!
Built-in output variable gl_FragCoord!
!
Built-in input variable
q A fragment is basically a screen posi6on (x,y), a depth value (z), plus all interpolated a=ributes (color) from previous stages
q Fragment shaders can access the fragment posi6on (stored in read-‐only built-‐in variable gl_FragCoord), but cannot change it
Fragment Shader
Fragment shader
Rasteriza6on & Interpola6on
gl_FragCoord!!
Built-in input variable
6
q Here is the GLSL code for a simple fragment shader:
q Line 1: this shader is wri=en in GLSL version 1.5 q Line 2: declare an output variable that will hold the pixel color q Line 4: set the pixel color to white
q Note: Built-‐in variable gl_FragCoord stores current fragment posi6on
Simplest Fragment Shader
#version 150!!out vec4 finalColor;!!void main() {! //set every drawn pixel to white! finalColor = vec4(1.0, 1.0, 1.0, 1.0);!}!
Passing Data Between Shaders
#version 150!!in vec4 color;!out vec4 finalColor;!!void main() {! //set every drawn pixel to white! finalColor = color;!}!
#version 150!!in vec3 vert;!out vec4 color;!!void main() {! // does not alter the vertices at all! gl_Position = vec4(vert.x, vert.y, vert.z, 1);! color = vec4(0.0, 0.5, 0.0, 1.0);!}!
Vertex shader
Fragment shader
7
1. Modify the shaders in 01_project_skeleton (under resources) to change the output color to dark red, using the method shown on the previous slide.
Hands-‐On AcCvity 1
2. Modify the vertex shader in 01_project_skeleton so that the triangle is upside down.
Hands-‐On AcCvity 2
8
3. Output the vertex posi6on to the fragment shader and set the fragment's color equal to this vertex posi6on (see how the color posi6on values are interpolated across the triangle). Why is the bo=om-‐leY side of our triangle black?
Hands-‐On AcCvity 3
4. Modify the fragment shader to bring the fragment’s color in the range (0, 1). The shader should s6ll use the vertex posi6on in deriving the fragment’s color. Here is one example:
Hands-‐On AcCvity 4
9
5. Instead of sedng the vertex color in the vertex shader, have the applica6on pass the vertex color to the vertex shader
– You will need to modify the code in 01_project_skeleton to set vertex colors (RGB components) in the vertData array (in addi6on to vertex coordinates) and bind them to the vertColor a=ribute of the vertex shader
Hands-‐On AcCvity 5
#version 150!!in vec3 vert;!in vec3 vertColor;!out vec4 color;!!void main() {! // does not alter the vertices at all! gl_Position = vec4(vert.x, vert.y, vert.z, 1);! color = vec4(vertColor, 1.0);!}!
Vertex shader
For example, if you set the top vertex to be red (1.0, 0.0, 0.0), the leY vertex green (0.0, 1.0, 0.0) and the right vertex blue (0.0, 0.0, 1.0), you should get an image similar to the following:
Hands-‐On AcCvity 5 (contd.)
10
Hands-‐On AcCvity 6 6. Let’s get a li=le funky and mix colors in the fragment shader:
q mix(color1, color2, alpha)!– Linearly interpolate between the two colors alpha*color1 + (1-alpha)*color2!
#version 150!in vec4 vertColor;!out vec4 finalColor;!!vec4 purpleTint = vec4(0.5, 0.0, 0.5, 1.0);!!!void main() {! // give the entire image a purple tint! finalColor = mix(vertColor, purpleTint, 0.6);!}!
Fragment shader
before mixing aYer mixing
11
GLSL Variable Overview
q h=p://rela6vity.net.au/gaming/glsl/Variables.html
Required Reading
12
Scalar types: float, int, bool! Vector types: vec2, vec3, vec4! ivec2, ivec3, ivec4! bvec2, bvec3, bvec4! C++ style constructors: vec3 a = vec3(1.0, 2.0, 3.0);!
GLSL Data Types
1.02.03.0
!
"
###
$
%
&&&
Matrix types: mat2, mat3, mat4! mat3 rotate30 = mat3(0.86, 0.5, 0.0, !! ! ! ! ! -0.5, 0.86, 0.0, !! ! ! ! ! 0.0, 0.0, 1);!!!!!mat3 scale2 = mat3(2);!
GLSL Data Types
0.86 −0.5 0.00.5 0.86 0.00.0 0.0 1
"
#
$$$
%
&
'''
2.0 0.0 0.00.5 2.0 0.00.0 0.0 2.0
!
"
###
$
%
&&&
13
§ Standard C/C++ arithme6c and logic operators § Operators overloaded for matrix and vector opera6ons
mat4 m;!vec4 a, b, c;!!b = a*m;!c = m*a;!
GLSL Operators
For vectors can use [], xyzw, rgba or stpq!
Example: ! !vec3 v(1.0, 2.0, 3.0);!! !!!Then!! !v[1], v.y, v.g, v.t !all refer to the same element 2.0
Components and Swizzling
1.02.03.0
!
"
###
$
%
&&&
14
For vectors can use [ ], xyzw, rgba or stpq!
Swizzling: !vec3 a, b, c;!!a.xy = vec2(2.3, 1.7);!!b.yx = a.xy;!!c.xyz = a.rrr;!
Swizzling Examples
2.31.7?
!
"
###
$
%
&&&
1.72.3?
!
"
###
$
%
&&&
2.32.32.3
!
"
###
$
%
&&&
a b c
More on GLSL Later …