diff --git a/compute_samples.gd b/compute_samples.gd index 1844a62..0277e1f 100644 --- a/compute_samples.gd +++ b/compute_samples.gd @@ -1,4 +1,4 @@ - +extends Node3D var rd: RenderingDevice var shader_file1: Resource var shader_file2: Resource @@ -7,6 +7,8 @@ var shader_spirv2: RDShaderSPIRV var shader_pass1: RID var shader_pass2: RID var start_time := Time.get_ticks_msec() / 1000.0 +var color = Color.CORAL +@export var iout_surface_points = [] func create_device(): rd = RenderingServer.create_local_rendering_device() @@ -142,6 +144,7 @@ func compute_mesh(world_size: int, threshold: float) -> ArrayMesh: var out_norms = rd.buffer_get_data(normal_buffer).to_float32_array() var out_indices = rd.buffer_get_data(idx_buffer).to_int32_array() var final_count = rd.buffer_get_data(counter_buffer).to_int32_array()[0] + var out_surface_points = rd.buffer_get_data(surface_buffer).to_float32_array() rd.free_rid(buffer) rd.free_rid(params_buffer) @@ -185,7 +188,7 @@ func compute_mesh(world_size: int, threshold: float) -> ArrayMesh: packed_indices.append(active_map[old_idx]) - + iout_surface_points = out_surface_points if packed_verts.size() > 0: arrays[Mesh.ARRAY_VERTEX] = packed_verts arrays[Mesh.ARRAY_NORMAL] = packed_normals @@ -193,7 +196,6 @@ func compute_mesh(world_size: int, threshold: float) -> ArrayMesh: mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) return mesh - func build_sample_dict(world_size: int, flat_buffer: PackedFloat32Array) -> Dictionary: var dict := {} diff --git a/generate_mesh.tres b/generate_mesh.tres index 80663c1..f6047a2 100644 --- a/generate_mesh.tres +++ b/generate_mesh.tres @@ -4,6 +4,7 @@ constant = Color(0.30202293, 0.6060653, 0.9109474, 1) [resource] +modes/cull = 2 nodes/vertex/0/position = Vector2(360, 220) nodes/fragment/0/position = Vector2(660, 140) nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_sxi40") diff --git a/sdf_mesh_generation.glsl b/sdf_mesh_generation.glsl index a7bf065..87f9755 100644 --- a/sdf_mesh_generation.glsl +++ b/sdf_mesh_generation.glsl @@ -17,20 +17,21 @@ bool has_vertex(ivec3 p) { // Boundary check for the voxel itself if (any(lessThan(p, ivec3(0))) || any(greaterThanEqual(p, ivec3(params.world_size)))) return false; uint idx = index3(uint(p.x), uint(p.y), uint(p.z)); - return surface.surface_points[idx * 3u] > -0.5; + return surface.surface_points[idx * 3u] > - 0.5; } // Translated QUAD_POINTS from your GDScript const ivec3 QUAD_OFFSETS[3][4] = ivec3[3][4]( // X-Axis Edges ivec3[](ivec3(0,0,-1), ivec3(0,-1,-1), ivec3(0,-1,0), ivec3(0,0,0)), - // Y-Axis Edges - ivec3[](ivec3(0,0,-1), ivec3(0,0,0), ivec3(-1,0,0), ivec3(-1,0,-1)), - // Z-Axis Edges - ivec3[](ivec3(0,0,0), ivec3(0,-1,0), ivec3(-1,-1,0), ivec3(-1,0,0)) + // Y-Axis Edges + ivec3[](ivec3(0,0,-1), ivec3(0,0,0), ivec3(-1,0,0), ivec3(-1,0,-1)), + // Z-Axis Edges + ivec3[](ivec3(0,0,0), ivec3(0,-1,0), ivec3(-1,-1,0), ivec3(-1,0,0)) ); void main() { + memoryBarrierBuffer(); ivec3 id = ivec3(gl_GlobalInvocationID); if (id.x >= params.world_size || id.y >= params.world_size || id.z >= params.world_size) return; @@ -42,20 +43,17 @@ void main() { for (int i = 0; i < 3; i++) { ivec3 neighbor_id = id + AXIS[i]; - // Ensure neighbor is in bounds before sampling noise - if (any(greaterThanEqual(neighbor_id, ivec3(params.world_size)))) continue; + if (any(greaterThan(neighbor_id, ivec3(params.world_size)))) continue; float d1 = voxels.sample_points[idx]; float d2 = voxels.sample_points[index3(neighbor_id.x, neighbor_id.y, neighbor_id.z)]; - // Sign change check (Crossing detection) if ((d1 < 0.0) != (d2 < 0.0)) { ivec3 p0 = id + QUAD_OFFSETS[i][0]; ivec3 p1 = id + QUAD_OFFSETS[i][1]; ivec3 p2 = id + QUAD_OFFSETS[i][2]; ivec3 p3 = id + QUAD_OFFSETS[i][3]; - // Verify all 4 surrounding voxels have valid vertices if (has_vertex(p0) && has_vertex(p1) && has_vertex(p2) && has_vertex(p3)) { uint v0 = index3(p0.x, p0.y, p0.z); uint v1 = index3(p1.x, p1.y, p1.z); @@ -64,7 +62,6 @@ void main() { uint start = atomicAdd(index_count.count, 6); - // Use the same winding logic as your add_quad / add_reversed_quad if (d1 < 0.0) { mesh_indices.indices[start + 0] = v0; mesh_indices.indices[start + 1] = v1; diff --git a/sdf_shader.glsl b/sdf_shader.glsl index 87aba07..c2f8ce8 100644 --- a/sdf_shader.glsl +++ b/sdf_shader.glsl @@ -181,7 +181,7 @@ const ivec3 CORNERS[8] = ivec3[]( ); float get_noise_at(vec3 p) { - return snoise((p / 10.0) + vec3(params.u_time * .5)) * 5.0; + return snoise((p / 20.0) + vec3(params.u_time * .5)); } // Calculate normal using central difference @@ -193,19 +193,21 @@ vec3 calculate_normal(vec3 p) { return normalize(vec3(dx, dy, dz)); } -void main() { - uvec3 id = gl_GlobalInvocationID; - if (id.x >= uint(params.world_size) || - id.y >= uint(params.world_size) || - id.z >= uint(params.world_size)) - return; +vec3 grid_to_world(uvec3 grid_id) { + return (vec3(grid_id) - params.world_size / 2.0) * 0.5; +} - vec3 p = vec3(id) - params.world_size / 2; +void main() { + ivec3 id = ivec3(gl_GlobalInvocationID); + if (any(greaterThanEqual(id, uvec3(params.world_size)))) return; + + vec3 p = grid_to_world(id); uint idx = index3(id.x, id.y, id.z); voxels.sample_points[idx] = get_noise_at(p); - barrier(); memoryBarrierBuffer(); + barrier(); + vec3 intersection_sum = vec3(0.0); uint count = 0; @@ -223,11 +225,11 @@ void main() { if (any(greaterThanEqual(c1, uvec3(params.world_size))) || any(greaterThanEqual(c2, uvec3(params.world_size)))) continue; - float d1 = voxels.sample_points[index3(c1.x, c1.y, c1.z)]; - float d2 = voxels.sample_points[index3(c2.x, c2.y, c2.z)]; + float d1 = get_noise_at(grid_to_world(c1)); + float d2 = get_noise_at(grid_to_world(c2)); // Standard sign-change test - if ((d1 < 0.0) != (d2 < 0.0)) { + if ((d1 < 0.0) != (d2 < 0.0) && d1 != -d2) { // Linear interpolation to find the exact crossing point on the edge float t = d1 / (d1 - d2); intersection_sum += mix(vec3(c1), vec3(c2), t); @@ -240,7 +242,7 @@ void main() { store_surface_point(idx, avg_pos); // Normals should be calculated at the exact averaged surface point - vec3 world_p = avg_pos - params.world_size / 2.0; + vec3 world_p = (avg_pos - params.world_size / 2.0) * vec3(0.5); vec3 n = calculate_normal(world_p); uint base = idx * 3u; normal.normals[base + 0] = n.x; diff --git a/smooth_world.gd b/smooth_world.gd index 7fe0b19..00c978c 100644 --- a/smooth_world.gd +++ b/smooth_world.gd @@ -53,11 +53,21 @@ func _process(_delta: float) -> void: #regenerate_mesh = false clear() meshinstance.mesh = gpu_sdf.compute_mesh(world_size, RADIUS) - if !surface_points.is_empty(): - if show_surface_points: - draw_surface_points() - if show_sample_points: - draw_sample_points() + if show_surface_points: + var idx = 0 + var text_id = 0 + while idx < gpu_sdf.iout_surface_points.size(): + text_id += 1 + var value = Vector3(gpu_sdf.iout_surface_points.get(idx), gpu_sdf.iout_surface_points.get(idx+1), gpu_sdf.iout_surface_points.get(idx+2)) - Vector3(world_size / 2, world_size / 2, world_size / 2) + if gpu_sdf.iout_surface_points.get(idx) != -1.0: + DebugDraw3D.draw_square(value, 0.2, color.from_rgba8(255, 128, 128, 255)) + if text_id % 3 == 0: + DebugDraw3D.draw_text(value, str(value), 35) + idx += 3 + else: + idx += 1 + if show_sample_points: + draw_sample_points() func clear(): diff --git a/smooth_world.tscn b/smooth_world.tscn index 69da829..b8c5d5f 100644 --- a/smooth_world.tscn +++ b/smooth_world.tscn @@ -10,7 +10,7 @@ shader = ExtResource("2_an62b") [node name="SmoothWorld" type="Node3D" unique_id=1592820568] script = ExtResource("1_4h467") RADIUS = 18.524 -world_size = 64 +world_size = 53 [node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1739626442] material_override = SubResource("ShaderMaterial_iutkt") diff --git a/world.tscn b/world.tscn index 04786f2..e007fad 100644 --- a/world.tscn +++ b/world.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=6 format=3 uid="uid://dls7ggmf46ia0"] +[gd_scene format=3 uid="uid://dls7ggmf46ia0"] [ext_resource type="Script" uid="uid://caefudn8tgqpr" path="res://activation.gd" id="1_tlwt5"] [ext_resource type="PackedScene" uid="uid://chbs3naovk63w" path="res://player.tscn" id="3_036b0"] @@ -16,20 +16,20 @@ sky = SubResource("Sky_tlwt5") tonemap_mode = 2 glow_enabled = true -[node name="Root" type="Node3D"] +[node name="Root" type="Node3D" unique_id=1762688074] script = ExtResource("1_tlwt5") wanted_world = 1 -[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=340320928] environment = SubResource("Environment_aqk2v") -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1883705458] transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) shadow_enabled = true -[node name="Player" parent="." instance=ExtResource("3_036b0")] +[node name="Player" parent="." unique_id=1950519856 instance=ExtResource("3_036b0")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.182447, 0.6673207, 0.0726881) -PLAYER_SPEED = 0.305 +PLAYER_SPEED = 0.035 NOCLIP = true [connection signal="change_world" from="." to="." method="_on_change_world"]