Ive started looking at bone animation and wonder if for high efficiency animations of bones :
1) the transformations applied to the tree of bone matrices are done in the CPU (bone matrices are built for each time step - every render frame) and draw primitives are called against bone sub-mesh IB/VB/Tex (data already in the GPU mem) -- with simple vertex shaders
OR
2) matrices are built partially in the CPU (bone matrices are initially built for the current animation step set of multiple frames and then they are tweened in the GPU via a vertex shader script doing the matrix interpolation), then the next tranformation commands rebuilt the new target matrice in the CPU for the next time span ( animation is lockstep across the whole bone tree)
OR
3) matrices changes are made IN the GPU memory via shader scripts to apply the new animation transformation commands (possibly individually to bones when needed) -- the commands being the only input coming from the CPU fed as needed for each animation step/time span.
OR
4)ultimately, those bone specific commands are ALL staticly cached in the GPU data space and a Shader pass is done against a matrice stack (the bone tree) when needed to modify the tweening targets followed by the normal vertice pass(es) doing tweening)
I understand that the shader instructions have gotten more versatile and the older more limited shaders had more/most matrix manipulations done in the CPU, but I want to understand whats done at the highest Shader versions now (with their ability to do if-then logic).
At this point I dont know how much of the animations are/can be done inside the GPU shaders.
Note - dont bother to tell me "just use the MS mechanism (.X files etc..) and you dont have to think about what it does",
because Im after understanding what it does (or what can be done better)
Bone Animation vertex shaders used or CPU rebuilts the bone matrix ?
I don't think it's efficient use of the GPU to do calculations for transformations and stuff. You should do all your bone and vertex calculations on the CPU, and just bind the updated vertex buffers to the GPU to be rendered. It's usually most efficient to use the GPU only for rendering, and the CPU for all other calculations. I think that's what you were asking, so the method i would use is transform the bones and weights and calculate the vertex positions all on the CPU, then bind the vertex buffer to the GPU.
Generally the skeleton is driven by CPU-side gameplay code (choosing which animations to play, how to blend them, etc...) plus the gameplay code often needs to read back data from the animations (e.g. 'where is the character's hand right now?') so the actual skeleton (i.e. an array of bone matrices) is updated on the CPU side.
This array of bone matrices is then bound to a vertex shader. Each vertex has [font=courier new,courier,monospace]n[/font] bone indices and blend weights, the shader fetches those [font=courier new,courier,monospace]n[/font] matrices out of the array and blends them using the weights to the produce the final skinned vertex position. Performing this skinning/tweening on the GPU is much faster than having the CPU do it and send the results down to VRAM each frame.
If the same skinned mesh is going to be re-drawn several times in a frame (e.g. when it's casting several shadows), then the results from the above vertex shader can be written into a temporary vertex buffer by the GPU (via stream-out functionality) so that the model doesn't have to be re-skinned each time it's drawn.
N.B. it's also possible to run your skeleton update/blend code on the GPU, but this isn't the best idea if the CPU-side gameplay code needs to know about animation poses (e.g. to position it's hit-boxes, or attach items to characters, etc...).
For non-gameplay related animated objects, this is becoming more and more commonplace.
This array of bone matrices is then bound to a vertex shader. Each vertex has [font=courier new,courier,monospace]n[/font] bone indices and blend weights, the shader fetches those [font=courier new,courier,monospace]n[/font] matrices out of the array and blends them using the weights to the produce the final skinned vertex position. Performing this skinning/tweening on the GPU is much faster than having the CPU do it and send the results down to VRAM each frame.
If the same skinned mesh is going to be re-drawn several times in a frame (e.g. when it's casting several shadows), then the results from the above vertex shader can be written into a temporary vertex buffer by the GPU (via stream-out functionality) so that the model doesn't have to be re-skinned each time it's drawn.
N.B. it's also possible to run your skeleton update/blend code on the GPU, but this isn't the best idea if the CPU-side gameplay code needs to know about animation poses (e.g. to position it's hit-boxes, or attach items to characters, etc...).
For non-gameplay related animated objects, this is becoming more and more commonplace.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement