Suppose I have a character sprite and I want to apply some animating effect that overlays its color, how would I do it? What I desire is something along this line: (From final fantasy tactics)

enter image description here

It is a sprite overlay with animating gray effect and white color for black line.

However, in XNA, pixel shader support only shading of all sprite in the scene. If I am to pixel shade only specific sprite I want, I have to either apply stencil buffer which makes the system more complicated when I have multiple, separated effects for each sprite ( I have to determine stencil buffer clipping for each effects ). Another forum suggest using seperate sprite batch for each sprite drawn (call Begin / End for each sprite) and create my own sorting routine, but I found out that this batching method will really consume alot of GPU performance.

On the other hand, If I have 2D texture filled prerendered overlay effect, then I apply it onto the character sprite for some blending effect, the Sprite batch will not clip out the overlay effect and limit it only to character shapde but will pass it onto the background too.

Therefore, any suggestion to tackle this problem?

  • \$\begingroup\$ You need just one spritebatch for each pixel shader effect not for each sprite \$\endgroup\$ – Kikaimaru May 23 '12 at 10:02
  • \$\begingroup\$ The problem is each spritebatch has its own sorting routine. If I am to apply my own depth sorting, then I have to organize spritebatch drawing sequence in depth order not in pixel shading effect order. For example, pic 1,2,3 is to draw in this order. If pic 1 and 3 use same effect and pic 2 use another effect, I have to find a way to organize it such that pic 1,3 is drawn using same effect while the drawing order remains 1,2,3. The only way I know how to accomplish this is make separate batch for each pic \$\endgroup\$ – user1542 May 23 '12 at 10:45
  • \$\begingroup\$ @user1542 - You could put the effects into the same file and pass in a shader parameter to tell it which one (if any) to apply. Then, you could use SpriteSortMode.Immediate to draw each sprite how you want it. You would have to handle the draw order, but you wouldn't need to create many sprite batches. \$\endgroup\$ – Richard Marskell - Drackir May 23 '12 at 13:00
  • \$\begingroup\$ @RichardMarskell-Drackir From the msdn reference: blogs.msdn.com/b/shawnhar/archive/2010/04/05/… ------ It points out that 'SpriteSortMode.Immediate' will not be batched for multiple 'Draw()' call. Therefore, from my understanding, this mode works similar to separate batch call method. \$\endgroup\$ – user1542 May 23 '12 at 15:30
  • \$\begingroup\$ Actually, you'll note the article is discussing how it used to work in 3.1. In XNA 4.0: "Every Immediate mode SpriteBatch.Draw call now generates a separate GPU draw call, exactly like the name implies, really truly immediately with no batching whatsoever." (same article, near the bottom). Also, that's a blog post, if you look at the actual MSDN reference page it says "sprites will be drawn within each Draw call." vs other modes where "Sprites are not drawn until End is called." \$\endgroup\$ – Richard Marskell - Drackir May 23 '12 at 15:58

Your Answer

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

Browse other questions tagged or ask your own question.