5
\$\begingroup\$

Lets say I want to blend two textures together:

  • A texture containing the result of the SSAO calculation.
  • A texture containing the rendered scene.

I could do it in two ways:

  1. Use a shader that samples both the SSAO and scene textures, blends them together and outputs the final color to a render target.
  2. Render to the texture containing the scene and use a blending mode to blend the SSAO texture on top of it. Only the SSAO texture will be sampled inside the shader.

Is it possible to give a general answer about which version is faster, or is it highly hardware dependent?

\$\endgroup\$
2
\$\begingroup\$

It is actually a very interesting question. Initially I thought that a definitive answer does not even exist; after all, it is only certain that speed difference between these methods deviates based on hardware and driver version, just like it does for every other thing.

But what exactly makes that speed deviation? Lets look at the difference between old-fashioned fixed-function blending and custom fragment program blending. Maybe some kind of conclusion will arise.

Rough comparison

Fixed-function blending uses one of the predefined equations to mix fragment color outputs with the framebuffer color values:

  1. render first texture to the framebuffer;
  2. set blending function and parameters for a simple alpha blending;
  3. render second texture to the framebuffer. Note that fixed-function blending is performed directly on the framebuffer, sampling it and modifying it at the same time.

Shader-based blending uses custom fragment program to turn a fragment into colors and a depth value:

  1. render first texture to a previously allocated texture buffer;
  2. change shader program to one with custom blending of any complexity;
  3. render second texture to the framebuffer while reading texture buffer from step 1.

What gives?

It may seem that fixed-function blending should be faster, due to GPU's special hardware for simple blending, direct framebuffer reads and lack of an additional memory buffer.

However, nowadays video memory is usually abundant, and hardware is really optimized for customizable pipeline, so there is no gain on read speed. GPU's speed for simple blending is highly hardware dependent, but so is the shaders performance.

There is one important detail still missing: framebuffer blending has its own stage in rendering pipeline — it is independent from fragment shaders. Which means fixed-function blending can be generally considered being "always faster" simply because it can perform blending operations while custom fragment shader program is processing later fragments.

This also means that fixed-function blending contributes to your ROP count and, consequently, framebuffer bandwidth. And fragment shaders contribute to your fragment shading costs. Frame-buffer bandwidth is a function of GPU memory clock, and fragment-shading speed is a function of the GPU core clock.

So in case of performance problems with two concerned techniques it is possible to be ROP-bound or fragment-shading-bound. (Actually, there are other possible resource bounds, like limit on vertex transformations, but these does not matter in context of the question.)

Just for the sake of completeness and possible effects on the texture sampling performance, it is also worth noting that texture bandwidth is consumed any time a texture fetch request goes out to memory. Texture bandwidth is also a function of GPU memory clock.

Conclusion

In conclusion, use blending for simple blending operations or when you need to blend something with entire framebuffer, and you are not ROP-bound. Use texture sampling when needed or when it suits your code better, and you are not fragment-shading-bound.

Obviously, if you are texture-bandwidth-bound, it is better to avoid unnecessary texture samples, so framebuffer-based blending is preferrable.

Your specific case

As long as you are not bound on those three things mentioned earlier, relative speed of your two methods should be identical. #1 would be easier to tweak and fix, in my opinion.

Also, I have not seen your code, but generally SSAO should be applied only to ambient part of lighting, so blending it over the final scene sounds wrong. All the more reason to sample SSAO texture in your lighting shader.

\$\endgroup\$
  • \$\begingroup\$ Thank you a lot for that extensive answer!! And about the SSAO: Yes, that's actually incorrect, but there's a reason for that.^^ \$\endgroup\$ – Tara Apr 7 '15 at 1:21
-1
\$\begingroup\$

The standard answer to "which is faster" is "profile it and see". Because everything varies a lot by platform, coding pattern, &c. (Method 2, with blending mode, might have direct hardware support... but you never know. Modern cards, behind the scenes, might do exactly the same work as you'd do with your shader.)

Method 1 might, overall, "block" for three draws (color, ssao, combine), while method 2 only waits on two draw (color, ssao-with-blendmode). But how this affects the performance would need to be measured.

This is the sort of thing you'll do once per frame, probably, so it won't be the most important thing to optimize. Either is almost certainly fine.

Using method 1 will give you more flexibility for how to combine the two screens, since you do all the math in your shader. This might be even more valuable to you than counting cycles, as it lets you control the look of your product.

\$\endgroup\$
  • 3
    \$\begingroup\$ Thank you for your answer. I have the exact same number of render passes in both cases. So this is not an argument. I am merely interested in the performance difference between using blending modes and blending in a shader. And "profile and see" is not an applicable answer here, because I asked for a general answer. One approach might be faster on my hardware, but slower on other hardware. And I don't own all hardware in the world in order to profile this. \$\endgroup\$ – Tara Mar 29 '15 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.