81 lines
4.7 KiB
GDScript
81 lines
4.7 KiB
GDScript
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))
|
|
|
|
|