You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: chapter-21/chapter-21.md
+341-5
Original file line number
Diff line number
Diff line change
@@ -329,14 +329,350 @@ As in the previous methods, we will store the weights and bone indices informati
329
329
330
330
## Compute shaders
331
331
332
-
TBD: AnimationRender
332
+
It is turn now to implement animation transformations through compute shaders. As it has been said before, a shader is like any other shader but it does not compose any restrictions on its inputs and its outputs. We will use them to transform data, they will have access to the global buffers that hold information about binding poses and animation transformation matrices and it will dump the result into another buffer. The shader code for animations (`anim.comp`) is defined like this:
As you can see the code is very similar to the one used in previous chapters for animation (unrolling the loops). You wil notice that we need to apply an offset for each mesh, since the data is now stored in a common buffer. In order to support push constants in the compute shader. The input / output data is defined as a set of buffers:
433
+
*`srcVector`: this buffer will contain vertices information (positions, normals, etc.).
434
+
*`weightsVector`: this buffer will contain the weights for the current animation state for a specific mesh and entity.
435
+
*`bonesMatrices`: the same but with bones matrices information.
436
+
*`dstVector`: this buffer will hold the result of applying animation transformations.
437
+
438
+
The interesting thing is how we compute that offset. The `gl_GlobalInvocationID` variable will contain the index of work item currently being execute din the compute shader. In our case, we will create as many work items as "chunks" we will have in the global buffer. A chunk models a vertex data, that its its position, normals, texture coordinates etc. Therefore, por vertices data each time the work item is increased, we need to move forward in the buffer 14 positions (14 floats: 3 for positions,. 3 for normals, 3 for bitangents, 3 for tangent and 2 for texture coordinates). The same applies for weights buffers which holds data for weights (4 floats) and bone indices (4 floats) associated to each vertex. We use also the vertex offset to move long the binding poses buffer and the destination buffer along with the `drawParameters` data which point to th ebase offset for each mesh and entity.
439
+
440
+
We will use this shader in a new class named `AnimationRender` which is defined like this:
As you can see, the definition is quite simple, when creating the shader we need to set up the `GL_COMPUTE_SHADER` to indicate that this is the compute shader. The uniforms that wew ill use will contain the offset in binding pose buffer, weights and matrices buffer and destination buffer. In the `render` method we just iterate over the models and get the mesh draw data for each entity to dispatch a call to the compute shader by invoking the `glDispatchCompute`. The key, again tos the `groupSize` variable. As you can see we need to invoke the shader as many times as vertices chunks there are in the mesh.
333
509
334
510
## Other changes
335
511
336
-
TODO:
337
-
- SceneRender
338
-
- ShadowRender
339
-
- Main
512
+
We need to update the `SceneRender` class to render the entities associated to animated models. The changes are shown below:
The code to render animated models is quite similar as the one used for static entities. The differences is that we are not grouping entities that share the same model, we need to record draw instructions for each of the entities and associated meshes.
595
+
596
+
We need also to update the `ShadowRender` class to render animated models:
In the `Render` class we just need to instantiate the `AnimationRender` class, and use it in the `render` loop and the `cleanup` method. In the `render` loop we will invoke the `AnimationRender` class `render` method at the very beginning, so animation transformations are applied prior to render the scene.
0 commit comments