GLSL Programming Nicolas Holzschuch GLSL programming C-like - - PowerPoint PPT Presentation

glsl programming
SMART_READER_LITE
LIVE PREVIEW

GLSL Programming Nicolas Holzschuch GLSL programming C-like - - PowerPoint PPT Presentation

GLSL Programming Nicolas Holzschuch GLSL programming C-like language structure: int i, j; i = 2; j = 0; j += i; Functions, loops, branches... Reading your first GSL shader is easy Differences with C New data


slide-1
SLIDE 1

GLSL Programming

Nicolas Holzschuch

slide-2
SLIDE 2

GLSL programming

  • C-like language structure:


int i, j;
 i = 2;
 j = 0;
 j += i;

  • Functions, loops, branches...
  • Reading your first GSL shader is easy

slide-3
SLIDE 3

Differences with C

  • New data types: vec, mat...
  • Must write simple code
  • Data input/output
  • Compiling & linking
slide-4
SLIDE 4

New data types

  • vec4: a 4-component floating-point array
  • also vec2, vec3, ivec4...
  • mat4: a 4x4 floating-point matrix
  • also mat2, mat3...
  • Standard operations on vec/mat
slide-5
SLIDE 5

Standard operations

  • v = u + w
  • does the right thing with vec/mat
  • v = M*w
  • Matrix-vector multiplication, matrix-matrix

multiplication...

  • Other operators (see reference):
  • length(v), dot(v,w), cross(v,w)...
slide-6
SLIDE 6

Standard math functions

  • sin, cos, tan...
  • asin, acos, atan...
  • pow, exp, log, sqrt, inversesqrt
  • abs, sign, frac, floor, min, max,
  • step, smoothstep
  • Use them! (don’t recode them)
slide-7
SLIDE 7

Components & swizzle

  • Access to vector components:
  • u.x equivalent to u[0]
  • Operations on several components:
  • u.xyz = v.xyz/v.w (projection)
  • Reordering:
  • u = u.wzyx; w = u.xxyy;
slide-8
SLIDE 8

Components & swizzle

  • Very useful for Image Synthesis
  • Several sets of letters:
  • u.xyzw / u.rgba / u.stpq
  • Can use any of them
  • Makes code easier to read
slide-9
SLIDE 9

Input & Output

  • The basis for any program
slide-10
SLIDE 10

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

slide-11
SLIDE 11

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

slide-12
SLIDE 12

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders: Uniform variables

slide-13
SLIDE 13

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders: Uniform variables Shader:

uniform vec3 lightSource;

slide-14
SLIDE 14

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders: Uniform variables Shader:

uniform vec3 lightSource;

Program:

loc=glGetUniformLocation(shader, "lightSource"); glUniform3f(loc, x, y, z);

slide-15
SLIDE 15

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders: Uniform variables Shader:

uniform vec3 lightSource;

slide-16
SLIDE 16

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders (2): Textures

slide-17
SLIDE 17

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders (2): Textures In the shader:

uniform sampler2D MyTex;

slide-18
SLIDE 18

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

CPU ➜ shaders: discussion Q: Textures or uniform? A: Depends on the variable Constant (for every vertex): uniform Depends on position: texture

slide-19
SLIDE 19

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

slide-20
SLIDE 20

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

Vertex sh. ➜ Frag. shader

slide-21
SLIDE 21

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

Vertex sh. ➜ Frag. shader Interpolated variables

slide-22
SLIDE 22

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

Vertex sh. ➜ Frag. shader Interpolated variables Vertex shader:

  • ut vec4 ambientColor;

ambientColor = 0.3 * gl_Color;

Fragment shader:

in vec4 ambientColor;

slide-23
SLIDE 23

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

Fragment shader output:

slide-24
SLIDE 24

Input & Output

CPU Main memory Vertex shader Fragment shader Frame buffer Z-buffer

Fragment shader output:

fragColor = ...; //required fragDepth = ...; //optional

slide-25
SLIDE 25

Compiling & linking

  • 3 steps:
  • load and compile vertex shader
  • load and compile fragment shader
  • link shader
  • OpenGL functions:
  • glShaderSource, glCreateShader, glCompileShader,

glLinkProgram

slide-26
SLIDE 26

Compiling & linking

  • 3 steps:
  • load and compile vertex shader
  • load and compile fragment shader
  • link shader
slide-27
SLIDE 27

Compiling & linking

  • Check the result of the compilation

if (newProg != NULL) ...

  • Get the errors! (glGetShaderInfoLog)
  • Read them, they’re your only information
slide-28
SLIDE 28

One fun bug

  • Compiler designed for efficiency
  • Removes everything useless
  • …including useless variables
  • can be quite aggressive in that
  • …and complains of non-existent variable
  • also, C++ program tests if variable exists…
