Open Rattel opened 6 years ago
After a lot of digging I see it's possible. If you have a mesh instance you need to call "set" on the mesh instance with "blend_shapes/
onready var body = $Model/Skeleton/Body
var t = 0.0
func _process(delta):
t += delta
if t > 1:
t = 0
body.set("blend_shapes/FaceSmile", t)
Wouldn't it be better to change this issue to a "bug" or "enchancement", given it is quite unintuitive for users?
I guess it might be better to add a set_blend_amount(blendshape, amount)
instead of documenting the workaround.
I'd agree. I spent a long time looking for how to do this and ended up digging through the code before finally stumbling upon a solution. A wrapper for the method wouldn't be unwelcome, especially if it caps the range to 0-1 as is needed by blendshapes.
There is this method in VisualServer.cs
/// <summary>
/// <para>Sets the weight for a given blend shape associated with this instance.</para>
/// </summary>
[GodotMethod("instance_set_blend_shape_weight")]
public static void InstanceSetBlendShapeWeight(RID instance, int shape, float weight)
{
NativeCalls.godot_icall_3_630(method_bind_262, ptr, RID.GetPtr(instance), shape, ref weight);
}
Just needs better documentation not different implementation IMO
I think I've actually changed my mind about this. Particularly because of how multimesh should handle blendshapes. If multimesh instances handled it the same way as mesh instances then that would mean that all meshes of the multimesh would have to have the same value of blendshape, where as if we instead were able to call a method you could use one of the parameters that make each mesh of the multimesh unique to make each blendshape have its own value. Which would be good if you had a bird mesh with flying blend shapes and you wanted them all to fly off at different times. In my case I want them all to have the same blend shape but the method would allow that flexibility. Having a method might even make the variables mesh instance has obsolete. I was going to make my own issue for blendshape support for multimeshes but this might solve that.
@lukostello Using blendshapes with multimeshes is out of scope for this issue. This issue is about changing the values for a blend shape from script.
With respect to animating different multimesh instances differently with blendshapes, it is not trivial to implement and may not even be possible. MultiMeshes use GPU instancing which is different that having Mesh Instances in Godot. GPU instancing means that only one mesh is sent to the GPU and then it is rendered multiple times in a single draw call. What makes it fast is that only one mesh is used. Your suggestion would require the each instance uses a unique mesh (a blendshape is essentially another mesh) which would make it impossible to use GPU instancing. This problem is described well (from a tech artists persective) in the GDC talk "Creating the Art of ABZU" https://www.gdcvault.com/play/1024409/Creating-the-Art-of-ABZ. the speaker outlines their attempt to animate thousands of fish using blendshapes and how it was not possible, then they propose a solution, which is using vertex animation instead. Vertex animation works very well for simple Meshes (like fish or birds). The technique is also decribed in the Godot docs in the Animating thousands of fish with the MultiMeshInstance tutorial.
@clayjohn even in the instance where all meshes in the multimesh share the same blendshape?
@lukostello It is technically possible for all instances to share a blend shape. However, the animations for all instances will be in synch. Further, I am not sure if Godot properly supports blend shapes with the MultiMeshInstance (from a quick glance it looks like it doesn't).
The way blendshapes work is that they process the mesh before it is drawn and actually morph the mesh stored on the GPU, so when it comes time to issue a draw call, the engine cant tell the difference between a mesh with blend shapes and a static mesh.
This is a problem for MultiMeshes because they only send one copy of the mesh to the GPU and then use GPU instancing to draw the same mesh multiple times.
@clayjohn that doesn't seem like a problem, just have the copy of the mesh being sent be the mesh made after the blend shapes are applied, but even if that does work that would mean all of them would be in sync which is what I want but its probably a pretty niche usage.
that doesn't seem like a problem, just have the copy of the mesh being sent be the mesh made after the blend shapes are applied, but even if that does work that would mean all of them would be in sync which is what I want but its probably a pretty niche usage.
Feel free to open a proposal! I don't think it should be too much trouble to add. But of course, we would need to see if there is user demand before considering it.
Godot version: 3.0 Beta 2
Issue description: Looks like it's impossible to change values of a Blend Shape in a mesh with a script, or at least it's not documented, even though you can change them in the editor.