Kenobi
Kenobi

Reputation: 423

Why is a simple shader slower than the standard pipeline?

I want to write a very simple shader which is equivalent to (or faster) than the standard pipeline. However, even the simplest shader possible:

Vertex Shader

void main(void)
{
  gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_Position = ftransform();
}

Fragment Shader

uniform sampler2D Texture0;

void main(void)
{
  gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
}

Cuts my framerate half in my game, compared to the standard shader, and performs horrific if some transparent images are displayed. I don't understand this, because the standard shader (glUseProgram(0)) does lighting and alpha blending, while this shader only draws flat textures. What makes it so slow?

Upvotes: 1

Views: 880

Answers (3)

Kenobi
Kenobi

Reputation: 423

It looks like this massive slowdown of custom shaders is a problem with old Intel Graphics chips, which seem to emulate the shaders on the CPU.

I tested the same program on recent hardware and the frame drop with the custom shader activated is only about 2-3 percents.

EDIT: wrong theory. See new answer below

Upvotes: 1

Kenobi
Kenobi

Reputation: 423

After long investigation, the slowdown of the simple shader was caused by the shader being too simple.

In my case, the slowdown was caused by the text rendering engine, which made heavy use of "glBitmap", which would be very slow with textures enabled (for whatever reason I cannot understand; these letters are tiny).

However, this did not affect the standard pipeline, as it would acknowledge the feature glDisable(GL_LIGHTING) and glDisable(GL_TEXTURE_2D ), which circumvents the slowdown, whereas the simple shader failed to do so and would thus even do more work as the standard pipeline. After introducing these two features to the custom shader, it is as fast as the standard pipeline, plus the ability to add random effects without any performance impact!

Upvotes: 0

MichaelCMS
MichaelCMS

Reputation: 4763

I think you might bump into overdraw.

I don't know what engine you are using your shader on, but if you have alpha blend on then you might end up overdrawing allot.

Think about it this way :

If you have a 800x600 screen, and a 2D quad over the whole screen, that 2D quad will have 480000 fragment shader calls, although it has only 4 vertexes.

Now, moving further, let's assume you have 10 such quads, on on top of another. If you don't sort your geometry Front to Back or if you are using alpha blend with no depth test, then you will end up with 10x800x600 = 4800000 fragment calls.

2D usually is quite expensive on OpenGL due to the overdraw. 3D rejects many fragments. Eventhou the shaders are more complicated, the number of calls are greatly reduced for 3D objects compared to 2D objects.

Upvotes: 0

Related Questions