save before os reset

This commit is contained in:
Guillaume Vern 2025-12-05 11:18:12 +01:00
parent 42ccbebb52
commit 217f9dac58
5 changed files with 89 additions and 59 deletions

View File

@ -10,7 +10,6 @@ func create_device():
shader_spirv = shader_file.get_spirv() shader_spirv = shader_file.get_spirv()
shader = rd.shader_create_from_spirv(shader_spirv) shader = rd.shader_create_from_spirv(shader_spirv)
func compute(world_size: int, threshold: float): func compute(world_size: int, threshold: float):
# Prepare our data. We use floats in the shader, so we need 32 bit. # Prepare our data. We use floats in the shader, so we need 32 bit.
@ -77,11 +76,37 @@ func compute(world_size: int, threshold: float):
var output_bytes := rd.buffer_get_data(surface_buffer) var output_bytes := rd.buffer_get_data(surface_buffer)
var output := output_bytes.to_float32_array() var output := output_bytes.to_float32_array()
var output_sample_bytes := rd.buffer_get_data(buffer)
var output_sample := output_sample_bytes.to_float32_array()
rd.free_rid(buffer) rd.free_rid(buffer)
rd.free_rid(params_buffer) rd.free_rid(params_buffer)
rd.free_rid(surface_buffer) rd.free_rid(surface_buffer)
return build_surface_dict(world_size, output)
var surface_points_dict := build_surface_dict(world_size, output)
var sample_points_dict := build_sample_dict(world_size, output_sample)
return {
"surface_points_dict": surface_points_dict,
"sample_points_dict": sample_points_dict
}
func build_sample_dict(world_size: int, flat_buffer: PackedFloat32Array) -> Dictionary:
var dict := {}
var total = world_size * world_size * world_size
for idx in total:
var voxel_x = idx % world_size
var voxel_y = (idx / world_size) % world_size
var voxel_z = idx / (world_size * world_size)
var voxel_id = Vector3i(voxel_x, voxel_y, voxel_z)
var distance = flat_buffer[idx]
dict[voxel_id] = distance
return dict
func build_surface_dict(world_size: int, flat_buffer: PackedFloat32Array) -> Dictionary: func build_surface_dict(world_size: int, flat_buffer: PackedFloat32Array) -> Dictionary:
var dict := {} var dict := {}
var total = world_size * world_size * world_size var total = world_size * world_size * world_size

28
generate_mesh.tres Normal file
View File

@ -0,0 +1,28 @@
[gd_resource type="VisualShader" load_steps=2 format=3 uid="uid://bose286qacwdl"]
[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_sxi40"]
constant = Color(0.30202293, 0.6060653, 0.9109474, 1)
[resource]
code = "shader_type spatial;
render_mode blend_mix, depth_draw_opaque, depth_test_default, cull_back, diffuse_lambert, specular_schlick_ggx;
void fragment() {
// ColorConstant:2
vec4 n_out2p0 = vec4(0.302023, 0.606065, 0.910947, 1.000000);
// Output:0
ALBEDO = vec3(n_out2p0.xyz);
}
"
nodes/vertex/0/position = Vector2(360, 220)
nodes/fragment/0/position = Vector2(660, 140)
nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_sxi40")
nodes/fragment/2/position = Vector2(260, 220)
nodes/fragment/connections = PackedInt32Array(2, 0, 0, 0)

View File

@ -15,7 +15,7 @@ layout(set = 0, binding = 1) uniform Params {
float threshold; float threshold;
} params; } params;
layout(set = 0, binding = 2) buffer SurfaceBuffer { layout(set = 0, binding = 2, std430) buffer SurfaceBuffer {
float surface_points[]; float surface_points[];
} surface; } surface;
@ -89,4 +89,6 @@ void main() {
store_surface_point(idx, vec3(0.0)); // no surface store_surface_point(idx, vec3(0.0)); // no surface
} }
} }

View File

