26 March 2015
Today, we want to share some best practices on using the OpenGL Shading Language (GLSL) that can optimize the performance of your game and simplify your workflow. Specifically, Layout qualifiers make your code more deterministic and increase performance by reducing your work.
attribute vec4 vertexPosition; attribute vec2 vertexUV; uniform mat4 matWorldViewProjection; varying vec2 outTexCoord; void main() { outTexCoord = vertexUV; gl_Position = matWorldViewProjection * vertexPosition; }
struct Vertex { Vector4 Position; Vector2 TexCoords; };Therefore, we defined our vertex shader attributes like this:
attribute vec4 vertexPosition; attribute vec2 vertexUV;To associate the vertex data with the shader attributes, a call to
glGetAttribLocation
will get the handle of the named attribute. The attribute format is then detailed with a call to glVertexAttribPointer
.GLint handleVertexPos = glGetAttribLocation( myShaderProgram, "vertexPosition" ); glVertexAttribPointer( handleVertexPos, 4, GL_FLOAT, GL_FALSE, 0, 0 ); GLint handleVertexUV = glGetAttribLocation( myShaderProgram, "vertexUV" ); glVertexAttribPointer( handleVertexUV, 2, GL_FLOAT, GL_FALSE, 0, 0 );But you may have multiple shaders with the vertexPosition attribute and calling
glGetAttribLocation
for every shader is a waste of performance which increases the loading time of your game.layout(location = 0) in vec4 vertexPosition; layout(location = 1) in vec2 vertexUV;To do so you also need to tell the shader compiler that your shader is aimed at GL ES version 3.1. This is done by adding a version declaration:
#version 300 esLet’s see how this affects our shader, changes are marked in bold:
#version 300 es layout(location = 0) in vec4 vertexPosition; layout(location = 1) in vec2 vertexUV; uniform mat4 matWorldViewProjection; out vec2 outTexCoord; void main() { outTexCoord = vertexUV; gl_Position = matWorldViewProjection * vertexPosition; }Note that we also changed outTexCoord from varying to out. The varying keyword is deprecated from version 300 es and requires changing for the shader to work.
#version 300 es
are supported from OpenGL ES 3.0. The desktop equivalent is supported on OpenGL 3.3 and using #version 330
.glGetAttribLocation
:const int ATTRIB_POS = 0; const int ATTRIB_UV = 1; glVertexAttribPointer( ATTRIB_POS, 4, GL_FLOAT, GL_FALSE, 0, 0 ); glVertexAttribPointer( ATTRIB_UV, 2, GL_FLOAT, GL_FALSE, 0, 0 );This simple change leads to a cleaner pipeline, simpler code and saved performance during loading time.