godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.24k stars 20.23k forks source link

`multimesh.set_instance_transform(0, Transform.FLIP_Z)` does not flip #87483

Closed bruce965 closed 8 months ago

bruce965 commented 8 months ago

Tested versions

System information

Godot v4.2.1.stable (b09f793f5) - Freedesktop SDK 23.08 (Flatpak runtime) - Wayland - Vulkan (Forward+) - integrated AMD Radeon Graphics (RADV RENOIR) () - AMD Ryzen 7 4700U with Radeon Graphics (8 Threads)

Issue description

MultiMeshInstance3D do not respect Transform.FLIP_Z.

Steps to reproduce

I populated a MultiMeshInstance3D with the following code:

multimesh = MultiMesh.new()
multimesh.transform_format = MultiMesh.TRANSFORM_3D
multimesh.instance_count = 1
multimesh.mesh = QuadMesh.new()
multimesh.set_instance_transform(0, Transform3D.FLIP_Z)

Basically it's just a quad flipped on the Z axis, this is what I would expect to see (a quad facing the opposite way):

expected result

But instead I see this (a quad facing my way):

actual result

Fun fact: it works as expected if I flip a MeshInstance3D, but doesn't seem to work with MultiMeshInstance3D.

My assumption without checking the code: I assume the transformation is applied at the GPU level (basically, in a shader). Each vertex gets flipped individually, but ultimately the position remains the same, and thus the "clockwise-ness" of each triangle doesn't change, and thus the quad remains unflipped.

Minimal reproduction project (MRP)

Godot 3: MultimeshFlipTest_3.zip Godot 4: MultimeshFlipTest_4.zip

clayjohn commented 8 months ago

My assumption without checking the code: I assume the transformation is applied at the GPU level (basically, in a shader). Each vertex gets flipped individually, but ultimately the position remains the same, and thus the "clockwise-ness" of each triangle doesn't change, and thus the quad remains unflipped.

Ya, that's about right. FLIP_Z bakes a transformation that flips a point over the z axis. In your case you would be applying it to the vertices so each gets flipped on the z axis. But since they lie on the z axis they just stay in the same spot.

bruce965 commented 8 months ago

Ya, that's about right. FLIP_Z bakes a transformation that flips a point over the z axis. In your case you would be applying it to the vertices so each gets flipped on the z axis. But since they lie on the z axis they just stay in the same spot.

Ah... in that case I don't think it's fixable without some invasive changes, right? Perhaps we can just close this issue. Thoughts?

clayjohn commented 8 months ago

Ah... in that case I don't think it's fixable without some invasive changes, right? Perhaps we can just close this issue. Thoughts?

That's right. I don't think you can get the behaviour that you want using FLIP_Z you'd have to use a 180 degree rotation instead.

bruce965 commented 8 months ago

[…] you'd have to use a 180 degree rotation instead.

This would alter the UVs though. In my specific case the workaround is to not use MultiMeshInstace3D, not a big deal.

I assumed this was considered a bug in Godot, but perhaps it's just a known limitation instead.

clayjohn commented 8 months ago

Fair enough.

Closing as this isn't a bug in Godot and you have found a satisfactory workaround.