1 of 41

GLSL: Part 1

Instructor: Christopher Rasmussen (cer@cis.udel.edu)

Course web page:

https://goo.gl/th9HB2

February 27, 2018 ❖ Lecture 7

2 of 41

Outline

  • Shader background
  • GLSL tutorial
    • Portions adapted from CIS 565 “GPU Programming & Architecture” slides (Patrick Cozzi, instructor) at U. Pennsylvania

3 of 41

OpenGL (< 2.0) “fixed function” pipeline

Hardware implementations tightly coupled with OpenGL functions

4 of 41

OpenGL (< 2.0) “fixed function” pipeline

Hardware implementations tightly coupled with OpenGL functions

Wikipedia: "...the data needed to shade the pixel, plus the data needed to test whether the fragment survives to become a pixel (depth, alpha, stencil, scissor, window ID, etc.)"

5 of 41

OpenGL from 2.0 to 3.0

  • Programmable Processing units (exposing what was fixed)
    • Programmable per-vertex processors
    • Programmable per-fragment processors
  • Texture memory – general purpose data storage

from Orange Book

6 of 41

OpenGL from 2.0 to 3.0

  • Programmable Processing units (exposing what was fixed)
    • Programmable per-vertex processors
    • Programmable per-fragment processors
  • Texture memory – general purpose data storage

from Orange Book

7 of 41

Vertex Shader (circa OpenGL 3.0)

  • Operates on single vertex, executed in parallel
  • Input includes position, color, normals, etc.
  • Must take care of:
    • Model, view, and perspective transformations
    • Normal transformations
    • Texture coordinate generation & transformations
    • Lighting per vertex

8 of 41

Fragment Shader (circa OpenGL 3.0)

  • Operates on single fragment, executed in parallel
  • Fragment = info necessary for pixel...but might not get drawn

9 of 41

Fragment Shader (circa OpenGL 3.0)

  • Operates on single fragment, executed in parallel
  • Fragment = info necessary for pixel...but might not get drawn
  • Can be used to:
    • Compute colors
      • Per-pixel lighting (aka shading, next week)
      • Compute fog (depth-dependent color)
    • Access/apply textures
    • Blending, convolution

10 of 41

Other Shader types

  • Geometry shader
    • Can "emit" more vertices -- can use for splines, terrain generation, particle spawning, etc.
  • Compute shader
    • Do calculations that don't lead to rendering

11 of 41

GLSL (GL Shading Language)

  • High-level (C-like) language for vertex & fragment shader programs
    • Links on course page to "Orange book", tutorials
  • Compiler, linker tightly integrated with OpenGL driver…part of “core” for OpenGL > 3.0

12 of 41

GLSL (GL Shading Language)

  • High-level (C-like) language for vertex & fragment shader programs
    • Links on course page to "Orange book", tutorials
  • Compiler, linker tightly integrated with OpenGL driver…part of “core” for OpenGL > 3.0
  • Alternatives
    • HLSL (Microsoft, only on Windows/XBox with Direct3D), PSSL for PS4
    • Cg (created by Nvidia, cross platform, works with OpenGL, Direct3D, PS3). DISCONTINUED!

13 of 41

GLSL Syntax Overview

  • GLSL is like C without
    • Pointers, objects (but structs are still there)
    • Recursion
    • Gotos, switches
    • Dynamic memory allocation

14 of 41

GLSL Syntax Overview

  • GLSL is like C without
    • Pointers, objects (but structs are still there)
    • Recursion
    • Gotos, switches
    • Dynamic memory allocation
  • GLSL is like C with
    • Built-in vector, matrix and sampler types
    • Constructors
    • Good math library
    • Input and output qualifiers (aka variables for reading and variables for writing)

More details...and see last several slides for more functions

15 of 41

GLSL Syntax Overview

  • If you change your GLSL shader program(s), you don't need to recompile
  • They are loaded and compiled dynamically with LoadShaders() utility function in .cpp
  • If you want to change shader program name, make sure to change corresponding string in call to LoadShaders()

16 of 41

Modified .vertexshader in HW #1

(additions to tutorial 3 version in bold)

#version 330 core

// Input vertex data, different for all executions of shader

layout(location = 0) in vec3 vertexPosition_modelspace;

layout(location = 1) in vec3 vertexColor;

// Values that stay constant for the whole mesh.

uniform mat4 MVP;

out vec3 fragmentColor;

void main()

{

// Output position of the vertex (clip space)

// = MVP * position

gl_Position = MVP * vec4(vertexPosition_modelspace,1);

fragmentColor = vertexColor;

}

17 of 41