@ -10,6 +10,8 @@ var SurfacePoint = preload("res://surface_point.gd")
var ComputeSdf = preload("res://compute_test.gd") var ComputeSdf = preload("res://compute_test.gd")
var gpu_sdf var gpu_sdf
var generate_mesh_shader = preload("res://generate_mesh.tres")
@export var world_size = 16 @export var world_size = 16
@export var show_sample_points = false @export var show_sample_points = false
@ -19,29 +21,34 @@ var gpu_sdf
@export var do_the_thing: bool = false @export var do_the_thing: bool = false
@export var clear_the_thing: bool = false @export var clear_the_thing: bool = false
var sdf_buffer = []
var surface_points_buffer = []
var color = Color.CORAL var color = Color.CORAL
var surface_point_color = Color.CRIMSON var surface_point_color = Color.CRIMSON
var mesh var mesh
var surface_tool: SurfaceTool = SurfaceTool.new() var surface_tool: SurfaceTool = SurfaceTool.new()
var meshinstance = MeshInstance3D.new()
var material = ShaderMaterial.new()
func _ready() -> void: func _ready() -> void:
material.shader = generate_mesh_shader
meshinstance.material_override = material
add_child(meshinstance)
gpu_sdf = ComputeSdf.new() gpu_sdf = ComputeSdf.new()
gpu_sdf.create_device() gpu_sdf.create_device()
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
clear() clear()
surface_points = gpu_sdf.compute(world_size, RADIUS) var dictionaries = gpu_sdf.compute(world_size, RADIUS)
surface_points = dictionaries.surface_points_dict
sample_points = dictionaries.sample_points_dict
if !surface_points.is_empty(): if !surface_points.is_empty():
#create_surface_points_gpu() #create_surface_points_gpu()
#create_surface_points() #create_surface_points()
if show_surface_points: if show_surface_points:
draw_surface_points() draw_surface_points()
if show_surface: if show_surface:
create_surface_mesh(world_size) create_surface_mesh()
if show_sample_points: if show_sample_points:
draw_sample_points() draw_sample_points()
@ -49,9 +56,7 @@ func _process(_delta: float) -> void:
func clear(): func clear():
surface_points = {} surface_points = {}
mesh = ArrayMesh.new() mesh = ArrayMesh.new()
for child in get_children():
if child is MeshInstance3D:
child.queue_free()
func get_index_from_coords(coords: Vector3i): func get_index_from_coords(coords: Vector3i):
return coords.x + coords.y * world_size + coords.z * world_size * world_size return coords.x + coords.y * world_size + coords.z * world_size * world_size
@ -68,64 +73,27 @@ func draw_surface_points():
for surface_point in surface_points: for surface_point in surface_points:
if surface_points[surface_point] != Vector3(0, 0, 0): if surface_points[surface_point] != Vector3(0, 0, 0):
DebugDraw3D.draw_square(surface_points[surface_point] , 0.3, surface_point_color) DebugDraw3D.draw_square(surface_points[surface_point] , 0.3, surface_point_color)
#DebugDraw3D.draw_text(surface_points[Vector3i(x, y, z)], str(surface_points[Vector3i(x, y, z)])) DebugDraw3D.draw_text(surface_points[surface_point], str(surface_points[surface_point]))
func create_surface_points():
for x in range(world_size):
for y in range(world_size):
for z in range(world_size):
create_surface_point(Vector3i(x, y, z))
func create_surface_point(voxel: Vector3i):
var previous_sign = 0
var previous_sample_point
var previous_sample_point_distance_from_sdf
var intersection_points_sum = Vector3.ZERO
var intersection_points_number = 0
for sample_point_to_check_index in range(SURFACE_AXIS.size()):
var sample_point_to_check = voxel + SURFACE_AXIS[sample_point_to_check_index]
var normal_x = sample_point_to_check.x + world_size - 1
var normal_y = sample_point_to_check.y + world_size - 1
var normal_z = sample_point_to_check.z + world_size - 1
var buffer_index = sample_point_to_check.x + sample_point_to_check.y * world_size + sample_point_to_check.z * world_size * world_size
if buffer_index < sdf_buffer.size():
var sample_point_distance_from_sdf = sdf_buffer[buffer_index]#get_sample_value(sample_point_to_check)
sample_points[sample_point_to_check] = sample_point_distance_from_sdf
if previous_sign != 0 && sign(sample_point_distance_from_sdf) != previous_sign:
var intersection_point = (1-previous_sample_point_distance_from_sdf/(previous_sample_point_distance_from_sdf - sample_point_distance_from_sdf))*previous_sample_point+(previous_sample_point_distance_from_sdf/(previous_sample_point_distance_from_sdf-sample_point_distance_from_sdf)*sample_point_to_check)
intersection_points_sum += intersection_point
intersection_points_number += 1
previous_sign = sign(sample_point_distance_from_sdf)
previous_sample_point = sample_point_to_check
previous_sample_point_distance_from_sdf = sample_point_distance_from_sdf
if intersection_points_sum != Vector3.ZERO && intersection_points_number != 0:
var intersection_points_average = intersection_points_sum/Vector3(intersection_points_number, intersection_points_number, intersection_points_number)
var surface_point = SurfacePoint.new()
surface_point.position = intersection_points_average
surface_points[voxel] = surface_point
func calculate_surface_point_position(voxel: Vector3i): func calculate_surface_point_position(voxel: Vector3i):
var final_point = Vector3(voxel) var final_point = Vector3(voxel)
return final_point return final_point
func create_surface_mesh(size: int = 6): func create_surface_mesh():
surface_tool = SurfaceTool.new() surface_tool = SurfaceTool.new()
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES) surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
for x in range(-size, size): for x in range(world_size):
for y in range(-size, size): for y in range(world_size):
for z in range(-size, size): for z in range(world_size):
if surface_points.has(Vector3i(x, y, z)): if surface_points.has(Vector3i(x, y, z)):
create_surface_mesh_quad(Vector3i(x,y,z)); create_surface_mesh_quad(Vector3i(x,y,z));
mesh = surface_tool.commit() mesh = surface_tool.commit()
var meshinstance = MeshInstance3D.new()
meshinstance.mesh = mesh meshinstance.mesh = mesh
add_child(meshinstance)
func create_surface_mesh_quad(index: Vector3i): func create_surface_mesh_quad(index: Vector3i):
for axis_index in range(AXIS.size()): for axis_index in range(AXIS.size()):
var axis = AXIS[axis_index] var axis = AXIS[axis_index]
if sample_points.has(index + axis): if sample_points.has(index + axis):
var sample_value1 = sample_points[index] var sample_value1 = sample_points[index]
var sample_value2 = sample_points[index + axis] var sample_value2 = sample_points[index + axis]
@ -179,10 +147,10 @@ func add_reversed_quad(index: Vector3i, axis_index: int):
func get_quad_points(index: Vector3i, axis_index: int): func get_quad_points(index: Vector3i, axis_index: int):
if surface_points.has(index + QUAD_POINTS[axis_index][0]) and surface_points.has(index + QUAD_POINTS[axis_index][1]) and surface_points.has(index + QUAD_POINTS[axis_index][2]) and surface_points.has(index + QUAD_POINTS[axis_index][3]): if surface_points.has(index + QUAD_POINTS[axis_index][0]) and surface_points.has(index + QUAD_POINTS[axis_index][1]) and surface_points.has(index + QUAD_POINTS[axis_index][2]) and surface_points.has(index + QUAD_POINTS[axis_index][3]):
return [ return [
surface_points[index + QUAD_POINTS[axis_index][0]].position, surface_points[index + QUAD_POINTS[axis_index][0]],
surface_points[index + QUAD_POINTS[axis_index][1]].position, surface_points[index + QUAD_POINTS[axis_index][1]],
surface_points[index + QUAD_POINTS[axis_index][2]].position, surface_points[index + QUAD_POINTS[axis_index][2]],
surface_points[index + QUAD_POINTS[axis_index][3]].position, surface_points[index + QUAD_POINTS[axis_index][3]],
] ]
const QUAD_POINTS := [ const QUAD_POINTS := [

View File

@ -1,8 +1,15 @@
[gd_scene load_steps=2 format=3 uid="uid://llggsd0qmn4p"] [gd_scene load_steps=4 format=3 uid="uid://llggsd0qmn4p"]
[ext_resource type="Script" uid="uid://bdfq22we54eul" path="res://smooth_world.gd" id="1_4h467"] [ext_resource type="Script" uid="uid://bdfq22we54eul" path="res://smooth_world.gd" id="1_4h467"]
[ext_resource type="Shader" uid="uid://bose286qacwdl" path="res://generate_mesh.tres" id="2_an62b"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_iutkt"]
render_priority = 0
shader = ExtResource("2_an62b")
[node name="SmoothWorld" type="Node3D"] [node name="SmoothWorld" type="Node3D"]
script = ExtResource("1_4h467") script = ExtResource("1_4h467")
RADIUS = 6.789 RADIUS = 6.789
show_surface_points = true
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
material_override = SubResource("ShaderMaterial_iutkt")