GPU Instancer Pro-Crowd Animations
About | Getting Started | Crowd Animations | Terminology | Best Practices | API Documentation | F.A.Q. | Support
Go to Asset Store Page
The Crowd Animations extension enables high-performance animation support for Skinned Mesh Renderers by leveraging the GPU Instancer Pro framework.
Contents
Description
Crowd Animations applies GPU skinning based on bone transform data, significantly boosting rendering performance when rendering many animated instances that share the same mesh and material. Each instance can play different animation clips independently, with full support for variation in behavior and logic.
Animator Workflows
The system offers multiple animation workflows, allowing you to balance performance and flexibility on a per-instance basis. Draw calls remain batched even when different workflows are used across instances.
Feature Comparison of Workflows
Bone Tracker | Mecanim Reader | Legacy Animation Reader | Compute Animator | |
---|---|---|---|---|
Performance | ★★☆☆☆ |
★★★☆☆ |
★★★☆☆ |
★★★★★
|
Mecanim Animator | ✓ |
✓ |
✗ |
✗
|
Legacy Animation | ✓ |
✗ |
✓ |
✗
|
Root Motion | ✓ |
✓ |
✓ |
✓
|
Bone Attachments | ✓ |
~1 |
~1 |
~1
|
Optimized Bone Hierarchy | ✗ |
✓ |
✓ |
✓
|
Animation Blending | ✓ |
✓ |
✓ |
✓
|
Transitions | ✓ |
✓ |
✓ |
✓
|
IK | ✓ |
~1 |
~1 |
✗
|
Animation Layers | ✓ |
✗ |
✗ |
✗
|
Avatar Masks | ✓ |
✗ |
✗ |
✗
|
Ragdolls | ✓ |
✗ |
✗ |
✗
|
Procedural Animations | ✓ |
✗ |
✗ |
✗
|
Blend Shapes | ✗ |
✗ |
✗ |
✗
|
No-GameObjects | ✗ |
✗ |
✗ |
✓
|
Notes
- Some features are not supported directly but can be implemented by utilizing Bone Read/Write Control.
Bone Tracker
Directly reads Transform components in the bone hierarchy. This workflow offers maximum flexibility and supports runtime modifications such as Inverse Kinematics (IK), Ragdoll physics or Procedural animation. It typically involves higher CPU overhead due to frequent transform reads.
Mecanim Reader
Reads animation state from Unity’s Mecanim Animator at runtime and plays pre-baked animation clips accordingly. This allows integration with existing Animator Controllers while still benefiting from GPU skinning.
Legacy Animation Reader
Reads animation state from Unity’s Animation component at runtime and plays pre-baked animation clips accordingly. This allows integration with existing Legacy Animation systems while still benefiting from GPU skinning.
Compute Animator
Uses compute shaders to calculate bone transforms directly on the GPU using pre-baked animation data. This workflow offers the highest performance and significantly reduces CPU usage. However, it requires a custom setup and does not work out-of-the-box with standard Animator Controllers. It also supports No-GameObjects usage via the API.
Custom Workflows
The system is fully extensible. You can create custom workflows that supply bone transform data to Crowd Animations, allowing for unique animation systems or runtime behaviors.
Hybrid Workflow Support
You can assign different workflows to different instances in the same scene. Draw calls remain batched even when instances use a mix of workflows. This makes it possible to apply the most efficient workflow (e.g., Compute Animator) to most instances, while switching to more flexible ones (e.g., Bone Tracker) only where needed—without increasing draw call counts.
Runtime Animation Baking
Animation clips are automatically baked at runtime when needed. If an animation is used without pre-baked data, the system will generate the baked data on first use for workflows that require it (e.g., Compute Animator, Mecanim Reader). No manual setup or baking in edit mode is required. This approach reduces build size and minimizes memory usage by avoiding unnecessary baked data.
Bone Read/Write Control
Crowd Animations provides per-instance control over which bones are read from or written to:
- Write Mode:
Baked animation data is written to the selected bone transforms. This is useful for bone attachments, running bone-based physics, or syncing bone motion with other systems.
- Read Mode:
Bone transforms are read from the hierarchy at runtime. Ideal for cases where bones are modified during gameplay (e.g., IK, procedural animation), while still allowing the rest of the skeleton to use GPU animation.
Getting Started
Quick Start
The Prefab Manager
Use the Prefab Manager for rendering animated prefab instances in scenes.
- Add Prefab Manager:
Tools -> GPU Instancer Pro -> Add Prefab Manager
- Click on the Add button.
- Select the prefabs with or expected to have many instances in the scene. (See Instance Counts)
- Select the Enable Crowd Animations option under Prototype Settings
- Press the Select button to go to the prefab and edit the GPUI Crowd Instance settings.
No-GameObjects Workflow
This workflow allows you to use Crowd Animations entirely through code, without requiring any active GameObjects in the scene. It is ideal for large-scale simulations, procedural systems, or scenarios where maximum performance and memory efficiency are needed.
- Add the GPUI Crowd Instance component to your character prefab to enable animation with Crowd Animations.
- In the GPUI Crowd Instance component, set the Animator Workflow field to Compute Animator.
- Register the renderer using the RegisterRenderer API method and store the returned
rendererKey
. - Set transform matrices for your instances using SetTransformBufferData with the corresponding
rendererKey
. - Start an animation on an instance:
GPUIAWComputeAnimator.Instance.StartAnimation(rendererKey, instanceIndex, animationClip);
- When the renderer is no longer needed, clean it up using DisposeRenderer.
GPUICoreAPI.RegisterRenderer(this, crowdPrefab, profile, out _rendererKey); // Register the prefab as renderer
GPUICoreAPI.SetTransformBufferData(_rendererKey, GenerateMatrixArray(instanceCount)); // Set matrices for the renderer
GPUIAWComputeAnimator computeAnimator = GPUIAWComputeAnimator.Instance; // Get Compute Animator
for (int i = 0; i < instanceCount; i++)
computeAnimator.StartAnimation(_rendererKey, i, clip); // Start playing the animation clip for each instance.
GPUI Crowd Instance
Prefabs with the GPUI Crowd Instance component are automatically registered by the Crowd Animations system and animated according to the selected Animator Workflow.
This component is added automatically when the Enable Crowd Animations option is enabled in the Prefab Manager. For the No-GameObjects workflow, however, the component must be manually added to the prefab before use.
Animator Workflow: Determines how bone transform data is provided for GPU skinning. The workflow selected on the prefab acts as the default, but individual instances in the scene can override this without increasing draw call counts. See Animator Workflows for detailed descriptions of each available workflow.
Apply Root Motion:
Enables root motion calculation when using the Compute Animator workflow.
This allows characters to move based on animation data.
Bone Settings:
Provides per-instance control over which bones are read from or written to.
This enables advanced runtime features such as:
- Selectively writing animation data to specific bones for physics or attachments
- Reading bone transforms for runtime modifications like IK or procedural animation
Crowd Rig:
The Crowd Rig stores essential data for skinned mesh rendering, including bone hierarchies, bind poses, and skinning metadata.
It also manages baked animation clips at runtime, serving as the core data asset used by Crowd Animations workflows.
- Skin Weights: Specifies the maximum number of bone influences per vertex. This setting affects how vertex skinning is calculated and can impact both visual fidelity and performance.
Compute Animator Methods
The methods below provide control over animations when using the Compute Animator workflow. They can be accessed through various classes, such as GPUICrowdAPI
, GPUICrowdInstance
, or GPUIAWComputeAnimator
.
StartAnimation
public static bool StartAnimation(GPUICrowdInstance crowdInstance, AnimationClip animationClip, float normalizedClipTime = -1.0f, float speed = 1.0f, float transitionTime = 0, bool? isLoopingOverride = null, bool isSyncTime = false)
Parameters | |
---|---|
crowdInstance |
The instance on which to play the animation. |
animationClip |
The animation clip to be played. |
normalizedClipTime |
(Optional) Normalized start time of the clip, between 0f and 1f. Use a negative value to continue from where it left off (e.g., if it was already playing with a blend). |
speed |
(Optional) The animation speed. |
transitionTime |
(Optional) Transition time from the previous clip. |
isLoopingOverride |
(Optional) If null, the clip's looping setting is used. If set to true or false, it forces the animation to loop or not loop. |
isSyncTime |
(Optional) If true, synchronizes the normalized time between animation clips during transitions. |
Description:
Starts playing the specified animation clip on the given crowd instance.
StartBlend
public static bool StartBlend(GPUICrowdInstance crowdInstance, Vector4 animationWeights, AnimationClip animationClip1, AnimationClip animationClip2, AnimationClip animationClip3 = null, AnimationClip animationClip4 = null, Vector4? normalizedClipTimes = null, Vector4? animationSpeeds = null, float transitionTime = 0, bool? isLoopingOverride = null, bool isSyncTime = true)
Parameters | |
---|---|
crowdInstance |
The instance on which to play the animations. |
animationWeights |
Weights of the animation clips. Must sum to 1f. |
animationClip1 |
Clip 1. |
animationClip2 |
Clip 2. |
animationClip3 |
(Optional) Clip 3. |
animationClip4 |
(Optional) Clip 4. |
normalizedClipTimes |
(Optional) Normalized start times for the clips, between 0f and 1f. Use negative values to continue from where they left off (e.g., if previously playing). |
animationSpeeds |
(Optional) Speeds of the animation clips. |
transitionTime |
(Optional) Transition time from the previous clip. |
isLoopingOverride |
(Optional) If null, uses the clips' looping settings. If set to true or false, forces looping or non-looping. |
isSyncTime |
(Optional) If true, synchronizes normalized time across clips during transitions. |
Description:
Starts blending the specified animation clips with the given weights on the specified crowd instance.
System Settings
GPUI Crowd Runtime Settings
To modify the Runtime Settings, navigate to: Tools -> GPU Instancer Pro -> Utilities -> Add Crowd Runtime Settings Overwrite
Then click the Create button on the GPUI Crowd Runtime Settings Overwrite component to create a new settings file.
Mecanim Reader - Max Delay: The Mecanim Reader workflow checks the states of a limited number of instances each frame. By setting the Max Delay value, you limit the number of frames an instance can go without being read. If set to 1 or lower, Mecanim Reader will read the states of all instances every frame.
Mecanim Reader - Min Read: This value determines the minimum number of instances that the Mecanim Reader workflow should read each frame.
Legacy Animation Reader - Max Delay: The Legacy Animation Reader workflow checks the states of a limited number of instances each frame. By setting the Max Delay value, you limit the number of frames an instance can go without being read. If set to 1 or lower, Legacy Reader will read the states of all instances every frame.
Legacy Animation Reader - Min Read: This value determines the minimum number of instances that the Legacy Animation Reader workflow should read each frame.
Additional Components
GPUI Crowd Event Definition
Using the GPUI Crowd Event Definition, you can define events at specific times within animation clips for selected prototypes when using Compute Animator.
GPUI Crowd Compute Player
The GPUI Crowd Compute Player component exposes parameters that allow testing animations using Compute Animator. You can easily experiment with different clips, weights, speeds, transitions, and more to find the ideal setup.
GPUI Crowd Batch Compute Player
While the Compute Player allows you to play animation clips on a single instance, the Batch Compute Player component allows animations to be played on all instances in the scene. It enables easy playback across all instances, with options to randomize clips and their start times.
Shader Setup Guide
Shader Graph Setup
To set up a Shader Graph shader, simply add the GPUI Pro Crowd Setup
node to the shader and connect it to the Vertex Position, Normal, and Tangent outputs.
If your Shader Graph contains the GPU Instancer Pro Setup node, replace it with the GPUI Pro Crowd Setup node, as it already includes the functionality of the former. In addition to setting up procedural instancing, the GPUI Pro Crowd Setup node also implements GPU skinning based on bone data. If other nodes are already connected to the Vertex outputs, you can link them to the input of the GPUI Pro Crowd Setup node, then connect its outputs to the Vertex. If no nodes are currently connected to the outputs, you can add Position, Normal Vector, and Tangent Vector nodes in Object space, connect them to the input of the GPUI Pro Crowd Setup node, and then link its outputs to the Vertex node, as illustrated in the image.
Amplify Shader Editor Setup
To set up an Amplify Shader Editor shader, simply add the GPUI Pro Crowd ASE Setup
node and connect it to the Local Vertex Position, Local Vertex Normal, and Local Vertex Tangent outputs.
Make sure the Vertex Output setting is set to Absolute instead of Relative.
This node already includes the instancing setup, so you should not add the GPUI Pro ASE Setup
node as well.
Manual Setup
To add Crowd Animations support to a shader, first make sure the shader is correctly set up for GPU Instancer Pro.
Then, after each GPUInstancerSetup.hlsl include line, also add GPUICrowdSetup.hlsl:
#include_with_pragmas "Packages/com.gurbu.gpui-pro/Runtime/Shaders/Include/GPUInstancerSetup.hlsl" #include_with_pragmas "Packages/com.gurbu.gpui-pro.crowd-animations/Runtime/Shaders/Include/GPUICrowdSetup.hlsl"
In addition to the UNITY_SETUP_INSTANCE_ID method call, Crowd Animations requires the GPUI_CROWD_VERTEX method call in the shader's vertex function. The GPUI_CROWD_VERTEX method requires 4 inputs: uint vertexID, float3 vertexPosition, float3 normal, and float3 tangentVector.
VertexOutput vert(appdata_full v, uint vid : SV_VertexID) { UNITY_SETUP_INSTANCE_ID(v); GPUI_CROWD_VERTEX(vid, v.vertex.xyz, v.normal.xyz, v.tangent.xyz); ... }