Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MeshDataTool corrupting meshes in Forward+ rendering method #91618

Open
PlusOneRabbit opened this issue May 6, 2024 · 5 comments
Open

MeshDataTool corrupting meshes in Forward+ rendering method #91618

PlusOneRabbit opened this issue May 6, 2024 · 5 comments

Comments

@PlusOneRabbit
Copy link

Tested versions

  • Reproducible in: v4.3.dev6 [64520fe67], v4.2.2.stable, v4.1.4.stable, v4.0.4.stable, v4.0.0.stable

System information

Godot v4.2.2.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 31.0.15.5123) - 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz (16 Threads)

Issue description

I'm running into an issue where 3D models (unmodified default cube & UV sphere from Blender 4.1 exported as .GLB) are getting corrupted, turning solid black and changing size, after creating a MeshDataTool from their surface and re-committing it to the mesh.

The following barebones script causes the issue to occur:

extends MeshInstance3D

func _ready():
	var mdt = MeshDataTool.new()
	mdt.create_from_surface(mesh, 0)
	mesh.clear_surfaces()
	mdt.commit_to_surface(mesh)

The docs include a warning that MeshDataTool can only be used on Meshes that use the PrimitiveType Mesh.PRIMITIVE_TRIANGLES (3), but if you modify the script to print it out, you can confirm that this is not the issue.

	print((mesh as ArrayMesh).surface_get_primitive_type(0)) # Prints 3

The MRP scene contains 5 meshes, left to right: cube and sphere with the barebones script, cube and sphere with the example MeshDataTool script from the Godot docs, and finally, the only working one, the previous script but using a procedurally generated sphere mesh made with the example ArrayMesh script from the Godot docs.

Editor screenshot:
Godot_v4 2 2-stable_mono_win64_2024-05-06T033144 905

Forward+ rendering method build:
Godot_v4 2 2-stable_mono_win64_2024-05-06T064649 384

Mobile rendering method build:
Godot_v4 2 2-stable_mono_win64_2024-05-06T064712 477

This honestly makes zero sense to me and I have no idea what's happening here or how any of the involved steps even could go wrong. Whether it's somehow an issue with the models, the import process, MeshDataTool, or why it changes depending on the rendering method. I've tried asking in the Discord server a couple times, but the only lead that's been found is that it works when using the mobile renderer.

Steps to reproduce

Open the attached MRP in any Godot version 4.x. The selected rendering method is Forward+, and when running the project, you should see the above graphical glitch. If you switch the rendering method to Mobile and save and restart the project, it will look correct when running.

Minimal reproduction project (MRP)

MRP_MeshDataTool_ForwardPlus_Issue.zip

@huwpascoe
Copy link

The imported resource is being overwritten, it needs to be either mesh = mesh.duplicate(), or since it's being discarded anyway, assigned a new one. mesh = ArrayMesh.new()

extends MeshInstance3D

func _ready():
	var mdt = MeshDataTool.new()
	mdt.create_from_surface(mesh, 0)
	mesh = ArrayMesh.new()
	mdt.commit_to_surface(mesh)

image

@PlusOneRabbit
Copy link
Author

It works, thank you! Is this behavior intentional? The documentation shows to call clear_surfaces() and makes no mention of there being an exception for imported resources, and I'm still not quite sure why there was a difference between rendering methods.

@PlusOneRabbit
Copy link
Author

Misclick, sorry, just woke up

@PlusOneRabbit PlusOneRabbit reopened this May 7, 2024
@huwpascoe
Copy link

It works, thank you! Is this behavior intentional? The documentation shows to call clear_surfaces() and makes no mention of there being an exception for imported resources, and I'm still not quite sure why there was a difference between rendering methods.

The data is created as part of an import process so it should be readonly, yeah the documentation needs to warn for this at the very least.

@clayjohn
Copy link
Member

To be more precise. The problem here is that you have a shadow_mesh inside your mesh which is an optimized version of the mesh generated at import time:
image

image

The shadow mesh is used for the depth prepass since it is slightly optimized. However, your script changes the mesh in such a way that it no longer matches the shadow mesh and so the object does not draw accurately.

You have three options:

  1. Disable creating shadow meshes in the import options,
  2. Replace the shadow mesh when you modify the source mesh, or
  3. Do as suggested above and just create a new mesh

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

No branches or pull requests

4 participants