- Edited
I'm making a map editor for my game, and that means I'm having to build the map's 3D mesh through code, using the SurfaceTool, but I came across the problem of lighting not working as it should.
I'm calling SurfaceTool.add_smooth_group(true)
before building the entire mesh (code below), and then SurfaceTool.generate_normals()
before committing the mesh. I'm not sure how to use the former. It smooths the lighting within each tile this way (each tile is two triangles), and I couldn't get any different results by calling it before adding each vertex, or in any other way that I tried.
The result is what you can see in the image below. When I pull a vertex up the lighting creates seams between tiles. However, within each tile, the lighting is smooth.
I don't know what I'm doing wrong...
The map is a 2D array of "cells" (stored in 1D), and when I create or make changes to a cell this function gets called (and the resulting mesh fed into the map's MeshInstance):
func make_map_mesh(cells, w, h):
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_material(material)
st.add_smooth_group(true)
for c in cells:
if c != null:
create_cell_mesh(st, c)
st.generate_normals()
return st.commit()
Each cell object stores the positions of its 8 vertices: 4 for the ceiling, and 4 for the floor. The walls are computed depending on neighbors (I excluded the code for the walls and ceilings for testing).
The create_cell_mesh()
function takes each cell and builds its part of the mesh.
# I'm handling vertices in this order (not sure if it's ideal, but...)
# A ----------- B
# / / top face
# E ----------- F
#
# D ----------- C
# / / bottom face
# H ----------- G
#
func create_cell_mesh(st, cell):
# (...) - compute uvs according to cell's tile textures
var a = cell.a # ceiling vertices
var b = cell.b
var e = cell.e
var f = cell.f
var c = cell.c # floor vertices
var d = cell.d
var g = cell.g
var h = cell.h
# (...) - build walls
# (...) - build ceiling
# build floor
create_face(st, d, c, g, h, u, v, u2, v2)
And this is where I create the vertices.
func create_face(st, a, b, c, d, u, v, u2, v2):
var a_uv = Vector2(u, v)
var b_uv = Vector2(u2, v)
var c_uv = Vector2(u2, v2)
var d_uv = Vector2(u, v2)
# top right triangle
st.add_uv(a_uv)
st.add_vertex(a)
st.add_uv(b_uv)
st.add_vertex(b)
st.add_uv(c_uv)
st.add_vertex(c)
# bottom left triangle
st.add_uv(c_uv)
st.add_vertex(c)
st.add_uv(d_uv)
st.add_vertex(d)
st.add_uv(a_uv)
st.add_vertex(a)