GLSL Syntax: Types

  • Scalar types: float, int, uint, bool
    • Can do casts: int i = int(0.0);
  • Vectors are first-class types:
    • vec2, vec3, vec4
    • ivec, bvec: Integer, boolean vectors
  • Matrices
    • mat2, mat3, mat4 (2x2, 3x3, 4x4)
    • Can also do m x n; stored in column-major format
  • Samplers (aka textures)
    • sampler1D, sampler2D, sampler3D, etc.

18 of 41

GLSL Syntax: Vectors

  • Constructors

vec3 xyz = vec3(1.0, 2.0, 3.0);

vec3 xyz = vec3(1.0); // [1.0, 1.0, 1.0]

vec3 xyz = vec3(vec2(1.0, 2.0), 3.0);

19 of 41

Modified .vertexshader in HW #1

#version 330 core

// Input vertex data, different for all executions of shader

layout(location = 0) in vec3 vertexPosition_modelspace;

layout(location = 1) in vec3 vertexColor;

// Values that stay constant for the whole mesh.

uniform mat4 MVP;

out vec3 fragmentColor;

void main()

{

// Output position of the vertex (clip space)

// = MVP * position

gl_Position = MVP * vec4(vertexPosition_modelspace,1);

fragmentColor = vertexColor;

}

20 of 41

GLSL Syntax: Vectors

  • Constructors

  • Access components three ways
    • .x, .y, .z, .w position or direction
    • .r, .g, .b, .a color
    • .s, .t, .p, .q texture coordinate
    • But don’t mix
      • OK: myColor.xyz
      • No! myColor.xgb or vec3.xrs

vec3 xyz = vec3(1.0, 2.0, 3.0);

vec3 xyz = vec3(1.0); // [1.0, 1.0, 1.0]

vec3 xyz = vec3(vec2(1.0, 2.0), 3.0);

21 of 41

GLSL Built-in Functions

  • Selected geometric functions

vec3 l, n; // = . . .

vec3 p, q; // = . . .

float f = length(l); // vector length

float d = distance(p, q); // dist between pts

float d2 = dot(l, n); // dot product

vec3 v2 = cross(l, n); // cross product

vec3 v3 = normalize(l); // “unitize”

22 of 41

GLSL Syntax: Matrices

  • Constructors

  • Accessing elements

mat3 i = mat3(1.0); // 3x3 identity matrix

mat2 m = mat2(1.0, 2.0, // [1.0 3.0]

3.0, 4.0); // [2.0 4.0]

float f = m[column][row];

float x = m[0].x; // x component of first column

vec2 yz = i[1].yz; // yz components of second column

Treat matrix as array of column vec2’s

Can swizzle too!

23 of 41

GLSL Syntax: Vectors and Matrices

  • Matrix and vector operations are easy and fast:

vec3 xyz = // ...

vec3 v0 = 2.0 * xyz; // scale

vec3 v1 = v0 + xyz; // component-wise

vec3 v2 = v0 * xyz; // component-wise

mat3 M = // ...

mat3 N = // ...

mat3 MN = M * N; // matrix * matrix

vec3 xyz2 = MN * xyz; // matrix * vector

24 of 41

GLSL Built-in Functions

  • Selected matrix functions

mat4 m = // ...

mat4 t = transpose(m);

float d = determinant(m);

mat4 d = inverse(m);

25 of 41

Type qualifiers

  • const: Compile time constant
  • attribute: Variables that may change per vertex
    • Passed from OpenGL app to vertex shaders
    • Read-only variable
  • uniform: Variables that may change per primitive
    • Passed from OpenGL app to shaders (see "MVP" variable in x_tutorial03.cpp) via glUniformMatrix4fv() and glGetUniformLocation()
    • Can be used in vertex or fragment shaders, where it is read-only

26 of 41

Modified .vertexshader in HW #1

#version 330 core

// Input vertex data, different for all executions of shader

layout(location = 0) in vec3 vertexPosition_modelspace;

layout(location = 1) in vec3 vertexColor;

// Values that stay constant for the whole mesh.

uniform mat4 MVP;

out vec3 fragmentColor;

void main()

{

// Output position of the vertex (clip space)

// = MVP * position

gl_Position = MVP * vec4(vertexPosition_modelspace,1);

fragmentColor = vertexColor;

}

27 of 41

Type qualifiers

  • const: Compile time constant
  • attribute: Variables that may change per vertex
    • Passed from OpenGL app to vertex shaders
    • Read-only variable
  • uniform: Variables that may change per primitive
    • Passed from OpenGL app to shaders (see "MVP" variable in x_tutorial03.cpp) via glUniformMatrix4fv() and glGetUniformLocation()
    • Can be used in vertex or fragment shaders, where it is read-only
  • varying: Interpolated data between vertex shader & fragment shader
    • Can be written in vertex shader
    • Read-only in fragment shader