slide-29
SLIDE 29

That’s it!

  • These are the basics
  • You have a working program to start with
  • Edit it, understand it, improve it
  • Start with simple programs
slide-30
SLIDE 30

OpenGL4 and Qt5

  • OpenGL 4: removes many legacy options
  • more efficient, but different
  • Qt5: great integration with OpenGL4
  • encapsulates everything useful
slide-31
SLIDE 31

Loading a shader

QOpenGLShaderProgram* program = new QOpenGLShaderProgram(this); program->addShaderFromSourceFile (QOpenGLShader::Vertex, vertexShaderPath); program->addShaderFromSourceFile (QOpenGLShader::Fragment,fragmentShaderPath); program->link(); program->bind();

slide-32
SLIDE 32

Loading a shader (2)

QOpenGLShaderProgram* program = new QOpenGLShaderProgram(this); if (!program) qWarning() << "Failed to allocate the shader"; bool result = program->addShaderFromSourceFile (QOpenGLShader::Vertex, vertexShaderPath); if ( !result ) qWarning() << program->log(); result = program->addShaderFromSourceFile (QOpenGLShader::Fragment, fragmentShaderPath); if ( !result ) qWarning() << program->log(); result = program->link(); if ( !result ) qWarning() << program->log(); program->bind(); return program;

slide-33
SLIDE 33

Passing variables

m_program->bind(); m_program->setUniformValue ("lightPosition",lightPosition);

slide-34
SLIDE 34

Encoding the scene

  • Before (Open GL 3 and below): face-based

glBegin(GL_POLYGON) glVertex3f(x1,y1,z1); glVertex3f(x2,y2,z2); glVertex3f(x3,y3,z3); glVertex3f(x4,y4,z4); glEnd();

slide-35
SLIDE 35

Encoding the scene

  • OpenGL4:

Vertex Array Object

  • object-based
  • Single structure for each object
  • Vertex, color, normals, tex coords in arrays
  • VAO = set of arrays (vertex, color…)
slide-36
SLIDE 36

Vertex Array Objects: creation

QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vertexBuffer; QOpenGLBuffer m_indexBuffer; QOpenGLBuffer m_normalBuffer; QOpenGLBuffer m_colorBuffer; QOpenGLBuffer m_texcoordBuffer;

slide-37
SLIDE 37

Vertex array objects: filling

m_vao.bind(); m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDra w); m_vertexBuffer.bind(); m_vertexBuffer.allocate(&(modelMesh->vertices.front()), modelMesh->vertices.size()*sizeof(trimesh::point));

(same for index, color, normals…)

Pointer Size (bytes)

slide-38
SLIDE 38

Vertex array objects: drawing

m_program->bind(); m_vao.bind(); glDrawElements(GL_TRIANGLES, 3 * modelMesh->faces.size(), GL_UNSIGNED_INT, 0); m_vao.release(); m_program->release(); Primitive Nb index starting index

slide-39
SLIDE 39

Notes

  • Only the

VAO is drawn

  • Internal buffers used only at creation time
  • What if I only want to draw the geometry?
  • driver-dependent
  • = doesn’t always work
  • drivers expect vertices+normals
slide-40
SLIDE 40

Textures

texture = new QOpenGLTexture (QImage(textureName)); texture->setWrapMode(QOpenGLTexture::Repeat); texture->setMinificationFilter (QOpenGLTexture::LinearMipMapLinear); texture->setMagnificationFilter (QOpenGLTexture::Linear); texture->bind(0); m_program->setUniformValue("colorTexture", 0);

Texture unit number

slide-41
SLIDE 41

Frame Buffer Objects

  • For offscreen rendering
  • shadow maps, deferred shading
  • multi-target rendering
slide-42
SLIDE 42

Frame Buffer Objects

shadowMap = new QOpenGLFramebufferObject(w,h); shadowMap->bind(); shadowMap->release(); m_program->setUniformValue("shadowMap", shadowMap- >texture());

From here, all render events go to FBO And we make it a texture for main shader

slide-43
SLIDE 43

Frame Buffer Objects

QOpenGLFramebufferObjectFormat sFormat; sFormat.setAttachment(QOpenGLFramebufferObject::Depth); sFormat.setTextureTarget(GL_TEXTURE_2D); sFormat.setInternalTextureFormat (GL_RGBA32F_ARB); shadowMap = new QOpenGLFramebufferObject(w, h, sFormat); shadowMap->bind(); … shadowMap->release(); m_program->setUniformValue("shadowMap", shadowMap- >texture());

slide-44
SLIDE 44

Frame Buffer Objects

  • Also works with multiple render targets
slide-45
SLIDE 45

That’s all!