diff --git a/NoclipCamera.gd b/NoclipCamera.gd index 01307b5..678e223 100644 --- a/NoclipCamera.gd +++ b/NoclipCamera.gd @@ -13,6 +13,7 @@ var move_y = 0 var move_z = 0 var camera: Camera3D var ray_hit_positions = [] +var delta_speed = 0 # Declare member variables here. Examples: # var a = 2 # var b = "text" @@ -49,6 +50,7 @@ func _input(event): camera.rotate_object_local(Vector3(-1, 0, 0), rot_y) # then rotate in X # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta): + delta_speed = PLAYER_SPEED * _delta * 500 if NOCLIP: process_noclip() else: @@ -73,9 +75,9 @@ func process_physics_movements(): if Input.is_action_pressed("MoveCamBack"): move_z = -1 - constant_force.y = move_y * PLAYER_SPEED - constant_force.x = (sin(rot_x) * move_z * PLAYER_SPEED + cos(rot_x) * move_x * PLAYER_SPEED) - constant_force.z = (-cos(rot_x) * move_z * PLAYER_SPEED + sin(rot_x) * move_x * PLAYER_SPEED) + constant_force.y = move_y * delta_speed + constant_force.x = (sin(rot_x) * move_z * delta_speed + cos(rot_x) * move_x * delta_speed) + constant_force.z = (-cos(rot_x) * move_z * delta_speed + sin(rot_x) * move_x * delta_speed) if constant_force.x != 0 || constant_force.y != 0 || constant_force.z != 0: physics_material_override.friction = 0 @@ -122,9 +124,9 @@ func process_noclip(): if Input.is_action_pressed("MoveCamBack"): move_z = -1 - position.y += move_y * PLAYER_SPEED - position.x += (sin(rot_x) * move_z * PLAYER_SPEED + cos(rot_x) * move_x * PLAYER_SPEED) - position.z += (-cos(rot_x) * move_z * PLAYER_SPEED + sin(rot_x) * move_x * PLAYER_SPEED) + position.y += move_y * delta_speed + position.x += (sin(rot_x) * move_z * delta_speed + cos(rot_x) * move_x * delta_speed) + position.z += (-cos(rot_x) * move_z * delta_speed + sin(rot_x) * move_x * delta_speed) move_y = 0 move_x = 0 diff --git a/compute_test.gd b/compute_samples.gd similarity index 96% rename from compute_test.gd rename to compute_samples.gd index 8f905bc..76b99ca 100644 --- a/compute_test.gd +++ b/compute_samples.gd @@ -3,6 +3,7 @@ var rd: RenderingDevice var shader_file: Resource var shader_spirv: RDShaderSPIRV var shader: RID +var start_time := Time.get_ticks_msec() / 1000.0 func create_device(): rd = RenderingServer.create_local_rendering_device() @@ -42,10 +43,13 @@ func compute(world_size: int, threshold: float): surface_uniform_buf.binding = 2 # this needs to match the "binding" in our shader file surface_uniform_buf.add_id(surface_buffer) + var u_time := Time.get_ticks_msec() / 1000.0 - start_time + print("utime: ", u_time) + var peer := StreamPeerBuffer.new() peer.put_32(world_size) peer.put_float(threshold) - peer.put_32(0) + peer.put_float(u_time) peer.put_32(0) var bytes := peer.data_array diff --git a/compute_test.gd.uid b/compute_samples.gd.uid similarity index 100% rename from compute_test.gd.uid rename to compute_samples.gd.uid diff --git a/project.godot b/project.godot index bd06016..2b0866b 100644 --- a/project.godot +++ b/project.godot @@ -96,6 +96,11 @@ RightClick={ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null) ] } +RegenerateMesh={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null) +] +} [physics] diff --git a/sdf_shader.glsl b/sdf_shader.glsl index a09f3eb..c298353 100644 --- a/sdf_shader.glsl +++ b/sdf_shader.glsl @@ -1,4 +1,3 @@ - #[compute] #version 450 @@ -13,12 +12,14 @@ layout(set = 0, binding = 0, std430) buffer DataBuffer { layout(set = 0, binding = 1) uniform Params { int world_size; float threshold; + float u_time; } params; layout(set = 0, binding = 2, std430) buffer SurfaceBuffer { float surface_points[]; } surface; + uint index3(uint x, uint y, uint z) { return x + y * params.world_size + z * params.world_size * params.world_size; } @@ -30,6 +31,111 @@ void store_surface_point(uint idx, vec3 pos) { surface.surface_points[base + 2u] = pos.z; } +// +// Description : Array and textureless GLSL 2D/3D/4D simplex +// noise functions. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : stegu +// Lastmod : 20201014 (stegu) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// https://github.com/stegu/webgl-noise +// + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x*34.0)+10.0)*x); +} + +vec4 taylorInvSqrt(vec4 r) +{ + return 1.79284291400159 - 0.85373472095314 * r; +} + +float snoise(vec3 v) +{ + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + + // First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + + // Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + vec3 x1 = x0 - i1 + C.xxx; + vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y + vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = mod289(i); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + float n_ = 0.142857142857; // 1.0/7.0 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + + //Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} + + void main() { uvec3 id = gl_GlobalInvocationID; if (id.x >= uint(params.world_size) || @@ -48,10 +154,9 @@ void main() { ivec3(0,0,0) ); - vec3 p = vec3(id) - params.world_size / 2 + 1; - float d = length(p) - params.threshold; + vec3 p = vec3(id) - params.world_size / 2; uint idx = index3(id.x, id.y, id.z); - voxels.sample_points[idx] = d; + voxels.sample_points[idx] = snoise((p / 10.0) + vec3(params.u_time * .5, params.u_time * .5, params.u_time * .5)) *5.0; int previous_sign = 0; vec3 previous_sample_point_coords = vec3(id.x, id.y, id.z); @@ -62,7 +167,7 @@ void main() { ivec3 sample_point_to_check = ivec3(id) + SURFACE_AXIS[sample_point_to_check_index]; // bounds check - if (sample_point_to_check.x < 0 || sample_point_to_check.y < 0 || sample_point_to_check.z < 0) continue; + //if (sample_point_to_check.x < 0 || sample_point_to_check.y < 0 || sample_point_to_check.z < 0) continue; if (uint(sample_point_to_check.x) >= params.world_size || uint(sample_point_to_check.y) >= params.world_size || uint(sample_point_to_check.z) >= params.world_size) continue; uint buffer_index = index3(uint(sample_point_to_check.x), uint(sample_point_to_check.y), uint(sample_point_to_check.z)); diff --git a/smooth_world.gd b/smooth_world.gd index 540a1db..7d939ff 100644 --- a/smooth_world.gd +++ b/smooth_world.gd @@ -7,12 +7,12 @@ var sample_points = {} var SamplePoint = preload("res://sample_point.gd") var surface_points = {} var SurfacePoint = preload("res://surface_point.gd") -var ComputeSdf = preload("res://compute_test.gd") +var ComputeSdf = preload("res://compute_samples.gd") var gpu_sdf var generate_mesh_shader = preload("res://generate_mesh.tres") -var regenerate_mesh = false +@export var regenerate_mesh = false @export var world_size = 16 @@ -42,6 +42,10 @@ func _ready() -> void: surface_points = dictionaries.surface_points_dict sample_points = dictionaries.sample_points_dict create_surface_mesh() + +func _input(event): + if event is InputEventKey and event.is_action_released("RegenerateMesh"): + regenerate_mesh = !regenerate_mesh func _process(_delta: float) -> void: @@ -51,6 +55,7 @@ func _process(_delta: float) -> void: if show_surface_points: draw_surface_points() if show_surface && regenerate_mesh: + #regenerate_mesh = false clear() var dictionaries = gpu_sdf.compute(world_size, RADIUS) surface_points = dictionaries.surface_points_dict @@ -74,18 +79,14 @@ func draw_sample_points(): for y in range(world_size): for z in range(world_size): if sample_points.has(Vector3i(x, y, z)): - DebugDraw3D.draw_square(Vector3i(x, y, z), 0.2, color) + DebugDraw3D.draw_square(Vector3i(x, y, z), 0.2, color.from_rgba8(sample_points.get(Vector3i(x, y, z)), 128, 128, 255)) #DebugDraw3D.draw_text(Vector3i(x, y, z), str(Vector3i(x, y, z))) func draw_surface_points(): for surface_point in surface_points: if surface_points[surface_point] != Vector3(0, 0, 0): DebugDraw3D.draw_square(surface_points[surface_point] , 0.3, surface_point_color) - DebugDraw3D.draw_text(surface_points[surface_point], str(surface_points[surface_point])) - -func calculate_surface_point_position(voxel: Vector3i): - var final_point = Vector3(voxel) - return final_point + #DebugDraw3D.draw_text(surface_points[surface_point], str(surface_points[surface_point])) func create_surface_mesh(): surface_tool = SurfaceTool.new() @@ -93,8 +94,9 @@ func create_surface_mesh(): for x in range(world_size): for y in range(world_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)); + surface_tool.generate_normals() mesh = surface_tool.commit() meshinstance.mesh = mesh @@ -137,7 +139,6 @@ func add_quad(index: Vector3i, axis_index: int): surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[2]) surface_tool.add_vertex(points[3]) - surface_tool.generate_normals() func add_reversed_quad(index: Vector3i, axis_index: int): var points = get_quad_points(index, axis_index) @@ -150,10 +151,9 @@ func add_reversed_quad(index: Vector3i, axis_index: int): surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[3]) surface_tool.add_vertex(points[2]) - surface_tool.generate_normals() 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]) and surface_points.get(index + QUAD_POINTS[axis_index][0]) != Vector3.ZERO and surface_points.get(index + QUAD_POINTS[axis_index][1]) != Vector3.ZERO and surface_points.get(index + QUAD_POINTS[axis_index][2]) != Vector3.ZERO and surface_points.get(index + QUAD_POINTS[axis_index][3]) != Vector3.ZERO: return [ surface_points[index + QUAD_POINTS[axis_index][0]], surface_points[index + QUAD_POINTS[axis_index][1]], @@ -161,6 +161,7 @@ func get_quad_points(index: Vector3i, axis_index: int): surface_points[index + QUAD_POINTS[axis_index][3]], ] + const QUAD_POINTS := [ # x axis [ diff --git a/smooth_world.tscn b/smooth_world.tscn index a0d11a7..6a18ed7 100644 --- a/smooth_world.tscn +++ b/smooth_world.tscn @@ -10,7 +10,13 @@ shader = ExtResource("2_an62b") [node name="SmoothWorld" type="Node3D"] script = ExtResource("1_4h467") RADIUS = 18.524 -world_size = 39 +regenerate_mesh = null +world_size = 30 +show_sample_points = null +show_surface_points = null +show_surface = null +do_the_thing = null +clear_the_thing = null [node name="MeshInstance3D" type="MeshInstance3D" parent="."] material_override = SubResource("ShaderMaterial_iutkt")