28 of 41

in, out qualifiers; "built-in" variables

  • in qualifier:
    • Shader-stage input variables
    • Given value by previous stage
    • Cannot be changed by user code
  • out qualifier
    • Shader-stage output variables
    • Passed to next stage of pipeline
    • Must be set at some point during shader execution
  • Built-in variables
    • gl_Position: Output of vertex shader
    • gl_FragCoord, gl_FragDepth: Inputs to fragment shader

29 of 41

Modified .vertexshader in HW #1

#version 330 core

// Input vertex data, different for all executions of shader

layout(location = 0) in vec3 vertexPosition_modelspace;

layout(location = 1) in vec3 vertexColor;

// Values that stay constant for the whole mesh.

uniform mat4 MVP;

out vec3 fragmentColor;

void main()

{

// Output position of the vertex (clip space)

// = MVP * position

gl_Position = MVP * vec4(vertexPosition_modelspace,1);

fragmentColor = vertexColor;

}

30 of 41

Layout

  • How to get arrays of user-defined values into the vertex shader
  • Index specifies which attribute in vertex array to use
    • Position
    • Normal
    • Color
    • Etc.
  • See this for GLSL syntax & glVertexAttribPointer() in .cpp for references to vertex/color arrays

31 of 41

Old .fragmentshader in HW #1

#version 330 core

// Output data

out vec3 color;

void main()

{

// Output color = red

color = vec3(1,0,0);

}

32 of 41

Modified .fragmentshader in HW #1

#version 330 core

// Ouput data

out vec3 color;

in vec3 fragmentColor;

void main()

{

color = fragmentColor;

}

33 of 41

More GLSL language features/API

34 of 41

GLSL Syntax: Vectors

  • Swizzle: select or rearrange components

vec4 c = vec4(0.5, 1.0, 0.8, 1.0);

vec3 rgb = c.rgb; // [0.5, 1.0, 0.8]

vec3 bgr = c.bgr; // [0.8, 1.0, 0.5]

vec3 rrr = c.rrr; // [0.5, 0.5, 0.5]

c.a = 0.5; // [0.5, 1.0, 0.8, 0.5]

c.rb = 0.0; // [0.0, 1.0, 0.0, 0.5]

float g = rgb[1]; // indexing, not swizzling

35 of 41

GLSL Built-in Functions

  • reflect(-l, n)
    • Given l and n, find r. Angle in equals angle out

  • refract()
  • faceforward()

n

l

r

36 of 41

GLSL Built-in Functions

  • Selected vector rational functions

vec3 p = vec3(1.0, 2.0, 3.0);

vec3 q = vec3(3.0, 2.0, 1.0);

bvec3 b = equal(p, q); // (F, T, F)

bvec3 b2 = lessThan(p, q); // (T, F, F)

bvec3 b3 = greaterThan(p, q); // (F, F, T)

bool b4 = any(b); // T

bool b5 = all(b); // F

37 of 41

GLSL Built-in Functions

  • Rewrite in one line of code

bool foo(vec3 p, vec3 q)

{

if (p.x < q.x)

return true;

else if (p.y < q.y)

return true;

else if (p.z < q.z)

return true;

return false;

}

return any(lessThan(p, q));

38 of 41

GLSL Built-in Functions

  • Selected trigonometry functions

float s = sin(theta);

float c = cos(theta);

float t = tan(theta);

float phi = asin(s);

// ...

vec3 angles = vec3(/* ... */);

vec3 vs = sin(angles);

Works on vectors component-wise

Angles are measured

in radians

39 of 41

GLSL Built-in Functions

  • Exponential Functions

float xToTheY = pow(x, y);

float eToTheX = exp(x);

float twoToTheX = exp2(x);

float l = log(x); // ln

float l2 = log2(x); // log2

float s = sqrt(x);

float is = inversesqrt(x);

40 of 41

GLSL Built-in Functions

  • Selected common functions

float ax = abs(x); // absolute value

float sx = sign(x); // -1.0, 0.0, 1.0

float m0 = min(x, y); // minimum value

float m1 = max(x, y); // maximum value

float c = clamp(x, 0.0, 1.0);

// many others: floor(), ceil(), …

41 of 41

GLSL Built-in functions

  • mix(x, y, a) // linear interpolation
    • x, y: start, end of range
    • a: Interpolation value in range [0, 1]
  • step(edge, x)
    • Returns 0 if x < edge, 1 otherwise
  • smoothstep(edge1, edge2, x)
    • edge1 = value of lower edge of step
    • edge2 = value of upper
    • x = value to be interpolated along S-curve