0
\$\begingroup\$

I am working on 2d games only. In that context, when would I ever need to use a shader rather than simply manipulate the pixel-data of an image?

For example, I have an image of a car and I want to change the color of the car (leaving the rest as is).

  1. Why should/shouldn't I iterate over the whole image and change a specific color to another?
  2. Why should/shouldn't I use shaders for this instead?
\$\endgroup\$
  • \$\begingroup\$ Special effects. Explosions, particle effects, distortions, LUT, lighting .. to name a few \$\endgroup\$ – Kromster Dec 25 '18 at 6:11
4
\$\begingroup\$

There are a few benefits when using a shader:

Speed

The GPU is faster in manipulating pixels. Ofcourse you can 'preprocess' the texture and that will be fine. It is under the assumption that you only have a few bitmaps to process and you have the time to do this (for example right after a "choose your car color" screen).

Flexibility

So if you want to change the player's car only; sure, you can read the spritesheet, manipulate it and be done.

Now imagine you want to recolor the oppenent cars and have a busy city, this becomes unpractical. Or if you want to show a preview and the player can pick any color they want. Imagine you also want to include a variant with the car flashing white because it has hit an obstacle or something.

In that case you want to do this on the fly... which brings us to:

Memory

If you want to have multiple variants of the same car spritesheet with different colors, you would need to rebuild the bitmap for each variant. If the car is static (only shows 1 side and no animations) you could do this. If you have multiple variations and animations the bitmap becomes bigger- and all variations will grow quick. All these textures then have to be put in the GPUs memory.

Now I hear you say: "but there is plenty of memory on the GPU for my 2D game!", next is:

Performance

Closely related to the speed topic, above. But in the light of the memory one; the GPU performs at best in 2D games with as little drawcalls as possible. This is usually done by using sprite atlasses; it provides the GPU with all texture data in one go.

Having one bitmap and a few shader parameters simply provides better performance- while having much more flexibility.

Maintainability

If you have one sprite atlas for the car's movement, a variable is enough to set the color for any car in the city. If you're to build one sprite atlas to hold all car variations and the colors, you have to keep track of where the images in the sprite atlas were placed (if packed to maximize efficiency). This may be a minor thing; but it greatly helps if all assets are manipulated programmatically by properties and not the location in a bitmap.

To conclude

Having said all that; if your game has no complex scenes and is able to redraw the sprites at convenient times without impact- there is no problem doing so. Even so if you are able to combine many small variations in a sprite atlas you may be fine.

In the end: the shader route simply provides more versatility with best performance when scaling up- which is why most games go that route.

\$\endgroup\$
  • \$\begingroup\$ This is a very detailed answer. Thank you! Actually the nain part I was missing is the fact, that shader process on the GPU vs the CPU. \$\endgroup\$ – Marco Zielbauer Dec 23 '18 at 12:58
1
\$\begingroup\$

Why should/shouldnt I iterate over the whole image and change a specific color to another?

Mainly because no matter how fast and efficent your algorithm is, It's still going to be much, much slower than just "changing the color to a new one" using shaders;

You would need to know which pixels need to be changed and change their value to the one we want; This becomes quite a fiddly and unnecessary process when dealing with large images.

Why should/shouldnt I use shaders for this instead?

Reading/writing to an image is most of the times done on the CPU; Shaders, on the other hand, are user-defined programs that run on the GPU, which is designed to process and shade pixels using a shading language like GLSL or HLSL very, very quickly.

\$\endgroup\$
  • \$\begingroup\$ The piece I was missing (learned it at university a few days ago) was that CUDA cores are working in clusters which will give you a huge performance boost over your normal 4-8 core processor. \$\endgroup\$ – Marco Zielbauer Feb 11 at 8:39

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.