static void
Transcrição
static void
GLSL OpenGL Shading Language Curso de Visualização Científica Waldemar Celes [email protected] Tecgraf/PUC-Rio OpenGL 3.* • API para interface com hardware gráfico • Independente de plataforma (e de sistema de janela) • Especificação padrão + extensões • SGI_, ATI_, AMD_, NV_, IBM_, WGL_, EXT_, ARB_ • Bibliotecas • OpenGL • GLUT: sistema de janela • GLEW: acesso às extensões INF2610 - W. Celes - PUC-Rio 2 Exemplo de programa OpenGL • Desenho de esferas sobre um plano INF2610 - W. Celes - PUC-Rio 3 Exemplo de programa OpenGL • Função principal // Main function int main (int argc, char argv[]) { // open GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT DOUBLE | GLUT DEPTH | GLUT RGB); glutInitWindowSize(800,600); // create window glutCreateWindow ("Spheres"); glutReshapeFunc(Reshape); glutDisplayFunc(Display); glutKeyboardFunc(Keyboard); // initiate OpenGL context Init(); // interact... glutMainLoop(); return 0; } INF2610 - W. Celes - PUC-Rio 4 Exemplo de programa OpenGL • Função de inicialização // Initialization function static void Init () { float white[4] = {1.0f,1.0f,1.0f,1.0f}; glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL DEPTH TEST); glEnable(GL LIGHTING); glEnable(GL LIGHT0); glEnable(GL COLOR MATERIAL); glColorMaterial(GL FRONT AND BACK,GL AMBIENT AND DIFFUSE); glMaterialfv(GL FRONT AND BACK,GL SPECULAR,white); glMaterialf(GL FRONT AND BACK,GL SHININESS,50.0); glLightModeli(GL LIGHT MODEL LOCAL VIEWER,1); } // Reshape callback static void Reshape (int w, int h) { glViewport(0,0,w,h); } INF2610 - W. Celes - PUC-Rio 5 Exemplo de programa OpenGL • Função de preparo do desenho // Display callback static void Display (void) { int vp[4]; glGetIntegerv(GL VIEWPORT,vp); glClear(GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT); glMatrixMode(GL PROJECTION); glLoadIdentity(); gluPerspective(50.0f,(float)vp[2]/vp[3],1.0,100.0); glMatrixMode(GL MODELVIEW); glLoadIdentity(); gluLookAt(0,7,15,0,0,0,0,1,0); // draw scene DrawScene(); glutSwapBuffers(); } INF2610 - W. Celes - PUC-Rio 6 Exemplo de programa OpenGL • Função de redesenho da cena /⇥ Draw scene ⇥/ static void DrawScene () { /⇥ position light ⇥/ float lpos[4] = {0.0f,6.0f,0.0f,1.0f}; glLightfv(GL LIGHT0,GL POSITION,lpos); /⇥ draw floor ⇥/ glColor3f(0.4f,0.6f,0.0f); glNormal3f(0.0f,1.0f,0.0f); glBegin(GL QUADS); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glEnd(); /⇥ draw spheres ⇥/ { int i,j; float d = 2⇥10.f/10; float p0 = 10.f + d/2; glColor3f(1.0f,0.0f,0.0f); for (i=0; i<10; i++) { for (j=0; j<10; j++) { glPushMatrix(); glTranslatef(p0+i⇥d,0.5f,p0+j⇥d); glutSolidSphere(0.5,32,32); glPopMatrix(); } } } } INF2610 - W. Celes - PUC-Rio 7 OpenGL 3.* • Introduz o uso de “deprecated functions” • Perfis • Core profile: apenas as funcionalidades atuais • OpenGL 3.2 e posterior • Compatibility profile: + funcionalidades “deprecated” • Nova extensão: GL_ARB_compatibility • Ainda com vida longa, senão eterna (grande legado) INF2610 - W. Celes - PUC-Rio 8 Pipeline Programável • Vertex & fragment shader Vertex program Aplicação Transformação Modelagem e Visualização Iluminação Projeção Clipping Mapeamento de Tela Rasterização Mapeamento de Textura Combinação Blend Teste α,s,z Frame Buffer Fragment program Aplicação Geometria Rasterização INF2610 - W. Celes - PUC-Rio OpenGL 3.*: deprecated functions • Função principal // Main function int main (int argc, char argv[]) { // open GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT DOUBLE | GLUT DEPTH | GLUT RGB); glutInitWindowSize(800,600); // create window glutCreateWindow ("Spheres"); glutReshapeFunc(Reshape); glutDisplayFunc(Display); glutKeyboardFunc(Keyboard); // initiate OpenGL context Init(); // interact... glutMainLoop(); return 0; } Glut continua sendo uma opção válida para desenvolvimento de programas OpenGL INF2610 - W. Celes - PUC-Rio 10 OpenGL 3.*: deprecated functions • Função de redesenho da cena /⇥ Draw Scene ⇥/ static void DrawScene () { ... } /⇥ draw spheres ⇥/ { int i,j; float d = 2⇥10.f/10; float p0 = 10.f + d/2; glColor3f(1.0f,0.0f,0.0f); for (i=0; i<10; i++) { for (j=0; j<10; j++) { glPushMatrix(); glTranslatef(p0+i⇥d,0.5f,p0+j⇥d); glutSolidSphere(0.5,32,32); glPopMatrix(); } } } Mas primitivas Glut são muito ineficiente! INF2610 - W. Celes - PUC-Rio 11 OpenGL 3.*: deprecated functions • Função de inicialização API para controle dos buffers continua válida. // Initialization function static void Init () { float white[4] = {1.0f,1.0f,1.0f,1.0f}; glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL DEPTH TEST); glEnable(GL LIGHTING); glEnable(GL LIGHT0); glEnable(GL COLOR MATERIAL); glColorMaterial(GL FRONT AND BACK,GL AMBIENT AND DIFFUSE); glMaterialfv(GL FRONT AND BACK,GL SPECULAR,white); glMaterialf(GL FRONT AND BACK,GL SHININESS,50.0); glLightModeli(GL LIGHT MODEL LOCAL VIEWER,1); } // Reshape callback static void Reshape (int w, int h) { glViewport(0,0,w,h); Não existe } modelo de iluminação pré-definido. INF2610 - W. Celes - PUC-Rio Codifique-o! 12 OpenGL 3.*: deprecated functions • Função de preparo do desenho // Display callback static void Display (void) { int vp[4]; glGetIntegerv(GL VIEWPORT,vp); glClear(GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT); glMatrixMode(GL PROJECTION); glLoadIdentity(); gluPerspective(50.0f,(float)vp[2]/vp[3],1.0,100.0); glMatrixMode(GL MODELVIEW); glLoadIdentity(); gluLookAt(0,7,15,0,0,0,0,1,0); // draw scene DrawScene(); glutSwapBuffers(); Biblioteca glu usa funções “deprecated” Codifique uma própria! } INF2610 - W. Celes - PUC-Rio 13 OpenGL 3.*: deprecated functions • Função de preparo do desenho // Display callback static void Display (void) { int vp[4]; glGetIntegerv(GL VIEWPORT,vp); glClear(GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT); glMatrixMode(GL PROJECTION); glLoadIdentity(); gluPerspective(50.0f,(float)vp[2]/vp[3],1.0,100.0); glMatrixMode(GL MODELVIEW); glLoadIdentity(); gluLookAt(0,7,15,0,0,0,0,1,0); // draw scene DrawScene(); glutSwapBuffers(); } Não existe modelo de transformação prédefinido, mas primitivas fora do cubo de [-1 -1 -1] a [ 1 1 1] são clipadas Ilumine no espaço que julgar mais apropriado! Transforme os vértice para o espaço de clip! INF2610 - W. Celes - PUC-Rio 14 OpenGL 3.*: deprecated functions • Função de redesenho da cena /⇥ Draw scene ⇥/ static void DrawScene () { /⇥ position light ⇥/ float lpos[4] = {0.0f,6.0f,0.0f,1.0f}; glLightfv(GL LIGHT0,GL POSITION,lpos); /⇥ draw floor ⇥/ glColor3f(0.4f,0.6f,0.0f); glNormal3f(0.0f,1.0f,0.0f); glBegin(GL QUADS); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glVertex3f( 10.f,0.0f, 10.f); glEnd(); Primitivas desenhadas apenas via API de array (ou usando buffers na placa) /⇥ draw spheres ⇥/ { int i,j; float d = 2⇥10.f/10; float p0 = 10.f + d/2; glColor3f(1.0f,0.0f,0.0f); for (i=0; i<10; i++) { for (j=0; j<10; j++) { glPushMatrix(); glTranslatef(p0+i⇥d,0.5f,p0+j⇥d); glutSolidSphere(0.5,32,32); glPopMatrix(); } } } } Controle as transformações dos espaços de coordenadas! (API de transformações já era substituída em aplicações “sérias”) INF2610 - W. Celes - PUC-Rio 15 Codificação com OpenGL 3.* • Aplicação cliente • Estrutura primitivas em arrays ou buffers • Implementa funções de manipulação de matrizes • Conceito de pilha, modelview, projection, etc. podem ser úteis • Implementa modelo de iluminação em shaders • Não existe programa sem shaders • Estrutura dados em variáveis uniform • Estado do OpenGL minimizado • Controla operações em buffer, culling, blend, etc. INF2610 - W. Celes - PUC-Rio 16 Exemplo simples com OpenGL 3.* • Desenho de um triângulo vermelho INF2610 - W. Celes - PUC-Rio 17 Exemplo simples com OpenGL 3.* • Função de inicialização static void Init () Uso da Glew para gerência de extensões. { // open GLEW GLenum err = glewInit(); if (GLEW OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); exit( 1); } // init OpenGL state glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL DEPTH TEST); CreateShaderProgram(); } Uso de shaders (obrigatório). INF2610 - W. Celes - PUC-Rio 18 Exemplo simples com OpenGL 3.* • Função de redesenho da cena Primitivas desenhadas API de array. /⇥ Draw scene ⇥/ Apenas atributos genéricos, sem static void DrawScene () semântica pré-atribuída. { static float coord[] = { Neste exemplo, índice 0 usado para 1.0f, 1.0f, 0.0f, especificar coordenadas já no espaço 1.0f, 1.0f, 0.0f, de clip para evitar transformações. 0.0f, 1.0f, 0.0f }; glUseProgram(p id); glVertexAttribPointer(0,3,GL FLOAT,GL FALSE,0,coord); glEnableVertexAttribArray(0); glDrawArrays(GL TRIANGLES,0,3); } INF2610 - W. Celes - PUC-Rio 19 Exemplo simples com OpenGL 3.* • Especificação do código fonte static const char vsource = "in vec4 myVertex; / OpenGL 2. used ’attribute’ " " instead of ’in’ /" "void main (void) " "{ " " gl Position = myVertex; " "}"; static const char fsource = "void main (void) " "{" " gl FragColor = vec4(1.0,0.0,0.0,1.0);" "}"; INF2610 - W. Celes - PUC-Rio 20 Exemplo simples com OpenGL 3.* • Função de criação do shade / Cria programa de shader / static void CreateShaderProgram () { / vertex shader / GLuint v id = glCreateShader(GL VERTEX SHADER); if (v id==0) Error("Could not create vertex shader object"); glShaderSource(v id, 1, &vsource, 0); CompileShader(v id); / fragment shader / GLuint f id = glCreateShader(GL FRAGMENT SHADER); if (f id==0) Error("Could not create fragment shader object"); glShaderSource(f id, 1, &fsource, 0); CompileShader(f id); / program / p id = glCreateProgram(); if (p id==0) Error("Could not create program object"); glBindAttribLocation(p id,0,"myVertex"); glAttachShader(p id,v id); glAttachShader(p id,f id); LinkProgram(p id); } INF2610 - W. Celes - PUC-Rio 21 Exemplo simples com OpenGL 3.* • Função de compilação de shaders / Compila shader / static void CompileShader (GLuint id) { GLint status; glCompileShader(id); glGetShaderiv(id, GL COMPILE STATUS, &status); if (!status) { GLint len; glGetShaderiv(id, GL INFO LOG LENGTH, &len); char message = (char ) malloc(len sizeof(char)); glGetShaderInfoLog(id, len, 0, message); Error(message); free(message); } } INF2610 - W. Celes - PUC-Rio 22 Exemplo simples com OpenGL 3.* • Função de link-edição de shaders /⇥ Link edita shader ⇥/ static void LinkProgram (GLuint id) { GLint status; glLinkProgram(id); glGetProgramiv(id, GL LINK STATUS, &status); if (!status) { GLint len; glGetProgramiv(id, GL INFO LOG LENGTH, &len); char⇥ message = (char⇥) malloc(len⇥sizeof(char)); glGetProgramInfoLog(id, len, 0, message); Error(message); free(message); } } INF2610 - W. Celes - PUC-Rio 23 Pipeline programável •Vertex shader • Tessellation shaders • Geometry shader •Fragment shader INF2610 - W. Celes - PUC-Rio 24 Pipeline Programável w Controle sobre operações de vértices w Controle sobre operações de fragmentos w Operações substituídas n Transformação n Iluminação n Projeção n Geração de coordenadas de textura n Aplicação de textura n Combinação w Geração de geometria w CPU → GPU INF2610 - W. Celes - PUC-Rio Vertex shader wOperações substituídas n Transformação de vértices l Modelview n e projection Transformação de normais l Transformação, re-escala, normalização n Iluminação por vértice n Geração de coordenadas de textura n Geração de “coordenadas de clip” n Definição de tamanho de ponto INF2610 - W. Celes - PUC-Rio Vertex shader wOperações não substituídas n Clipping contra frustum n Divisão da perspectiva n Mapeamento de tela l Transformação de viewport l Transformação de Z INF2610 - W. Celes - PUC-Rio Vertex shader w Recebe um vértice n Não transformado e não iluminado w Transforma o vértice n As 4 componentes devem ser preenchidas w Opcionalmente n Gera coordenadas de textura l Aplica transformações l A coordenada “w” deve ser preenchida n Ilumina n Calcula fator de fog n Calcula tamanho de ponto n etc. INF2610 - W. Celes - PUC-Rio Vertex shader w Não cria ou destrói vértice n 1 vértice de entrada n 1 vértice de saída w Não há informação topológica n Não há aresta, face n Não há info de vértices vizinhos l Podemos usar atributos com info explicitada w Carregado dinamicamente n Como objetos de textura INF2610 - W. Celes - PUC-Rio Fragment shader w Aplicado a qualquer fragmento n Ponto, linha, triângulo, pixel, bitmap n Pode-se descartar fragmentos w Processamento n Fragmento a fragmento, independentes w Operações substituídas n Texturing n Color sum l Soma das cores primária e secundária pelo programa w Acesso ao stencil e buffers auxiliares n Possível futura extensão INF2610 - W. Celes - PUC-Rio GLSL 230 CHAPTER 6 Thinking Outside the Box: Nonstock Shaders • Arquitetura básica GLSL 101 The OpenGL Shading Language (GLSL) is a C-like high-level language that is compiled and linked by your OpenGL implementation and (usually) runs entirely on the graphics hardware. Shader programs look a lot like C, they start with the main function as their entry point, and you can write functions in GLSL that accept parameters and return values. Figure 3.1 from Chapter 3 is repeated here as Figure 6.1 and shows our basic shader architecture. • Vertex & fragment shader Application Code: C/C++, etc. Server Attributes (Ins) Client Uniforms Texture Data OpenGL API Vertex Shader void main() { … … } Outs Uniforms Texture Data Vertex Positions ptg Primitive Assembly Ins Fragment Shader void main() { … … } FIGURE 6.1 Our basic shader architecture. INF2610 - W. Celes - PUC-Rio 31 perspective. Variables and Data Types 6 GLSL A good place to start for learning GLSL is to discuss the data types available to you. There are only four: integers (both signed and unsigned), floats (single precision only as of OpenGL 3.3), and Booleans (bool). There are no pointers in GLSL, and there are no strings or characters of any kind. Functions can return any of these data types but can also be declared as void, but again, no void pointers allowed. The use of these data types in GLSL mirrors their usage in C/C++. • Tipos de variáveis 232 232 bool bDone = false; // Boolean true or false int iValue = 42; // Signed integer CHAPTER 6 Thinking Outside Box: Nonstock uint uiValue = 3929u; //the unsigned integer Shaders float fValue = 42.0f; // Floating point value CHAPTER 6 Thinking Outside the Box: Nonstock Shaders TABLE Vector 6.1 Types GLSL Vector Data Types • Tipos de vetores built-in AnTypes exciting and unique feature of GLSL (as compared to C/C++) is the availability of Description vector dataGLSL types.Vector All four of the basic data types can be stored in two-, three-, or fourTABLE 6.1 Data Types vec2, vec3, vec4 2, 3, and 4 component floating-point vectors dimensional vectors. TheDescription complete list of vector data types is listed in Table 6.1. Types ivec2, ivec3, ivec4 2, 3, and 4 component integer vectors vec2, vec3,uvec3, vec4 uvec4 2, 3, 4 component floating-point vectors vectors uvec2, 2,and 3, and 4 component unsigned integer ivec2, ivec3, ivec4bvec4 2, 3, 4 component integer vectors bvec2, bvec3, 2,and 3, and 4 component Boolean vectors uvec2, uvec3, uvec4 2, 3, and 4 component unsigned integer vectors bvec2, bvec3, bvec4 2, 3, and 4 component Boolean vectors A vector data type can be declared just like any other kind of variable; for example, you would declare a vertex position as a four-component floating-point vector like this: A vector data type can be declared just like any other kind of variable; for example, you vec4 declare vVertexPos; would a vertex position as a four-component floating-point vector like this: • Construtores vec4 YouvVertexPos; can also initialize a vector with a constructor: Download from www.wowebook.com vec4 = vec4(39.0f, 0.0f, 1.0f); You canvVertexPos also initialize a vector with10.0f, a constructor: vec4 vVertexPos = vec4(39.0f, 10.0f, 0.0f, 1.0f); This should not be confused with C++ class constructors. GLSL vector data types are not classes; they are their own built-in data type. Vectors can be assigned to one another, This should not be confused with C++ class constructors. GLSL vector data types are not added together, scaled by a scalar (nonvector type), and so on. classes; they are their own built-in data type. Vectors can be assigned to one another, INF2610 - W. Celes - PUC-Rio vVertexPos = scaled vOldPos vOffset; added together, by +a scalar (nonvector type), and so on. 32 classes; they are their own built-in data type. Vectors can be assigned to one another, GLSL added together, scaled by a scalar (nonvector type), and so on. vVertexPos = vOldPos + vOffset; added together, scaled by a scalar (nonvector type), and so on. vVertexPos = vNewPos; vVertexPos = vOldPos + vOffset; vVertexPos += vOldPos vec4(1.0f, 1.0f, 0.0f, 0.0f); vVertexPos + vOffset; vVertexPos == vNewPos; vVertexPos *= 5.0f; vVertexPos = vNewPos; vVertexPos += vec4(1.0f, 1.0f, 0.0f, 0.0f); vVertexPos += 5.0f; vec4(1.0f, 1.0f, 0.0f, 0.0f); vVertexPos *= Another unique feature to GLSL is how we can address individual elements of a vector. If vVertexPos *= 5.0f; you are familiar with the union construct from C/C++, vectors are like unions on steroids. • Vetores built-in Another unique feature to GLSL is how we can address individual elements of a vector. If We dot notation tofrom four vector elements, can use the If Another unique feature to address GLSL isup how we can address individual elements of aof vector. youuse are the familiar with the to union construct C/C++, vectors arebut likewe unions onany steroids. following three sets of identifiers: xyzw, rgba, or stpq. Typically we would use the xyzw set We use dot notation to union addressconstruct up to fourfrom vector elements, but are we can any of you arethe familiar with the C/C++, vectors likeuse unions onthe steroids. of identifiers when referring to vertex type data. following three of identifiers: xyzwup , rgba or stpq . Typically we would theuse xyzw setof the We use the dotsets notation to address to ,four vector elements, but weuse can any of identifiers when referring to vertexxyzw type data., or stpq. Typically we would use the xyzw set following three sets of identifiers: , rgba vVertexPos.x = 3.0f; vVertexPos.xy = vec2(3.0f, 5.0f); of identifiers =when vVertexPos.x 3.0f;referring to vertex type data. • Sufixos: xyzw, rgba, stpq vVertexPos.xyz = vNewPos.xyz; GLSL 101 vVertexPos.xy = = 3.0f; vec2(3.0f, 5.0f); vVertexPos.x vVertexPos.xyz = = vNewPos.xyz; vVertexPos.xy vec2(3.0f, 5.0f); Then rgba when doing color work. vVertexPos.xyz = vNewPos.xyz; The of which setcolor of identifiers you use is completely arbitrary as far as GLSL is Thenchoice rgba when work. vOutputColor.r =doing 1.0f; GLSL 101 233 concerned; for example, you could easily do something like this: vOutputColor.rgba = vec4(1.0f, 1.0f, 0.5f, 1.0f); Then rgba when doing color work. vOutputColor.r = 1.0f; 233 vOutputColor.rgba = vec4(1.0f, 1.0f, 0.5f, 1.0f); vTexCoord.st = vVertex.st; vOutputColor.r 1.0f; with texture coordinates, stpq. And finally, when= working The choice of which set of identifiers you use is completely arbitrary as far as GLSL is vOutputColor.rgba = vec4(1.0f, 1.0f, 0.5f, 1.0f); And finally, when working coordinates, stpq . within a single vector access, concerned; for youwith could easily do something this: However, what you cannot do istexture mix the different like groups vTexCoord.st = example, vec2(1.0f, 0.0f); such as this: == vec2(1.0f, vTexCoord.st vVertex.st; 0.0f); vTexCoord.st And finally, when working with texture coordinates, stpq. vTexCoord.st = vVertex.xt; // mixing of x and t is not allowed! However, what=you cannot do is0.0f); mix the different groups within a single vector access, vTexCoord.st vec2(1.0f, such as this: Vector data types also support swizzling. A swizzle is when you swap two or more vector vTexCoord.st = vVertex.xt; // mixing of x and t is not allowed! elements. For example, if you were converting color data from RGB ordering to BGR ordering, the data following linesupport of code wouldAdo the trick: Vector types also swizzling. swizzle is when you swap two or more vector Download from www.wowebook.com elements. For example, if you were converting color data from RGB ordering to BGR order- • Swizzling vNewColor.bgra = vOldColor.rgba; ing, the following line of code would do the trick: Download from www.wowebook.com vNewColor.bgra = are vOldColor.rgba; Vector data types not only native to GLSL, they are native to the hardware. They are Download from www.wowebook.c fast, and operations are performed on all the components at once. For example, the Vector data types are not only native to GLSL, they are native to the hardware. They are following operationare performed on all the components at once. For example, the fast, and operations following operation - W. Celes - PUC-Rio vVertex.x = vOtherVertex.x INF2610 + 5.0f; 33 Matrix Types In addition to the vector data types, GLSL supports a number of matrix types. Unlike the vector types, however, the matrix types are all floating-point only—sorry, no integer or Boolean matrices, as these are not practically useful. Table 6.2 lists the supported matrix types. GLSL • Matrizes built-in TABLE 6.2 Type 234 234 GLSL Matrix Types Description mat2, mat2x2 2 columns and 2 rows mat3, mat3x3 3 columns and 3 rows mat4, mat4x4 4 columns and 4 rows CHAPTER the Box:and Nonstock mat2x3 6 Thinking Outside 2 columns 3 rows Shaders mat2x4 2 columns and 4 rows mat3x2 3 columns and 2 rows 3 columns and 4 rows Amat3x4 matrix is essentially an array of vectors in GLSL—column vectors, in fact (a review of mat4x2 4 columns and 2 rows 4, “Basic Transformations: A Vector/Matrix column vector Outside ordering CHAPTERmajor 6 Thinking thefrom Box:Chapter Nonstock Shaders mat4x3 may be in order here). 4 columns 3 rows to set the last column of a 4 x 4 matrix, you Primer,” For and example, would write code similar to this: A matrix is essentially an array of vectors GLSL—column vectors, in fact (a review of mModelView[3] = vec4(0.0f, 0.0f, 0.0f, in 1.0f); • Essencialmente, array de vetores por coluna column major vector ordering from Chapter 4, “Basic Transformations: A Vector/Matrix Primer,” may in order For example, to set the last column of a 4 x 4 matrix, you Conversely, tobe retrieve thehere). last column of a matrix: Download from www.wowebook.c would write code similar to this: vec4 vTranslation = mModelView[3]; mModelView[3] = vec4(0.0f, 0.0f, 0.0f, 1.0f); Or even a finer grained query: Conversely, to retrieve the last column of a matrix: vec3 vTranslation = mModelView[3].xyz; vec4 vTranslation = mModelView[3]; Matrices can be multiplied by vectors too; a common use of this is to transform a vertex Or the even a finer grained query: by ModelViewProjection matrix, such as: vec3 vTranslation = mModelView[3].xyz; vec4 vVertex; INF2610 - W. Celes - PUC-Rio mat4 mvpMatrix; 34 Matrices can be multiplied by vectors too; a common use of this is to transform a vertex Matrices can be multiplied bymatrix, vectorssuch too; as: a common use of this is to transform a vertex by the ModelViewProjection by the ModelViewProjection matrix, such as: GLSL 234 vec4 vVertex; vec4 mat4 vVertex; mvpMatrix; mat4 mvpMatrix; CHAPTER 6 Thinking Outside the Box: Nonstock Shaders … …… …vOutPos = mvpMatrix * vVertex; vOutPos vVertex; A matrix= ismvpMatrix essentially* an array of vectors in GLSL—column vectors, in fact (a review of • Matrizes built-in • Also, justmajor like vectors, the matrix data types have theirTransformations: own constructorsAtoo. For example, column vector ordering from Chapter 4, “Basic Vector/Matrix Also, justcode like an vectors, the matrix data types their constructors example, to hard 4 xhere). 4 matrix, you canhave write code likecolumn this: Primer,” may be inline in order For example, to set theown last of a 4too. x 4For matrix, you to hard code an inline 4 x 4 matrix, you can write code like this: would write code similar to this: Construtores mat4 vTransform = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, mat4 vTransform= =vec4(0.0f, mat4(1.0f, 0.0f, 0.0f, 0.0f, mModelView[3] 0.0f, 0.0f, 1.0f); 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f); 0.0f, 0.0f, Conversely, to retrieve the last 0.0f, column of a matrix: 0.0f, 0.0f, 0.0f, 1.0f); vec4 = the mModelView[3]; In thisvTranslation case we made transformation matrix the identity matrix. A quicker constructor forthis matrices that fills the in just the diagonalmatrix with athe single valuematrix. can alsoA be used. constructor In case we made transformation identity quicker Or matrices even a finer query: for thatgrained fills in just the diagonal with a single value can also be used. mat4 vTransform = mat4(1.0f); vec3 vTranslation = mModelView[3].xyz; mat4 vTransform = mat4(1.0f); com vetores • Operações Storage Qualifiers Matrices can be multiplied by vectors too; a common use of this is to transform a vertex by the ModelViewProjection matrix, such as:have a storage qualifier specified. Qualifiers Shader variable declarations may optionally Storage Qualifiers are used to flag variables as input variables (in or uniform), output variables (out), or Shader variable declarations may optionally have a storage qualifier specified. Qualifiers vec4 vVertex; constants (const). Input variables receive data either from the OpenGL client (attributes are used to flag variables as input variables (in or uniform), output variables (out), or mat4 mvpMatrix; submitted via C/C++) or from the previous shader stage (for example, variables passed constants (const). Input variables receive data either from the OpenGL client (attributes … from the vertex shader to the fragment shader). Output variables are variables you write to submitted via C/C++) or from the previous shader stage (for example, variables passed … in any of the shader stages that you want to be seen by the subsequent shader stages, for from the =vertex shader* to the fragment shader). Output variables are variables you write to vOutPos mvpMatrix vVertex; example, passing data from the vertex shader to the fragment shader or writing the final in any of the shader stages that you want to be seen by the subsequent shader stages, for fragment color by the fragment shader. Table 6.3 lists the primary variable qualifiers. example, data from the vertex to the fragment shader or writing the final Also, justpassing like vectors, the matrix data shader types have their own constructors too. For example, fragment coloranbyinline the fragment shader. 6.3 lists thelike primary to hard code 4 x 4 matrix, youTable can write code this: variable qualifiers. INF2610 - W. Celes - PUC-Rio mat4 vTransform = mat4(1.0f, 0.0f, 0.0f, 0.0f, 35 ?$%	+5296$+',$GJ&9#66-2'6 GLSL • Operadores ?;7 %	+5296 M*-(KN-+OP(H*9"#+?(P9+?79?-(*9.($*-(C%22%<#+?(%N-&9$%&.5 K9#:#,#':# %	+529$41+66 ((4(e*#?*-.$f N9&-+$*-$#/92(?&%7N#+? O*P ((((((W6 M*N O*P , GG**AA P-C$($%(=#?*$ A 9&&9I(.7Y./&#N$ C7+/$#%+(/922(9+"(/%+.$&7/$%&(.$&7/$7&-( C#-2"(%&(@-$*%"(.-2-/$%&0(.<#__2-& N%.$(C#Q(#+/&-@-+$(9+"("-/&-@-+$ N&-C#Q(#+/&-@-+$(9+"("-/&-@-+$ 7+9&I GG**AA G**A**V**X =#?*$($%(P-C$ F E @72$#N2#/9$#:- I***H****J P-C$($%(=#?*$ D 9""#$#:- G**A P-C$($%(=#?*$ G Y#$X<#.-(.*#C$ KK****LL P-C$($%(=#?*$ T &-29$#%+92 K****L****KW***LW P-C$($%(=#?*$ U -]792#$I WW***XW P-C$($%(=#?*$ [ Y#$X<#.-(9+"( U P-C$($%(=#?*$ 4J Y#$X<#.-(-Q/27.#:-(%&( S P-C$($%(=#?*$ 44 Y#$X<#.-(#+/27.#:-(%&( T P-C$($%(=#?*$ 4A 2%?#/92(9+" UU P-C$($%(=#?*$ 4F 2%?#/92(-Q/27.#:-(%& SS P-C$($%(=#?*$ 4E 2%?#/92(#+/27.#:-(%& T*T P-C$($%(=#?*$ 4D .-2-/$#%+ [*Y =#?*$($%(P-C$ 6..#?+@-+$ 9&#$*@-$#/(9..#?+@-+$. =#?*$($%(P-C$ W GW**AW IW**HW JW****KKW***LLW UW**SW**TW .-]7-+/- D 4G 4T(e2%<-.$f %	+5296 INF2610 - W. Celes - PUC-Rio N662:-+5->-5C P-C$($%(=#?*$ M*-&-(#.(+%(9""&-..X%C(%N-&9$%&(+%&(9("-&-C-&-+/-(%N-&9$%&5((M*-&-(#.(+%($IN-/9.$(%N-&9$%&i(/%+.$&7/$%&.( 36 GLSL GLSL 101 • 235 Qualificadores de tipos • • TABLE variável 6.3 Variable Storage <none>: local, sem Qualifiers visibilidade externa in • • • • Description <none> const Just a normal local variable, no outside visibility or access. A compile-time constant, or a read-only parameter to a function. in A variable passed in from a previous stage. Global: variável passada por estágio anterior in centroid Passed in from a previous state, uses centroid interpolation. Parâmetro: variável local regular out • • Qualifier out Passed out to the next processing stage or assigned a return value in a function. out centroid Passed out to the next processing stage, uses centroid interpolation. A read/write variable. Only valid for local function parameters. inout Global: variável passada para próximo estágio uniform Value is passed in from client code and does not change across vertices. Parâmetro: variável de saída One variable qualifier inout can only be used when declaring a parameter to a function. inout Because GLSL does not support pointers (or references), this is the only way to pass a value to a function and allow the function to modify and return the value of the same variable. variável de entrada e saída • Parâmetro: For example, this function declaration int CalculateSometing(float fTime, float fStepSize, inout float fVariance); • const would return an integer (perhaps a pass/fail flag), but also could modify the value of the fVariance variable, and the calling code could read the new value back from the variable Global: constante para tempo de compilação as well. In C/C++, to allow modification of a parameter, you might well declare the function this way using a pointer: Parâmetro: read-only 6 • • int CalculateSomething(float fTime, float fStepSize, float* fVariance); INF2610 - W. Celes - PUC-Rio The centroid qualifier has no effect unless rendering is being done to a multisampled 37 GLSL as well. In C/C++, to allow modification of a parameter, you might well tion this way using a pointer: int CalculateSomething(float fTime, float fStepSize, float* fVaria • QualificadoresThe centroid qualifier has no effect unless rendering is being done to a • buffer. In a single sampled buffer, interpolation is always performed from Especificaçãopixel. de interpolação entre estágios With multisampling, when the centroid qualifier is used, the inte sointerpolados that it falls within the primitive and the pixel. See Chapter 9 smooth: com correção perspectiva • <none>,selected Buffers: Beyond the Basics,” for more details about how multisampling w interpolados linearmente • noperspective: By default parameters are interpolated between shader stages in a perspe manner. You can specify nonperspective interpolation with the nopersp • flat: não interpolados even no interpolation at all with the flat keyword. You can also option usado em interpolação para multi-samples • centroid:keyword to explicitly state the variable is smoothly interpolated in a per manner, but that is already the default. Here are a few example declarat smooth out vec3 vSmoothValue; flat out vec3 vFlatColor; noperspective float vLinearlySmoothed; INF2610 - W. Celes - PUC-Rio 38 GLSL • Variáveis built-in • Vertex shader • in int gl_VertexID; • in int gl_InstanceID; • out vec4 gl_Position; • out float gl_PointSize; • out float gl_ClipDistance[]; OpenGL 2.*: Vertex shader in: attribute out: varying Fragment shader in: varying • Fragment shader • • • • • • • • • • • • in vec4 gl_FragCoord; in bool gl_FrontFacing; in float gl_ClipDistance; in float gl_PointSize; in float gl_ClipDistance[]; in int gl_PrimitiveID; in int gl_SampleID; in vec2 gl_SamplePosition; out vec4 gl_FragColor; out vec4 gl_FragData[]; out float gl_FragDepth; out int gl_SampleMask[]; INF2610 - W. Celes - PUC-Rio 39 GLSL • Exemplo de shader • Vertex shader #version 330 in vec4 vVertex; in vec4 vColor; out vec4 vVaryingColor; // Vertex position attribute // Vertex color attribute // Color value passed to fragment shader void main(void) { vVaryingColor = vColor; gl Position = vVertex; } CHAPTER 6 240 Thinking Outside the Box: Nonstock Shaders // Simply copy the color value // Simply pass along the vertex position • Fragment shader #version 330 in vec4 vVaryingColor; void main(void) { gl FragColor = vVaryingColor; } // Interpolated color to fragment FIGURE 6.2 INF2610 - W. Celes - PUC-Rio Output from the ShadedTriangle program. 40 Shader Uniforms GLSL uniform mat4 mvpMatrix; While attributes are needed for per-vertex positions, surface normals, texture coordinates, // Incoming per vertex and so on, a uniform is how we pass data into a shader that stays the same—is uniform— in vec4 vVertex; for the entire primitive batch. Probably the single most common uniform for a vertex shader is the transformation matrix. Previously, we allowed the GLShaderManager class to void main(void) do this for us, with built-in support for the stock shaders and their needed uniforms. Now { that we are writing our own shaders, we need to be able to set our own uniforms, and not // This is pretty much it, transform the geo just for matrix values; any shader variable can be specified as a uniform, and uniforms can gl_Position = mvpMatrix * vVertex; be in any of the three shader stages (even though we only talk about vertex and fragment } shaders in this chapter). Making a uniform is as simple as placing the keyword uniform at the beginning of the variable declaration: 6 • Variáveis uniforms • Constantes por primitivas de desenho uniform uniform uniform uniform float fTime; int iIndex; vec4 vColorValue; mat4 mvpMatrix; LISTING 6.5 The Flat Shader Fragment Program // Flat Shader // Fragment Shader // Richard S. Wright Jr. Shader Uniforms // OpenGL SuperBible Uniforms cannot be marked as in or out, they cannot be interpolated (although you can #version 130 • Exemplo: flat shader 253 copy them into interpolated variables) between shader stages, and they are always readonly. // Make geometry solid uniform vec4 vColorValue; // Transformation Matrix uniform mat4 mvpMatrix; Finding Your Uniforms // Output fragment colorin the After a shader has been compiled and linked, you must “find” the uniform location // Incoming per vertex out. vec4 vFragColor; shader. This is done with the function glGetUniformLocation in vec4 vVertex; GLint glGetUniformLocation(GLuint shaderID, const GLchar* varName); void main(void) void main(void) { { gl_FragColor = vColorValue; // This is pretty much it, transform the geometry } gl_Position = mvpMatrix * vVertex; } INF2610 - W. Celes - PUC-Rio In the vertex program shown in Listing 6.4 we have 41 transformation matrix. GLSL CHAPTER 6 256 • Thinking Outside the Box: Nonstock Shaders Funções built-in Trigonometry Functions Table 6.4 lists the trigonometry functions that are supported by GLSL. These functions are trigonométricas • Funções • defined for float, vec2, vec3, and vec4 data types. Here we denote the data type by anyFloat, meaning anyvec2, of thesevec3, four floating-point anyFloat: float, vec4 data types. TABLE 6.4 Trigonometric Functions a componente • Componente Function Description anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat anyFloat Converts degrees to radians Converts radians to degrees Trigonometric sine Trigonometric cosine Trigonometric tangent Arc sine Arc cosine Arc tangent of y / x Arc tangent of y_over_x Hyperbolic sine Hyperbolic cosine Hyperbolic tangent Arc hyperbolic sine Arc hyperbolic cosine Arc hyperbolic tangent radians(anyFloat degrees) degrees(anyFloat radians) sin(anyFloat angle) cos(anyFloat angle) tan(anyFloat angle) asin(anyFloat x) acos(anyFloat x) atan(anyFloat y, anyFloat x) atan(anyFloat y_over_x) sinh(anyFloat x) cosh(anyFloat x) tanh(anyFloat x) asinh(anyFloat x) acosh(anyFloat x) atanh(anyFloat x) Exponential Functions INF2610 - W. Celes - PUC-Rio 42 GLSL anyFloat acosh(anyFloat x) Arc hyperbolic cosine anyFloat atanh(anyFloat x) Arc hyperbolic tangent Exponential Functions Like the trigonometric functions, the exponential functions work on the floating-point data types (floats and floating-point vectors). The complete list of exponential functions is given in Table 6.5. • Funções built-in TABLE 6.5 Exponential Functions de exponenciação • Funções Function Description Built-In Functions 257 anyFloat pow(anyFloat x, anyFloat y) x raised to the y power anyFloat exp(anyFloat x) Natural exponent of x Geometric Functions anyFloat log(anyFloat x) The natural logarithm of x x) raised to the x A anyFloat numberexp2(anyFloat of general purpose geometric 2functions arepower also of included in GLSL. Some of anyFloat log2(anyFloat ) Base 2(cross logarithm of x for example); others accept these functions have angle specific argument types product anyFloat x) Square root, of x vec4), which we refer to here only any of thesqrt(anyFloat floating-point vector types (vec2 , vec3 and inversesqrt(anyFloat Inverse asanyFloat vec. These functions arex)listed in Table 6.6. square root of x TABLE 6.6 Geometric Functions geométricas • Funções Function Description float length(vec2/vec3/vec4 x) float distance(vec p0, vec p1) Returns the length of the vector x Returns the distance between p0 and p1 float dot(vec x, vec y) vec3 cross(vec3 x, vec3 y) Returns the dot product of x and y Returns the cross product of x and y vec normalize(vec x) vec faceforward(vec N, vec I, vec nRef) Returns a unit length vector in the same direction as x Download from www.wowebook.com if dot(Nref, I) < 0 return N, else return –N vec reflect(vec I, vec N) Returns reflection direction for incident vector I and vec refract(vec I, vec N, float eta) surface orientation N Returns refraction vector for incident vector I, surface orientation N, and ratio of indices of refraction eta Matrix Functions INF2610 - W. Celes - PUC-Rio 43 6 surface orientation N vec refract(vec I, vec N, float eta) GLSL Returns refraction vector for incident vector I, surface orientation N, and ratio of indices of refraction eta Matrix Functions • Funções algébricas TABLE 6.7 6 • Funções built-in Many matrix operations are done using the regular mathematical operators. Some useful matrix functions, however, are listed in Table 6.7. Each of these functions is specific and takes a specific argument data type, which is shown in the table. Matrix Functions Function Description mat matrixCompMult(mat x, mat y) Multiplies two matrices together component by component. This is not the same as the linear algebraic matrix multiply. Returns a matrix that is the outer product of the two vectors specified. mat2 outerProduct(vec2 c, vec2 r) mat3 outerProduct(vec3 c, vec3 r) mat4 outerProduct(vec4 c, vec4 r) mat2x3 outerProduct(vec3 c, vec2 r) mat3x2 outerProduct(vec2 c, vec3 r) mat2x4 outerProduct(vec4 c, vec2 r) mat4x2 outerProduct(vec2 c, vec4 r) mat3x4 outerProduct(vec4 c, vec3 r) mat4x3 outerProduct(vec3 c, vec4 r) Download from www.wowebook.com INF2610 - W. Celes - PUC-Rio 44 GLSL • Funções built-in 258 CHAPTER 6 Thinking Outside the Box: Nonstock Shaders TABLE 6.7 algébricas Matrix Functions • Funções continued Function Description mat2 transpose(mat2 m) mat3 transpose(mat3 m) mat4 transpose(mat4 m) mat2x3 transpose(mat3x2 mat3x2 transpose(mat2x3 mat2x4 transpose(mat4x2 mat4x2 transpose(mat2x4 mat3x4 transpose(mat4x3 mat4x3 transpose(mat3x4 Returns a matrix that is the transpose of the matrix specified. m) m) m) m) m) m) float determinant(mat2 m) float determinant(mat3 m) float determinant(mat4 m) Returns the determinant of the matrix specified. mat2 inverse(mat2 m) mat3 inverse(mat3 m) mat4 inverse(mat4 m) Returns a matrix that is the inverse of the matrix specified. Vector Relational Functions Scalar values can be compared using the standard equality operators (<, <=, >, >=, ++, !=). For vector comparisons, the functions listed in Table 6.8 are provided. All of these functions return a Boolean vector of the same number of dimensions as the arguments. TABLE 6.8 Vector Relational Functions INF2610 - W. Celes - PUC-Rio 45 float determinant(mat4 m) GLSL mat2 inverse(mat2 m) Returns a matrix that is the inverse of the matrix specified. mat3 inverse(mat3 m) mat4 inverse(mat4 m) ptg • Vector Relational Functions Funções built-in Scalar values can be compared using the standard equality operators (<, <=, >, >=, ++, !=). For vector comparisons, the functions listed in Table 6.8 are provided. All of these functions return a Boolean vector of the same number of dimensions as the arguments. • Funções relacionais para vetores TABLE 6.8 Vector Relational Functions Function Description bvec lessThan(vec x, vec y) bvec lessThan(ivec x, ivec y) Returns component by component the result of x < y. bvec lessThan(uvec x, uvec y) bvec lessThanEqual(vec x, vec y) Returns component by component the result of x <= y. bvec lessThanEqual(ivec x, ivec y) bvec lessThanEqual(uvec x, uvec y) Built-In Functions bvec greaterThan(vec x, vec y) bvec greaterThan(ivec x, ivec y) bvec greaterThan(uvec x, uvec y) Function Returns component by component the result of x > y. bvec greaterThanEqual(vec x, vec y) bvec greaterThanEqual(ivec x, ivec y) Returns component by component the result of x >= y. 259 Description bvec greaterThanEqual(uvec x, uvec y) bvec equal(vec x, vec y) Returns component by component the result of x == y. bvec equal(ivec x, ivec y) bvec equal(uvec x, uvec y) Download from www.wowebook.com bvec equal(bvec x, bvec y) bvec bvec bvec bvec notEqual(vec x, vec y) notEqual(ivec x, ivec y) notEqual(uvec x, uvec y) notEqual(bvec x, bvec y) Returns component by component the result of x != y. bool any(bvec x) bool all(bvec x) Returns true if any component of x is true. Returns true if all components of x are true. bvec not(bvec x) Returns component wise complement of x. INF2610 - W. Celes - PUC-Rio 46 bvec notEqual(bvec x, bvec y) GLSL bool any(bvec x) bool all(bvec x) bvec not(bvec x) Returns true if any component of x is true. Returns true if all components of x are true. Returns component wise complement of x. Common Functions • Funções built-in p 6 Finally we present the list of general purpose functions. All of these functions work on and return both scalar and vector data types (see Table 6.9). • Funções gerais TABLE 6.9 Common Functions Function Description anyFloat abs(anyFloat x) anyInt abs(anyInt x) Returns the absolute value of x. anyFloat sign(anyFloat x) Returns 1.0 or -1.0 depending on the sign of x. anyInt sign(anyInt x) anyFloat floor(anyFloat x) anyFloat trunc(anyFloat x) anyFloat round(anyFloat x) anyFloat roundEven(anyFloat x) anyFloat ceil(anyFloat x) anyFloat fract(anyFloat x) Returns the lowest whole number not larger than x. Returns the nearest whole number not larger than the absolute value of x. Returns the value of the nearest integer to x. The fraction 0.5 may round in either direction. (This is implementation-dependent.) Returns the value of the nearest integer to x. The fraction 0.5 rounds to the nearest even integer. Returns the value of the nearest integer greater than x. Returns the fractional part of x. Download from www.wowebook.com INF2610 - W. Celes - PUC-Rio 47 GLSL • Funções built-in 260 CHAPTER 6 Thinking Outside the Box: Nonstock Shaders TABLE 6.9gerais Common Functions • Funções continued Function Description anyFloat mod(anyFloat x, float y) anyFloat mod(anyFloat x, anyFloat y) Returns the modulus of x mod y. anyFloat modf(anyFloat x, out anyFloat i) Returns the fractional part of x and sets i to be the integer remainder. anyFloat min(anyFloat x, anyFloat y) Returns the smaller of x and y. anyFloat min(anyFloat x, float y) anyInt min(anyInt x, anyInt y) anyInt min(anyInt x, int y) anyUInt min(anyUInt x, anyUInt y) anyUint min(anyUInt x, uint y) anyFloat max(anyFloat x, anyFloat y) anyFloat max(anyFloat x, float y) anyInt max(anyInt x, anyInt y) anyInt max(anyInt x, int y) anyUInt max(anyUInt x, anyUInt y) anyUint max(anyUInt x, uint y) Returns the larger of x and y. anyFloat clamp(anyFloat x, anyFloat minVal, anyFloat maxVal) Returns x clamped to the range minVal to maxVal. anyFloat clamp(anyFloat x, float minVal, INF2610 - W. Celes - PUC-Rio 48 GLSL anyInt min(anyInt x, anyInt y) anyInt min(anyInt x, int y) anyUInt min(anyUInt x, anyUInt y) anyUint min(anyUInt x, uint y) anyFloat max(anyFloat x, anyFloat y) anyFloat max(anyFloat x, float y) Returns the larger of x and y. • Funções built-in anyInt max(anyInt x, anyInt y) anyInt max(anyInt x, int y) anyUInt max(anyUInt x, anyUInt y) anyUint max(anyUInt x, uint y) • Funções gerais anyFloat clamp(anyFloat x, anyFloat minVal, Returns x clamped to the range minVal to maxVal. anyFloat maxVal) anyFloat clamp(anyFloat x, float minVal, float maxVal); anyInt clamp(anyInt x, anyInt minVal, anyInt maxVal) anyInt clamp(anyInt x, int minVal, int maxVal) anyUint clamp(anyUint x, anyUint minVal, anyUint maxVal); anyUint clamp(anyUint x, uint minVal, uint maxVal) INF2610 - W. Celes - PUC-Rio 49 GLSL • Funções built-in • Funções gerais Function anyFloat mix(anyFloat x, Built-In Functions 261 Description Returns the linear blend of x and y, as a varies from 0 to 1 anyFloat y, anyFloat a) anyFloat mix(anyFloat x, anyFloat y, float a) anyFloat mix(anyFloat x, anyFloat y, anyBool a) Returns the components of x where a is false and the components of y where a is true. anyFloat step(anyFloat edge, anyFloat x) Returns 0.0 if x is less than edge, or 1.0 otherwise. anyFloat step(float edge, anyFloat x) anyFloat smoothstep(anyFloat edge0, Returns 0.0 if x <= edge0, and 1.0 if x >= edge1, and a anyFloat edge1, smooth Hermite interpolation between 0.0 and 1.0 in between. anyFloat x) anyFloat smoothStep(float edge0, float edge1, anyFloat x) ptg Returns true if x is Nan. anyBool isinf(anyFloat x) Returns true if x is positive or negative infinity. anyInt floatBitsToInt(anyFloat x) anyUint floatBitsToUint(anyFloat x) Converts floating-point values to integer values. anyFloat intBitsToFloat(anyInt x) anyFloat uintBitsToFloat(anyUint x) Converts integers to floating-point values. INF2610 - W. Celes - PUC-Rio 6 anyBool isnan(anyFloat x) 50 GLSL Simulatin • Exemplo: iluminação difusa por vértice // diffuse ilumination in vec4 vVertex; in vec3 vNormal; uniform uniform uniform uniform uniform vec4 vec3 mat4 mat4 mat3 diffuseColor; vLightPosition; mvpMatrix; mvMatrix; normalMatrix; smooth out vec4 vVaryingColor; void main(void) { vec3 vEyeNormal = normalMatrix ⇥ vNormal; FIGURE 6.6 The DiffuseLight example program. vec4 vPosition4 = mvMatrix ⇥ vVertex; vec3 vPosition3 = vPosition4.xyz / vPosition4.w; The ADS Light Model vec3 vLightDir = normalize(vLightPosition One of the mostPosition3); common lighting models, especially to those familiar with the now float diff = max(0.0, dot(vEyeNormal, vLightDir)); deprecated fixed function pipeline, is the ADS lighting model. ADS stands for Ambie vVaryingColor.xyz = diff ⇥ diffuseColor.xyz; Diffuse, and Specular. It works on a simple principle, which is that objects have three material properties, which are the Ambient, Diffuse, and Specular reflectivity. These p vVaryingColor.a = 1.0; } gl Position = mvpMatrix ⇥ vVertex; erties are assigned color values, with brighter colors representing a higher amount of reflectivity. Light sources have these same three properties and are again assigned col values that represent the brightness of the light. The final color value of a vertex is t the sum of the lighting and material interactions of these three properties. Ambient Light Ambient light doesn’t come from any particular direction. It has an original source s INF2610 - W. Celes - PUC-Riowhere, but the rays of light have bounced around the room or scene and 51 become dir For a given triangle, there are only three vertices and many more fragments that fill o the triangle. This makes vertex lighting and Gouraud shading very efficient, as all the computations are done only once per vertex. Figure 6.7 shows the output of the ADSGouraud example program. GLSL • Exemplo: iluminação ADS por vértice in vec4 vVertex; in vec3 vNormal; uniform uniform uniform uniform vec4 vec4 vec4 vec3 ambientColor; diffuseColor; specularColor; vLightPosition; void main (void) { FIGURE 6.7 Per-vertex-based lighting (Gouraud shading). vec3 vEyeNormal = normalMatrix ⇥ vNormal; vec4 vPosition4 = mvMatrix ⇥ vVertex; Phong Shading / vPosition4.w; vec3 vPosition3 = vPosition4.xyz One of the drawbacks to Gouraud shading is clearly apparent in Figure 6.7. Note the s burst pattern of the specular highlight. On a still image, this might almost pass as an vec3 vLightDir = normalize(vLightPosition vPosition3); intentional artistic effect. The running sample program, however, rotates the sphere a float diff = max(0.0, shows dot(vEyeNormal, vLightDir)); a characteristic flashing that is a bit distracting and generally undesirable. This vVaryingColor = diff ⇥caused diffuseColor; by the discontinuity between triangles because the color values are being inter lated linearly through color space. The bright lines are actually the seams between ind vVaryingColor += ambientColor; ual triangles. One way to reduce this effect is to use more and more vertices in your vec3 vReflection = normalize(reflect( vLightDir, vEyeNormal)); geometry. Another, and higher quality, method is called Phong shading. With Phong float spec = max(0.0, shading, dot(vEyeNormal, vReflection)); instead of interpolating the color values between vertices, we interpolate the if(diff != 0) { surface normals between vertices. Figure 6.8 shows the output from the ADSPhong sa program (Figures 6.7 and 6.8 are shown side-by-side in Color Plate 5). float fSpec = pow(spec, 128.0); uniform mat4 mvpMatrix; uniform mat4 mvMatrix; uniform mat3 normalMatrix; smooth out vec4 vVaryingColor; } vVaryingColor.rgb += vec3(fSpec, fSpec, fSpec); } gl Position = mvpMatrix ⇥ vVertex; Download from w INF2610 - W. Celes - PUC-Rio 52 GLSL • Exemplo: iluminação ADS por pixel (Phong shading) • Vertex shader in vec4 vVertex; in vec3 vNormal; uniform uniform uniform uniform mat4 mat4 mat3 vec3 mvpMatrix; mvMatrix; normalMatrix; vLightPosition; smooth out vec3 vVaryingNormal; smooth out vec3 vVaryingLightDir; void main (void) { vVaryingNormal = normalMatrix ⇥ vNormal; vec4 vPosition4 = mvMatrix ⇥ vVertex; vec3 vPosition3 = vPosition4.xyz / vPosition4.w; vVaryingLightDir = normalize(vLightPosition vPosition3); gl Position = mvpMatrix ⇥ vVertex; } INF2610 - W. Celes - PUC-Rio 53 GLSL 274 CHAPTER 6 Thinking Outside the Box: Nonstock Shaders • Exemplo: iluminação ADS por pixel (Phong shading) • Fragment shader uniform vec4 ambientColor; uniform vec4 diffuseColor; uniform vec4 specularColor; in vec3 vVaryingNormal; in vec3 vVaryingLightDir; void main (void) { float diff = max(0.0, dot(normalize(vVaryingNormal), FIGURE 6.8 Per-pixel-based lighting (Phong shading). normalize(vVaryingLightDir))); The trade-off is of course we are now doing significantly more work in the fragment gl FragColor = diff ⇥ diffuseColor; program, which is going to be executed significantly more times than the vertex program gl FragColor += ambientColor; The basic code is the same as for the ADSGouraud example program, but this time there i vec3 vReflection = normalize(reflect( normalize(vVaryingLightDir), some significant rearranging of the shader code. Listing 6.10 shows the new vertex program. normalize(vVaryingNormal))); float spec = max(0.0, dot(normalize(vVaryingNormal), Reflection)); LISTING 6.10 ADSPhong Vertex Shader if(diff != 0) { // ADS Point lighting Shader float fSpec = pow(spec, 128.0); // Vertex Shader gl FragColor.rgb += vec3(fSpec, fSpec,// fSpec); Richard S. Wright Jr. // OpenGL SuperBible } #version 330 } // Incoming per vertex... position and normal in vec4 vVertex; in vec3 vNormal; INF2610 - W. Celes - PUC-Rio uniform mat4 mvpMatrix; 54 GLSL API • Programs & shaders • API para shader object uint glCreateShader (enum type); // type: {VERTEX,FRAGMENT,GEOMETRY} SHADER, TESS {EVALUATION,CONTROL} SHADER void glShaderSource (uint shader, sizei count, const char void glCompileShader (uint shader); void glDeleteShader (uint shader); string, const int length); • API para program object uint void void void void void glCreateProgram (void); glAttachShader (uint program, uint glDetachShader (uint program, uint glLinkProgram(uint program); glUseProgram(uint program); glDeleteProgram(uint program); shader); shader); INF2610 - W. Celes - PUC-Rio 55 GLSL API • API para atributos de vértices // Before linking void glBindAttribLocation (uint program, uint index, const char // After linking void glGetActiveAttrib (uint program, uint index, sizei bufSize, sizei length, int // type returns: FLOAT,FLOAT{VECn,MATn,MATnxm}, INT,INT VECn,UNSIGNED {INT,INT VECn} int glGetAttribLocation (uint program, const char name); name); size, enum type, char name); • API para carga de variáveis uniformes // After linking the program int glGetUniformLocation (uint program, const char ⇤name); // load uniform variables in default uniform block on bound program void glUniform{1234}{ifd} (int location, T value); void glUniform{1234}{ifd}v (int location, sizei count, T value); void glUniform{1234}ui (int location, T value); void glUniform{1234}uiv (int location, sizei count, T value); void glUniformMatrix{234}{fd}v (int location, sizei count, boolean transpose, const T value); void glUniformMatrix{2x3,3x2,2x4,4x2, 3x4,4x3}{fd}v (int location, sizei count, boolean transpose, const T INF2610 - W. Celes - PUC-Rio value); 56 Bibliografia • The OpenGL Graphics System: A Specification (Version 4.1 (Core Profile) - July 25, 2010) • Mark Segal, Kurt Akeley INF2610 - W. Celes - PUC-Rio 57