Difference between revisions of "GLSL : common mistakes"

From OpenGL Wiki
Jump to navigation Jump to search
Line 1: Line 1:
==== Enable Or Not To Enable ====
+
The following article discusses common mistakes made in the OpenGL Shading Language, GLSL.
With fixed pipeline, you needed to call glEnable(GL_TEXTURE_2D) to enable 2D texturing. You needed to call glEnable(GL_LIGHTING). Since shaders override these functionalities, you don't need to glEnable/glDisable. If you don't want texturing, you either need to write another shader that doesn't do texturing or you can attach a all white or all black texture, depending on your needs. You can also write one shader that does lighting and one that doesn't.
+
 
 +
__TOC__
 +
 
 +
== Enable Or Not To Enable ==
 +
With fixed pipeline, you needed to call <code>glEnable(GL_TEXTURE_2D)</code> to enable 2D texturing. You needed to call <code>glEnable(GL_LIGHTING)</code>. Since shaders override these functionalities, you don't need to glEnable/glDisable. If you don't want texturing, you either need to write another shader that doesn't do texturing or you can attach a all white or all black texture, depending on your needs. You can also write one shader that does lighting and one that doesn't.
  
 
Things that are not overriden by shaders, like the alpha test, depth test, stencil test... calling glEnable/glDisable will have an effect.
 
Things that are not overriden by shaders, like the alpha test, depth test, stencil test... calling glEnable/glDisable will have an effect.
  
==== Binding A Texture ====
+
== Binding A Texture ==
When you compile and link your GLSL shader, the next step is to get uniform locations for your samplers (I'm talking about texture samplers) and setup the samplers. Some people do this<br>
+
When you compile and link your GLSL shader, the next step is to get uniform locations for your samplers (I'm talking about texture samplers) and setup the samplers. Some people do this:
glUniformi(location, textureID)<br>
+
glUniformi(location, textureID)
You can't send a GL texture ID as your sampler. A sampler should be from 0 to the max number of texture image units.<br>
+
You can't send a GL texture ID as your sampler. A sampler should be from 0 to the max number of texture image units.
To bind a texture, always use glBindTexture.
+
To bind a texture, always use <code>glBindTexture</code>.
 +
 
 +
== Types ==
 +
nVidia drivers are more relaxed. You could do
 +
float myvalue = 0;
 +
but this won't compile on other platforms. Use 0.0 instead.
 +
Don't write <code>0.0f</code>. GLSL is not C or C++.
 +
 
 +
float texel = texture2D(tex, texcoord);
 +
The above is wrong since <code>texture2D</code> returns a <code>vec4</code>
 +
Do this instead
 +
float texel = float(texture2D(tex, texcoord));
 +
or
 +
float texel = texture2D(tex, texcoord).r;
 +
or
 +
float texel = texture2D(tex, texcoord).x;
 +
 
 +
== Functions ==
 +
Functions should look like this
 +
vec4 myfunction(inout float value1, in vec3 value2, in vec4 value3)
 +
instead of
 +
vec4 myfunction(float value1, vec3 value2, vec4 value3)
 +
 
 +
== Not Used ==
 +
In the vertex shader
 +
gl_TexCoord[0] = gl_MultiTexCoord0;
 +
and in the fragment shader
 +
vec4 texel = texture2D(tex, gl_TexCoord[0].xy);
  
==== Types ====
+
zw isn't being used in the fs.
nVidia drivers are more relaxed. You could do<br>
 
float myvalue = 0;<br>
 
but this won't compile on other platforms. Use 0.0 instead.<br>
 
Don't write 0.0f. GLSL is not C or C++.<br>
 
<br>
 
float texel = texture2D(tex, texcoord);<br>
 
The above is wrong since texture2D returns a vec4<br>
 
Do this instead<br>
 
float texel = float(texture2D(tex, texcoord));<br>
 
or<br>
 
float texel = texture2D(tex, texcoord).r;<br>
 
or<br>
 
float texel = texture2D(tex, texcoord).x;<br>
 
  
==== Functions ====
+
== Easy Optimization ==
Functions should look like this<br>
+
gl_TexCoord[0].x = gl_MultiTexCoord0.x;
vec4 myfunction(inout float value1, in vec3 value2, in vec4 value3)<br>
+
gl_TexCoord[0].y = gl_MultiTexCoord0.y;
instead of<br>
 
vec4 myfunction(float value1, vec3 value2, vec4 value3)<br>
 
  
==== Not Used ====
+
turns into
In the vertex shader<br>
+
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
gl_TexCoord[0] = gl_MultiTexCoord0;<br>
 
and in the fragment shader<br>
 
vec4 texel = texture2D(tex, gl_TexCoord[0].xy);<br>
 
<br>
 
zw isn't being used in the fs.<br>
 
<br>
 
==== Easy Optimization ====
 
gl_TexCoord[0].x = gl_MultiTexCoord0.x;<br>
 
gl_TexCoord[0].y = gl_MultiTexCoord0.y;<br>
 
<br>
 
turns into<br>
 
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;<br>
 

Revision as of 19:37, 3 April 2008

The following article discusses common mistakes made in the OpenGL Shading Language, GLSL.

Enable Or Not To Enable

With fixed pipeline, you needed to call glEnable(GL_TEXTURE_2D) to enable 2D texturing. You needed to call glEnable(GL_LIGHTING). Since shaders override these functionalities, you don't need to glEnable/glDisable. If you don't want texturing, you either need to write another shader that doesn't do texturing or you can attach a all white or all black texture, depending on your needs. You can also write one shader that does lighting and one that doesn't.

Things that are not overriden by shaders, like the alpha test, depth test, stencil test... calling glEnable/glDisable will have an effect.

Binding A Texture

When you compile and link your GLSL shader, the next step is to get uniform locations for your samplers (I'm talking about texture samplers) and setup the samplers. Some people do this:

glUniformi(location, textureID)

You can't send a GL texture ID as your sampler. A sampler should be from 0 to the max number of texture image units. To bind a texture, always use glBindTexture.

Types

nVidia drivers are more relaxed. You could do

float myvalue = 0;

but this won't compile on other platforms. Use 0.0 instead. Don't write 0.0f. GLSL is not C or C++.

float texel = texture2D(tex, texcoord);

The above is wrong since texture2D returns a vec4 Do this instead

float texel = float(texture2D(tex, texcoord));

or

float texel = texture2D(tex, texcoord).r;

or

float texel = texture2D(tex, texcoord).x;

Functions

Functions should look like this

vec4 myfunction(inout float value1, in vec3 value2, in vec4 value3)

instead of

vec4 myfunction(float value1, vec3 value2, vec4 value3)

Not Used

In the vertex shader

gl_TexCoord[0] = gl_MultiTexCoord0;

and in the fragment shader

vec4 texel = texture2D(tex, gl_TexCoord[0].xy);

zw isn't being used in the fs.

Easy Optimization

gl_TexCoord[0].x = gl_MultiTexCoord0.x;
gl_TexCoord[0].y = gl_MultiTexCoord0.y;

turns into

gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;