Mesh generated programatically appears only black or emissive

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By DrPlamsa
:warning: Old Version Published before Godot 3 was released.

When generating a mesh using Mesh.add_surface(format,Vector3Array), I can generate the mesh correctly. I can add it as a resource to a MeshInstance node. The mesh displays correctly, except for how it interacts with lighting.

The MeshInstance does not interact with external lighting whatsoever. It does not diffract, it does not scatter uniformly. The only color seen is the emission color.

If an imported OBJ mesh is used instead, the problem is gone and the MeshInstance interacts with light correctly.

If the Mesh.regen_normalmaps() function is used, the problem persists. Only emission is seen.

If the mesh is saved as a resource using ResourceSaver.save and added to another MishInstance, the problem persists. Only emission is seen.

In the attached image, you can see four MeshInstance nodes. A cube, demonstrating the correct behavior of the external light. Next: Black paraboloid as saved from Mesh.add_surface and assigned to a MeshInstance. Its emission color is set to black. Next: Red paraboloid, as assigned to a MeshInstance at compile time using self.set_mesh. Its emission color is set to red. Next: Greed paraboloid, an attempt to use SurfaceTool (which is not a solution, as it is not parallelizable for efficiency). For SurfaceTool, both with and without generate_normals have the incorrect behavior.

My question is this: What am I doing wrong? How can I programatically add a locally generated mesh to the scene and have light diffuse and diffract correctly (not in a serial manner, as in SurfaceTool)? Is it something to do with normals? Thank you very much for reading; I am enjoying Godot a lot.

Mesh.add_surface(format,Vector3Array)

The input to add_surface should be the primitive type and an Array of arrays of varying types (the vertex array should be a Vector3Array, the color array should be a ColorArray etc., check the Mesh documentation). Does Godot give you any errors? What does surface_get_format() print for your surface? Does flipping your normals do anything?

mollusca | 2017-07-09 16:49

Thanks for your attention!

In clarification of the first point you raise, I should explicitly copy some of my code:
var mesh=Mesh.new()
var array = Array()
array.resize(ARRAY_MAX)
array[Mesh.ARRAY_VERTEX] = vertices
mesh.add_surface(Mesh.PRIMITIVE_TRIANGLES, array)
where ARRAY_MAX is 9 and vertices is a Vector3Array.

In response to whether Godot gives me any errors, the answer is no. No errors are displayed in the output, nor in the debug.

In response to what surface_get_format() gives, the answer is integer 1, or ARRAY_FORMAT_VERTEX according to the Mesh documentation.

In response to what flipping normals does, here I need to betray my ignorance. I haven’t specified normals. Would it be as simple as doing
array[Mesh.ARRAY_NORMAL] = normals
mesh.add_surface(Mesh.PRIMITIVE_TRIANGLES, array)

DrPlamsa | 2017-07-10 00:22

:bust_in_silhouette: Reply From: DrPlamsa

The comment by mollusca basically had the answer: Normals are required to render correctly. The code to do this is

	var array = Array()
array.resize(ARRAY_MAX)#this is 9
array[Mesh.ARRAY_VERTEX] = vertices#Vector3Array
array[Mesh.ARRAY_NORMAL] = normals#Vector3Array
print("Mesh.ARRAY_VERTEX ", Mesh.ARRAY_VERTEX)

mesh.add_surface(Mesh.PRIMITIVE_TRIANGLES, array)
set_mesh(mesh)

Can I update the array size and reposition the vertices on the fly, without recreating the mesh or the array? Thanks.

rraallvv | 2017-11-01 18:29