extends MeshInstance3D @export var resolution_scaling = 1 @export var height_scale = 500 * resolution_scaling func _ready(): DebugDraw3D.debug_enabled = true create_mesh() set_material() func create_mesh(): var heightmap_texture = ResourceLoader.load("res://Rolling Hills Height Map 1k/Rolling Hills Height Map.png") var heightmap_image: Image = heightmap_texture.get_image() heightmap_image.convert(Image.FORMAT_RF) var st = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) for i in range(-(heightmap_image.get_height() / resolution_scaling / 2), heightmap_image.get_height() / resolution_scaling / 2): for j in range(-(heightmap_image.get_width() / resolution_scaling / 2), heightmap_image.get_width() / resolution_scaling / 2): create_quad(st, Vector2(i, j), heightmap_image) st.index() mesh = st.commit() func set_material(): var material = StandardMaterial3D.new() material.vertex_color_use_as_albedo = true set_surface_override_material(0, material) func create_quad(st: SurfaceTool, position: Vector2, heightmap_image: Image): var height1 = heightmap_image.get_pixel((position.x + 1) * resolution_scaling + heightmap_image.get_width() / 2, position.y * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition1 = Vector3(position.x * resolution_scaling + resolution_scaling, height1.get_luminance() * height_scale, position.y * resolution_scaling ) var height2 = heightmap_image.get_pixel(position.x * resolution_scaling + heightmap_image.get_width() / 2, (position.y + 1) * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition2 = Vector3(position.x * resolution_scaling , height2.get_luminance() * height_scale, position.y * resolution_scaling + resolution_scaling) var height3 = heightmap_image.get_pixel(position.x * resolution_scaling + heightmap_image.get_width() / 2, position.y * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition3 = Vector3(position.x * resolution_scaling , height3.get_luminance() * height_scale, position.y * resolution_scaling ) var height4 = heightmap_image.get_pixel((position.x + 1) * resolution_scaling + heightmap_image.get_width() / 2, (position.y + 1) * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition4 = Vector3(position.x * resolution_scaling + resolution_scaling, height4.get_luminance() * height_scale, position.y * resolution_scaling + resolution_scaling) var height5 = heightmap_image.get_pixel(position.x * resolution_scaling + heightmap_image.get_width() / 2, (position.y + 1) * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition5 = Vector3(position.x * resolution_scaling, height5.get_luminance() * height_scale, position.y * resolution_scaling + resolution_scaling) var height6 = heightmap_image.get_pixel((position.x + 1) * resolution_scaling + heightmap_image.get_width() / 2, position.y * resolution_scaling + heightmap_image.get_height() / 2) var vertexPosition6 = Vector3(position.x * resolution_scaling + resolution_scaling, height6.get_luminance() * height_scale, position.y * resolution_scaling) var normal1 = -Vector3(vertexPosition2 - vertexPosition1).cross(Vector3(vertexPosition3 - vertexPosition1)).normalized() var normal2 = -Vector3(vertexPosition5 - vertexPosition4).cross(Vector3(vertexPosition6 - vertexPosition4)).normalized() st.set_color(Color.from_rgba8(normal1.x * 255, normal1.y * 255, normal1.z * 255)) st.set_normal(normal1.normalized()) st.add_vertex(vertexPosition1) st.set_color(Color.from_rgba8(normal1.x * 255, normal1.y * 255, normal1.z * 255)) st.set_normal(normal1.normalized()) st.add_vertex(vertexPosition2) st.set_color(Color.from_rgba8(normal1.x * 255, normal1.y * 255, normal1.z * 255)) st.set_normal(normal1.normalized()) st.add_vertex(vertexPosition3) st.set_color(Color.from_rgba8(normal2.x * 255, normal2.y * 255, normal2.z * 255)) st.set_normal(normal2.normalized()) st.add_vertex(vertexPosition4) st.set_color(Color.from_rgba8(normal2.x * 255, normal2.y * 255, normal2.z * 255)) st.set_normal(normal2.normalized()) st.add_vertex(vertexPosition5) st.set_color(Color.from_rgba8(normal2.x * 255, normal2.y * 255, normal2.z * 255)) st.set_normal(normal2.normalized()) st.add_vertex(vertexPosition6) func _process(delta): if Input.is_action_pressed("ShowNormals"): if mesh == null: return for surface_index in mesh.get_surface_count(): var arrays = mesh.surface_get_arrays(surface_index) if arrays.size() == 0: continue var vertices = arrays[Mesh.ARRAY_VERTEX] var normals = arrays[Mesh.ARRAY_NORMAL] for i in vertices.size(): DebugDraw3D.draw_line(vertices[i], normals[i] + vertices[i] , Color.from_rgba8(normals[i].x * 255, normals[i].y * 255, normals[i].z * 255))