diff --git a/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl b/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl index 3ceecf3..f695908 100644 --- a/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl +++ b/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl @@ -6,8 +6,8 @@ layout(set = 0, binding = 0) uniform sampler2D depth_sampler; layout(set = 0, binding = 1) uniform sampler2D velocity_sampler; -layout(rgba16f, set = 0, binding = 2) uniform writeonly image2D buffer_a; -layout(rgba16f, set = 0, binding = 3) uniform writeonly image2D buffer_b; +layout(rg16f, set = 0, binding = 2) uniform writeonly image2D buffer_a; +layout(rg16f, set = 0, binding = 3) uniform writeonly image2D buffer_b; layout(set = 0, binding = 4) uniform sampler2D buffer_a_sampler; layout(set = 0, binding = 5) uniform sampler2D buffer_b_sampler; @@ -36,14 +36,14 @@ layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; const int kernel_size = 8; const vec2 check_step_kernel[kernel_size] = { - vec2(1, 1), + vec2(-1, 0), + vec2(1, 0), + vec2(0, -1), vec2(0, 1), vec2(-1, 1), - vec2(1, 0), vec2(1, -1), - vec2(-1, 0), + vec2(1, 1), vec2(-1, -1), - vec2(0, -1), }; vec4 get_value(bool a, vec2 uv, ivec2 render_size) @@ -91,14 +91,16 @@ float get_motion_difference(vec2 V, vec2 V2, float parallel_sensitivity, float p } // ---------------------------------------------------------- -vec4 sample_fitness(vec2 uv_offset, vec4 uv_sample) +vec4 sample_fitness(vec2 uv_offset, vec4 uv_sample, vec2 render_size) { vec2 sample_velocity = -uv_sample.xy; + // if velocity is 0, we never reach it (steps never smaller than 1) if (dot(sample_velocity, sample_velocity) <= FLT_MIN || uv_sample.w == 0) { return vec4(FLT_MAX, FLT_MAX, FLT_MAX, 0); } + // velocity space distance (projected pixel offset onto velocity vector) float velocity_space_distance = dot(sample_velocity, uv_offset) / dot(sample_velocity, sample_velocity); // the velcity space distance to gravitate the JFA to (found more relieable than doing a 0 - 1 range) @@ -118,18 +120,13 @@ vec4 sample_fitness(vec2 uv_offset, vec4 uv_sample) float is_sample_better(vec4 a, vec4 b) { // see explanation at end of code - return mix(1. - step(b.x * a.w, a.x * b.w * (1. - step(b.z, a.z))), (1. - step(a.z, b.z)), step(abs(a.w - b.w), 0.5) * step(0.5, a.w)); -} - -vec2 round_uv(vec2 uv, vec2 render_size) -{ - return (round((uv * render_size) - vec2(0.5)) + vec2(0.5)) / render_size; + return mix(1. - step(b.x * a.w, a.x * b.w), step(b.z, a.z), step(0.5, b.w) * step(0.5, a.w)); } // dilation validation and better sample selection vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec3 chosen_velocity, vec4 best_sample_fitness, vec2 render_size) { - //return vec4(chosen_uv, best_sample_fitness.z, 0);// comment this to enable backtracking + //return vec4(chosen_uv, best_sample_fitness.z, best_sample_fitness.w);// comment this to enable backtracking float smallest_step = 1 / max(render_size.x, render_size.y); // choose maximum range to check along (matches with implementation in blur stage) @@ -137,7 +134,7 @@ vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec3 chosen_velocity, vec4 vec2 best_uv = chosen_uv; - //float best_multiplier = best_sample_fitness.y; + float best_multiplier = best_sample_fitness.y; float best_depth = best_sample_fitness.z; @@ -157,7 +154,7 @@ vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec3 chosen_velocity, vec4 continue; } - vec2 check_uv = round_uv(uvn - chosen_velocity.xy * velocity_multiplier, render_size); + vec2 check_uv = uvn - chosen_velocity.xy * velocity_multiplier; if(any(notEqual(check_uv, clamp(check_uv, vec2(0.0), vec2(1.0))))) { @@ -176,18 +173,18 @@ vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec3 chosen_velocity, vec4 if((abs(current_depth - best_sample_fitness.z) < params.depth_match_threshold) && (velocity_difference <= smallest_velocity_difference)) { best_uv = check_uv; - //best_multiplier = velocity_multiplier; + best_multiplier = velocity_multiplier; best_depth = current_depth; if(steps_to_compare == 0) { - return vec4(best_uv, best_depth, 0); + return vec4(best_uv, best_depth, best_multiplier); } steps_to_compare--; } // if a sample was found and we lost footing after, go with that found sample right away else if(initial_steps_to_compare > steps_to_compare) { - return vec4(best_uv, best_depth, 0); + return vec4(best_uv, best_depth, best_multiplier); } } @@ -202,10 +199,11 @@ void main() { return; } - // must be on pixel center for whole values (tested) + + // must be on pixel center for whole values vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size; - vec2 uv_step = vec2(params.step_size) / render_size; + vec2 uv_step = vec2(round(params.step_size)) / render_size; vec4 best_sample_fitness = vec4(FLT_MAX, FLT_MAX, FLT_MAX, 0); @@ -236,7 +234,7 @@ void main() vec4 uv_sample = vec4(textureLod(velocity_sampler, check_uv, 0.0).xyz, textureLod(depth_sampler, check_uv, 0.0).x); - vec4 current_sample_fitness = sample_fitness(step_offset, uv_sample); + vec4 current_sample_fitness = sample_fitness(step_offset, uv_sample, render_size); if (is_sample_better(current_sample_fitness, best_sample_fitness) > 0.5) { @@ -253,8 +251,8 @@ void main() } float depth = textureLod(depth_sampler, uvn, 0.0).x; - // best_sample_fitness.z contains the depth of the texture + offset of velocity z + // best_sample_fitness.z contains the depth of the texture + offset of velocity z vec4 backtracked_sample = get_backtracked_sample(uvn, chosen_uv, chosen_velocity, best_sample_fitness, render_size); if(best_sample_fitness.w == 0 || depth > backtracked_sample.z) @@ -263,17 +261,14 @@ void main() return; } - set_value(set_a, uvi, vec4(backtracked_sample.xy, 0, backtracked_sample.w), render_size); + set_value(set_a, uvi, backtracked_sample, render_size); return; } - -// ------ sample fitness conditions ------- +// // if((a.w == b.w) && (a.w == 1)) // { -// return a.z < b.z ? 1. : 0.; +// return a.z < b.z ? 0. : 1.; // } // -// float nearer = a.z > b.z ? 1 : 0; -// -// return a.x * b.w * nearer < b.x * a.w ? 1. : 0.; \ No newline at end of file +// return a.x * b.w < b.x * a.w ? 1. : 0.; \ No newline at end of file diff --git a/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl.import b/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl.import index 7eca49b..4eb6671 100644 --- a/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl.import +++ b/addons/MyJumpFloodIteration/jfp_backtracking_experimental.glsl.import @@ -2,7 +2,7 @@ importer="glsl" type="RDShaderFile" -uid="uid://yfjbb3iso4jt" +uid="uid://3v1b0hrdm7nw" path="res://.godot/imported/jfp_backtracking_experimental.glsl-d67307f6899fed647164be410a7debc8.res" [deps] diff --git a/addons/MyJumpFloodIteration/jump_flood_blur.gd b/addons/MyJumpFloodIteration/jump_flood_blur.gd index 5bc7b2b..7948086 100644 --- a/addons/MyJumpFloodIteration/jump_flood_blur.gd +++ b/addons/MyJumpFloodIteration/jump_flood_blur.gd @@ -96,6 +96,8 @@ var rd: RenderingDevice var linear_sampler: RID +var nearest_sampler : RID + var construct_shader : RID var construct_pipeline : RID @@ -142,7 +144,14 @@ func _initialize_compute(): sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE linear_sampler = rd.sampler_create(sampler_state) - + + sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_NEAREST + sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_NEAREST + sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE + sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE + + nearest_sampler = rd.sampler_create(sampler_state) + var construct_shader_spirv : RDShaderSPIRV = construction_pass.get_spirv() construct_shader = rd.shader_create_from_spirv(construct_shader_spirv) construct_pipeline = rd.compute_pipeline_create(construct_shader) @@ -162,11 +171,11 @@ func get_image_uniform(image: RID, binding: int) -> RDUniform: uniform.add_id(image) return uniform -func get_sampler_uniform(image: RID, binding: int) -> RDUniform: +func get_sampler_uniform(image: RID, binding: int, linear : bool = true) -> RDUniform: var uniform: RDUniform = RDUniform.new() uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE uniform.binding = binding - uniform.add_id(linear_sampler) + uniform.add_id(linear_sampler if linear else nearest_sampler) uniform.add_id(image) return uniform @@ -200,8 +209,8 @@ func _render_callback(p_effect_callback_type, p_render_data): return ensure_texture(texture, render_scene_buffers) - ensure_texture(buffer_a, render_scene_buffers) - ensure_texture(buffer_b, render_scene_buffers) + ensure_texture(buffer_a, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16_SFLOAT) + ensure_texture(buffer_b, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16_SFLOAT) ensure_texture(past_color, render_scene_buffers) ensure_texture(custom_velocity, render_scene_buffers) @@ -250,12 +259,12 @@ func _render_callback(p_effect_callback_type, p_render_data): var y_groups := floori((render_size.y - 1) / 16 + 1) tex_uniform_set = UniformSetCacheRD.get_cache(construct_shader, 0, [ - get_sampler_uniform(depth_image, 0), - get_sampler_uniform(custom_velocity_image, 1), + get_sampler_uniform(depth_image, 0, false), + get_sampler_uniform(custom_velocity_image, 1, false), get_image_uniform(buffer_a_image, 2), get_image_uniform(buffer_b_image, 3), - get_sampler_uniform(buffer_a_image, 4), - get_sampler_uniform(buffer_b_image, 5) + get_sampler_uniform(buffer_a_image, 4, false), + get_sampler_uniform(buffer_b_image, 5, false) ]) compute_list = rd.compute_list_begin() @@ -300,10 +309,10 @@ func _render_callback(p_effect_callback_type, p_render_data): rd.draw_command_begin_label("Compute blur " + str(view), Color(1.0, 1.0, 1.0, 1.0)) tex_uniform_set = UniformSetCacheRD.get_cache(motion_blur_shader, 0, [ - get_sampler_uniform(color_image, 0), - get_sampler_uniform(depth_image, 1), - get_sampler_uniform(custom_velocity_image, 2), - get_sampler_uniform(buffer_b_image if last_iteration_index % 2 else buffer_a_image, 3), + get_sampler_uniform(color_image, 0, false), + get_sampler_uniform(depth_image, 1, false), + get_sampler_uniform(custom_velocity_image, 2, false), + get_sampler_uniform(buffer_b_image if last_iteration_index % 2 else buffer_a_image, 3, false), get_image_uniform(texture_image, 4), get_image_uniform(past_color_image, 5), ]) diff --git a/addons/MyJumpFloodIteration/jump_flood_blur.glsl b/addons/MyJumpFloodIteration/jump_flood_blur.glsl index 58a0378..fa3c665 100644 --- a/addons/MyJumpFloodIteration/jump_flood_blur.glsl +++ b/addons/MyJumpFloodIteration/jump_flood_blur.glsl @@ -64,11 +64,6 @@ float soft_depth_compare(float depth_X, float depth_Y) } // ------------------------------------------------------- -vec2 round_uv(vec2 uv, vec2 render_size) -{ - return (round((uv * render_size) - vec2(0.5)) + vec2(0.5)) / render_size; -} - void main() { ivec2 render_size = ivec2(textureSize(color_sampler, 0)); @@ -122,11 +117,7 @@ void main() vec4 col = base_color * total_weight; - float dominant_depth = textureLod(depth_sampler, velocity_map_sample.xy, 0.0).x; - float naive_depth = textureLod(depth_sampler, uvn, 0.0).x; - // is dilation in front of ground truth (have we started sampling inside a dilation) - float dilation_foreground = step(naive_depth, dominant_depth - 0.000001); for (int i = 1; i < params.motion_blur_samples; i++) { @@ -134,9 +125,9 @@ void main() naive_offset += naive_step_sample; - vec2 dominant_uvo = round_uv(uvn + dominant_offset.xy, render_size); + vec2 dominant_uvo = uvn + dominant_offset.xy; - vec2 naive_uvo = round_uv(uvn + naive_offset.xy, render_size); + vec2 naive_uvo = uvn + naive_offset.xy; if (any(notEqual(dominant_uvo, clamp(dominant_uvo, vec2(0.0), vec2(1.0))))) { @@ -145,27 +136,21 @@ void main() velocity_map_step_sample = textureLod(velocity_map, dominant_uvo, 0.0); - vec3 current_velocity = -textureLod(vector_sampler, velocity_map_step_sample.xy, 0.0).xyz; - - float current_dominant_depth = textureLod(depth_sampler, velocity_map_step_sample.xy, 0.0).x; + vec3 current_dominant_velocity = -textureLod(vector_sampler, velocity_map_step_sample.xy, 0.0).xyz; float current_naive_depth = textureLod(depth_sampler, dominant_uvo, 0.0).x; // is current velocity different than dilated velocity - float motion_difference = get_motion_difference(dominant_velocity.xy, current_velocity.xy, 0.1); + float motion_difference = get_motion_difference(dominant_velocity.xy, current_dominant_velocity.xy, 0.1); // is current depth closer than origin of dilation (object in the foreground) float foreground = step(naive_depth + dominant_offset.z, current_naive_depth - 0.0001); - // is dilation in front of current ground truth (are we within a dilation still) - float naive_foreground = step(0.05 / dominant_depth + 0.1, 0.05 / current_naive_depth); // if we are sampling a foreground object and its velocity is different, discard this sample (prevent ghosting) float sample_weight = 1 - (foreground * motion_difference); - float naive_sample_weight = 1 - (foreground * motion_difference); - // if we started from and are still inside a dilation, choose the naive values for blurring - float dominant_naive_mix = dilation_foreground * naive_foreground; + float dominant_naive_mix = 1. - step(0.9, motion_difference); - vec2 sample_uv = mix(dominant_uvo, naive_uvo, dominant_naive_mix); + vec2 sample_uv = mix(naive_uvo, dominant_uvo, dominant_naive_mix); - total_weight += mix(sample_weight, naive_sample_weight, dominant_naive_mix); + total_weight += sample_weight; col += textureLod(color_sampler, sample_uv, 0.0) * sample_weight; } @@ -197,8 +182,8 @@ void main() if(params.debug_page == 1) { tl_col = vec4(naive_depth * 10); - tr_col = vec4(dilation_foreground); - bl_col = vec4(dominant_depth * 10); + tr_col = textureLod(color_sampler, velocity_map_sample.xy, 0.0);// + //bl_col = vec4(dominant_depth * 10); br_col = col; } diff --git a/addons/MyJumpFloodIteration/jump_flood_blur.glsl.import b/addons/MyJumpFloodIteration/jump_flood_blur.glsl.import index 22b9599..153a4e6 100644 --- a/addons/MyJumpFloodIteration/jump_flood_blur.glsl.import +++ b/addons/MyJumpFloodIteration/jump_flood_blur.glsl.import @@ -2,7 +2,7 @@ importer="glsl" type="RDShaderFile" -uid="uid://c3hemlr50tv6p" +uid="uid://wfmvke70qcpa" path="res://.godot/imported/jump_flood_blur.glsl-df0c6b7cc65d8b0520871790f9075253.res" [deps] diff --git a/addons/MyJumpFloodIteration/jump_flood_overlay.glsl.import b/addons/MyJumpFloodIteration/jump_flood_overlay.glsl.import index 6868d27..3366cf8 100644 --- a/addons/MyJumpFloodIteration/jump_flood_overlay.glsl.import +++ b/addons/MyJumpFloodIteration/jump_flood_overlay.glsl.import @@ -2,7 +2,7 @@ importer="glsl" type="RDShaderFile" -uid="uid://d03sqqhg3n1ys" +uid="uid://bbnb4hw0aoqy1" path="res://.godot/imported/jump_flood_overlay.glsl-764d3c488a9e9576eab825591e868325.res" [deps] diff --git a/addons/PreBlurProcessing/default_component.tres b/addons/PreBlurProcessing/default_component.tres new file mode 100644 index 0000000..3962537 --- /dev/null +++ b/addons/PreBlurProcessing/default_component.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="BlurVelocityComponentResource" load_steps=2 format=3 uid="uid://rp3mpjmisoyh"] + +[ext_resource type="Script" path="res://PreBlurProcessing/blur_velocity_component_resource.gd" id="1_ijikr"] + +[resource] +script = ExtResource("1_ijikr") +multiplier = 1.0 +lower_threshold = 0.0 +upper_threshold = 0.0 diff --git a/addons/PreBlurProcessing/pre_blur_processor.gd b/addons/PreBlurProcessing/pre_blur_processor.gd index 41a3322..8f0c9a4 100644 --- a/addons/PreBlurProcessing/pre_blur_processor.gd +++ b/addons/PreBlurProcessing/pre_blur_processor.gd @@ -6,9 +6,9 @@ class_name PreBlurProcessor pre_blur_processor_shader_file = value _init() -@export var camera_rotation_component : BlurVelocityComponentResource = BlurVelocityComponentResource.new() -@export var camera_movement_component : BlurVelocityComponentResource = BlurVelocityComponentResource.new() -@export var object_movement_component : BlurVelocityComponentResource = BlurVelocityComponentResource.new() +@export var camera_rotation_component : BlurVelocityComponentResource = preload("res://addons/PreBlurProcessing/default_component.tres") +@export var camera_movement_component : BlurVelocityComponentResource = preload("res://addons/PreBlurProcessing/default_component.tres") +@export var object_movement_component : BlurVelocityComponentResource = preload("res://addons/PreBlurProcessing/default_component.tres") var context: StringName = "MotionBlur" @@ -16,6 +16,8 @@ var rd: RenderingDevice var linear_sampler: RID +var nearest_sampler : RID + var construct_shader : RID var construct_pipeline : RID @@ -47,6 +49,12 @@ func _initialize_compute(): sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE linear_sampler = rd.sampler_create(sampler_state) + sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_NEAREST + sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_NEAREST + sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE + sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE + nearest_sampler = rd.sampler_create(sampler_state) + var shader_spirv: RDShaderSPIRV = pre_blur_processor_shader_file.get_spirv() pre_blur_processor_shader = rd.shader_create_from_spirv(shader_spirv) pre_blur_processor_pipeline = rd.compute_pipeline_create(pre_blur_processor_shader) @@ -58,11 +66,11 @@ func get_image_uniform(image: RID, binding: int) -> RDUniform: uniform.add_id(image) return uniform -func get_sampler_uniform(image: RID, binding: int) -> RDUniform: +func get_sampler_uniform(image: RID, binding: int, linear : bool = true) -> RDUniform: var uniform: RDUniform = RDUniform.new() uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE uniform.binding = binding - uniform.add_id(linear_sampler) + uniform.add_id(linear_sampler if linear else nearest_sampler) uniform.add_id(image) return uniform @@ -102,7 +110,6 @@ func _render_callback(p_effect_callback_type, p_render_data : RenderData): var view_count = render_scene_buffers.get_view_count() for view in range(view_count): - var color_image := render_scene_buffers.get_color_layer(view) var depth_image := render_scene_buffers.get_depth_layer(view) var velocity_image := render_scene_buffers.get_velocity_layer(view) var custom_velocity_image := render_scene_buffers.get_texture_slice(context, custom_velocity, view, 0, 1, 1) @@ -121,11 +128,9 @@ func _render_callback(p_effect_callback_type, p_render_data : RenderData): rd.draw_command_begin_label("Process Velocity Buffer " + str(view), Color(1.0, 1.0, 1.0, 1.0)) tex_uniform_set = UniformSetCacheRD.get_cache(pre_blur_processor_shader, 0, [ - get_sampler_uniform(color_image, 0), - get_sampler_uniform(depth_image, 1), - get_sampler_uniform(velocity_image, 2), - get_image_uniform(custom_velocity_image, 3), - get_image_uniform(color_image, 4), + get_sampler_uniform(depth_image, 0, false), + get_sampler_uniform(velocity_image, 1, false), + get_image_uniform(custom_velocity_image, 2), scene_data_buffer_uniform, ]) diff --git a/addons/PreBlurProcessing/pre_blur_processor.glsl b/addons/PreBlurProcessing/pre_blur_processor.glsl index 36f4c02..e10e55c 100644 --- a/addons/PreBlurProcessing/pre_blur_processor.glsl +++ b/addons/PreBlurProcessing/pre_blur_processor.glsl @@ -4,11 +4,9 @@ #define FLT_MAX 3.402823466e+38 #define FLT_MIN 1.175494351e-38 -layout(set = 0, binding = 0) uniform sampler2D color_sampler; -layout(set = 0, binding = 1) uniform sampler2D depth_sampler; -layout(set = 0, binding = 2) uniform sampler2D vector_sampler; -layout(rgba32f, set = 0, binding = 3) uniform writeonly image2D vector_output; -layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D color_output; +layout(set = 0, binding = 0) uniform sampler2D depth_sampler; +layout(set = 0, binding = 1) uniform sampler2D vector_sampler; +layout(rgba32f, set = 0, binding = 2) uniform writeonly image2D vector_output; struct SceneData { highp mat4 projection_matrix; @@ -119,7 +117,7 @@ float get_view_depth(float depth) void main() { - ivec2 render_size = ivec2(textureSize(color_sampler, 0)); + ivec2 render_size = ivec2(textureSize(vector_sampler, 0)); ivec2 uvi = ivec2(gl_GlobalInvocationID.xy); if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y)) { diff --git a/addons/PreBlurProcessing/pre_blur_processor.glsl.import b/addons/PreBlurProcessing/pre_blur_processor.glsl.import index cbfd7ce..f0622a6 100644 --- a/addons/PreBlurProcessing/pre_blur_processor.glsl.import +++ b/addons/PreBlurProcessing/pre_blur_processor.glsl.import @@ -2,7 +2,7 @@ importer="glsl" type="RDShaderFile" -uid="uid://tx5dpg4cese4" +uid="uid://ccg27o4i1gfty" path="res://.godot/imported/pre_blur_processor.glsl-15aad2fcd84f6b03da65e9fe7bb8e345.res" [deps]