Skip to content

[rmodels] Smarter use of GPU and CPU skinning - #5921

Open
JeffM2501 wants to merge 6 commits into
raysan5:masterfrom
JeffM2501:GPU_SKIN_ON_BY_DEFAULT
Open

[rmodels] Smarter use of GPU and CPU skinning#5921
JeffM2501 wants to merge 6 commits into
raysan5:masterfrom
JeffM2501:GPU_SKIN_ON_BY_DEFAULT

Conversation

@JeffM2501

Copy link
Copy Markdown
Contributor

This PR enables both GPU and CPU skinning to be used at the same time in the same build of raylib.
It uses the state of the shader instead of the build flag at load time to know if it should use the CPU animation buffers or not.
The update functions now lazy allocate the CPU side animation buffers only when they are needed (this has a side effect of saving memory on animatable models that are never drawn animated).
The update code also checks if the shader is going to use the bones, and if so, skips the CPU side buffers.
I also split the update functions into two parts, one that does just the bone math and one that does it all. This allows the user to update just the bones if they want, and not even try to do the CPU buffers.

This all allows animation to always 'just work' with a correct fallback to CPU is GPU is not supported, and only allocating the CPU side buffers if they are needed.

JeffM2501 and others added 2 commits June 13, 2026 10:34
Have the model animation update functions check the current shader to see if they are going to do GPU skinning or not.
Lazy load the CPU animation buffers so they don't get allocated if the user is doing GPU skinning.
This change allows both GPU and CPU skinning in the same program.
@JeffM2501

Copy link
Copy Markdown
Contributor Author

This is a refactor of PR #5902 made after feedback.

Comment thread src/rmodels.c Dismissed
Comment thread src/rmodels.c Dismissed
Comment thread src/rmodels.c Dismissed
@raysan5 raysan5 changed the title Smarter use of GPU and CPU skinning [rmodels] Smarter use of GPU and CPU skinning Jun 17, 2026
@raysan5 raysan5 added the enhancement This is an improvement of some feature label Jun 17, 2026
Comment thread src/config.h Outdated
@@ -322,7 +322,7 @@
#endif
#ifndef SUPPORT_GPU_SKINNING
// GPU skinning disabled by default, some GPUs do not support more than 8 VBOs

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment should probably be updated, too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Comment thread src/config.h
#define SUPPORT_GPU_SKINNING 0
// GPU skinning enabled by default for GL3.3+,
// Some GPUs do not support more than 8 VBOs so you may need to disable it if you have issues loading animated models
#define SUPPORT_GPU_SKINNING 1

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to avoid enabling this by default. CPU solution is widely supported but GPU can fail in some platforms.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not disable CPU skinning. Would you be ok with default enable for GL 3.3+?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If GPU skinning can not be enabled on target platform, does it fallback to CPU skinning? I'd like to keep the conditionals at minimum in config.h.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a plan for how to do this. I will test it in a fork.
Is there any hard info on devices that that the smaller number of vertex attributes? or is it just an ambiguous "some" ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My research on the OpenGL spec.
OpenGL 3.0 - 4.6: Requires a minimum of 16 attributes

Comment thread src/raylib.h
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, float frame); // Update model animation pose (vertex buffers and bone matrices)
RLAPI void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, ModelAnimation animB, float frameB, float blend); // Update model animation pose, blending two animations
RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, float frame); // Update model animation pose (bones only)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could those functions be kept internal to rmodels, I prefer to expose the minimum required functions for users.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is very useful for people who want to do GPU skinning only.
This was a function in 5.5, but it was removed for 6.0 for no clear reason (incorrectly in my option).
I am simply restoring it due to it's utility.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed them because I considered most users don't need them, that was the reason to add the models_animation_blend_custom example, for users that need that level of control.

Comment thread src/rmodels.c
blend = Clamp(blend, 0.0f, 1.0f);
if (currentFrame >= anim.keyframeCount) currentFrame = currentFrame%anim.keyframeCount;
if (nextFrame >= anim.keyframeCount) nextFrame = nextFrame%anim.keyframeCount;
if (currentFrame >= anim.keyframeCount) currentFrame = currentFrame % anim.keyframeCount;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, could you review formatting to follow raylib conventions.

Comment thread src/rmodels.c
// Compute runtime bone matrix from model current pose
//-----------------------------------------------------------------------------------
Transform *bindPoseTransform = &model.skeleton.bindPose[boneIndex];
Transform* bindPoseTransform = &model.skeleton.bindPose[boneIndex];

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, could you review formatting to follow raylib conventions.

Comment thread src/rmodels.c
static void UpdateModelAnimationVertexBuffers(Model model);

// Lazy allocation of CPU animation buffers for vertex positions and normals, used for software skinning
static void AllocateMeshCPUAnimBuffers(Mesh* mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far it is only used once, I prefert to avoid an extra function, code can be used inside function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I can make that change. I just didn't want to make the outer function much larger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement This is an improvement of some feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants