XNA Creators Club Online
Page 1 of 1 (4 items)
Sort Posts: Previous Next

Outline renderer optimisation w/ skinned models

Last post 07/11/2009 18:15 by Shawn Hargreaves. 3 replies.
  • 07/11/2009 2:41

    Outline renderer optimisation w/ skinned models

    Hi all! :)

    We have an outline shader which works by using an unlit scene to determine edges, and then compositing those edges onto a lit scene. The problem is we have a large number of skinned models on screen, and due to needing the outline map separate from the lit scene, this means drawing the entire scene twice. This is the same shader that both does the outline map and the final lit model, depending on a boolean parameter. 

    I've optimised it as much as I can, but one issue is that since vertex shader transforms all the vertices by the bones, this is happening twice for each skinned model. Ideally I'd do what I've done everywhere else in the C# code, and preserve all the data / shader parameters from the first draw to make the second as quick as possible.

    However since I have the skin transformations in the vertex shader, the second time around I have no choice but to redo these transformations. Ideally since the same shader does both, I would somehow store the resultant world matrix for a boneindex in the shader itself, and next time around when it draws the lit model it just refers to these. However it seems that is impossible and all variable states are lost between an Effect.End and Effect.Begin. I suspect this may not be the case when using passes, though i'm not sure, but I can't do this because a lot of my optimisations aka avoiding any setting of parameters would be lost and I'd probably just be making it worse.

    In case you're wondering using a depth map didn't produce the desired results for the outliner, where using unlit colour did. I'm aware if using depth I could probably sneak it into the alpha component of the output colour and do both with one shader pass, but there isn't enough resolution for what we need.

    If anyone's got any advice on a good way to handle outlined skinned models in an optimised way I would much appreciate it. :)

    Thanks!

    lemmy
  • 07/11/2009 13:00 In reply to

    Re: Outline renderer optimisation w/ skinned models

    This is a common problem with soft skinning.  Consider the case when you would need to render shadows for the skinned object.  Now you would be skinning three times!  Typically in this case when you have to do multi-pass rendering or other CPU related things like line checks etc, you'll end up skinning the model once and do it on the CPU so that you can cache the results and then re-use them as many times as need for the remainder of the frame.  And usually it's with hand optimized ASM or intrinsic code.

    Unfortunately, with no SIMD extensions available in Microsoft's .NET C#, this just really isn't an option.  Doing the CPU skinning on a parallel thread with the regular floating point stack would likely still take too long even on the PC, and especially with the PPC 360 processor.  As far as I can tell, you'll just have to re-skin on the GPU when needed (like you already are) and plan for that as your worst case.
  • 07/11/2009 17:50 In reply to

    Re: Outline renderer optimisation w/ skinned models

    The vertex shader generally runs very fast. I wouldn't worry about the re-skinning unless you measure that there really is a problem.

    If you want to save the output, you can use stream-out in DX10. In fact, with stream-out, you can do the "vertices per bone" method of skinning instead of the "bones per vertex" method of skinning. But not in XNA, as XNA is DX9 level only.
    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
  • 07/11/2009 18:15 In reply to

    Re: Outline renderer optimisation w/ skinned models

    Step #1 is to profile this app and gather some data about where your rendering bottlenecks are. There is a good chance it will turn out to be CPU bound, in which case drawing the models twice will make little difference to anything. Even if it is GPU bound, the bottleneck may well be something other than the vertex shader, in which case shading the same vertices twice will make little difference.

    If it does turn out that you are either:

    1. CPU bound with your character rendering calls a major bottleneck
    2. Or GPU bound, and bottlenecked by the vertex shader while drawing these models

    then you could try drawing both images in a single pass, using multiple rendertargets with a pixel shader that outputs a pair of color values.

    If this code really does turn out to be perf critical, though, I would spend some more time investigating whether you cannot encode enough data into the output alpha channel. If you can make that work, it would use much less bandwidth than creating an entirely separate output image.
    XNA Framework Developer - blog - homepage
Page 1 of 1 (4 items) Previous Next