• 3D
  • How do I get crisp edge shadows with ArrayMesh?

I'm using ArrayMesh in hopes of generating some procedural geometry, but right now it looks like this:

I would prefer that it look something like this:

In case you're wondering, that's from Sebastian Lague's fantastic video on Marching Cubes.

I would like to have sharper edge shadows so I can more accurately see where the geometry is once I have something more complex. I know I'm still learning to use ArrayMesh properly, but here's my code:

extends MeshInstance

var vertices = PoolVector3Array()
var uvs = PoolVector2Array()
var normals = PoolVector3Array()
var indices = PoolIntArray()

func add_triangle(Vone, Vtwo, Vthree):
	vertices.push_back(Vone)
	normals.append(Vone)
	
	vertices.push_back(Vtwo)
	normals.append(Vtwo)
	
	vertices.push_back(Vthree)
	normals.append(Vthree)

func _ready():
	
	add_triangle(Vector3(-1,0,1), Vector3(0,1,0), Vector3(1,0,1))
	add_triangle(Vector3(1,0,1), Vector3(0,1,0), Vector3(1,0,-1))
	add_triangle(Vector3(1,0,-1), Vector3(0,1,0), Vector3(-1,0,-1))
	add_triangle(Vector3(-1,0,-1), Vector3(0,1,0), Vector3(-1,0,1))
	
	add_triangle(Vector3(-1,0,1), Vector3(1,0,1), Vector3(0,-1,0))
	add_triangle(Vector3(1,0,1), Vector3(1,0,-1), Vector3(0,-1,0))
	add_triangle(Vector3(1,0,-1), Vector3(-1,0,-1), Vector3(0,-1,0))
	add_triangle(Vector3(-1,0,-1), Vector3(-1,0,1), Vector3(0,-1,0))
	
	var tmpMesh = ArrayMesh.new()
	var arrays = Array()
	arrays.resize(ArrayMesh.ARRAY_MAX)
	arrays[ArrayMesh.ARRAY_NORMAL] = normals
	arrays[ArrayMesh.ARRAY_VERTEX] = vertices

	tmpMesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
	mesh = tmpMesh

I'm sure it's something to do with my ArrayMesh because this is a MeshInstance with a CubeMesh right next to my ArrayMesh object:

To get sharp edges you have to create disconnected duplicate data. Connected points get smoothly interpolated in shading.

Hm, your array mesh looks like having smooth shading and no shadows.

What if you would change shading to flat shading? (that's to be done in material)

Anyway it is still is strange there is no shadows, maybe you need to enable shadows for your mesh?

The second image you shown in your first post seems to use flat shading, then shading is done per vertex and always whole face is shaded with the same color shade.

Edit: Another idea is something wrong with normal vectors for your mesh. To create something like pyramid and have proper shading you need to have 3-4 different normals per one vertex position.

Edit2: Yes, I think that what @Megalomaniak said is true in this case, because of that multiple normals you will need duplicate vertices. As I remember even in pure OpenGL it needs to be done the same way (because you can't set indices for position and normals separately, so you need create vertex with the same position, but different normal)

Well, I switched to using SurfaceTool and the generate_normals() function and it's exactly what I need.

Thanks for your replies though.