mirror of
https://github.com/sphynx-owner/JFA_driven_motion_blur_addon.git
synced 2025-09-19 04:06:08 +08:00
improvement/fixes: blur quality, blur range, Mac support, performance
- blur heuristics improved for reduced smearing - velocity blur range fixed a bug - fixed MacOs bug regarding doubles in shader - lowered buffer accuracy and changed doubles to floats, improved performance
This commit is contained in:
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#define FLT_MAX 3.402823466e+38
|
#define FLT_MAX 3.402823466e+38
|
||||||
#define FLT_MIN 1.175494351e-38
|
#define FLT_MIN 1.175494351e-38
|
||||||
#define DBL_MAX 1.7976931348623158e+308
|
|
||||||
#define DBL_MIN 2.2250738585072014e-308
|
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler2D depth_sampler;
|
layout(set = 0, binding = 0) uniform sampler2D depth_sampler;
|
||||||
layout(set = 0, binding = 1) uniform sampler2D velocity_sampler;
|
layout(set = 0, binding = 1) uniform sampler2D velocity_sampler;
|
||||||
@ -15,7 +13,7 @@ layout(push_constant, std430) uniform Params
|
|||||||
{
|
{
|
||||||
int iteration_index;
|
int iteration_index;
|
||||||
int last_iteration_index;
|
int last_iteration_index;
|
||||||
int nan1;
|
int backtracking_sample_count;
|
||||||
int nan2;
|
int nan2;
|
||||||
float perpen_error_thresh;
|
float perpen_error_thresh;
|
||||||
float sample_step_multiplier;
|
float sample_step_multiplier;
|
||||||
@ -81,9 +79,9 @@ void set_value(bool a, ivec2 uvi, vec4 value, ivec2 render_size)
|
|||||||
float get_motion_difference(vec2 V, vec2 V2, float parallel_sensitivity, float perpendicular_sensitivity)
|
float get_motion_difference(vec2 V, vec2 V2, float parallel_sensitivity, float perpendicular_sensitivity)
|
||||||
{
|
{
|
||||||
vec2 VO = V - V2;
|
vec2 VO = V - V2;
|
||||||
double parallel = abs(dot(VO, V) / max(DBL_MIN, dot(V, V)));
|
float parallel = abs(dot(VO, V) / max(FLT_MIN, dot(V, V)));
|
||||||
vec2 perpen_V = vec2(V.y, -V.x);
|
vec2 perpen_V = vec2(V.y, -V.x);
|
||||||
double perpendicular = abs(dot(VO, perpen_V) / max(DBL_MIN, dot(V, V)));
|
float perpendicular = abs(dot(VO, perpen_V) / max(FLT_MIN, dot(V, V)));
|
||||||
float difference = float(parallel) * parallel_sensitivity + float(perpendicular) * perpendicular_sensitivity;
|
float difference = float(parallel) * parallel_sensitivity + float(perpendicular) * perpendicular_sensitivity;
|
||||||
return clamp(difference, 0, 1);
|
return clamp(difference, 0, 1);
|
||||||
}
|
}
|
||||||
@ -103,19 +101,19 @@ vec4 sample_fitness(vec2 uv_offset, vec4 uv_sample)
|
|||||||
// uv_offset = normalize(sample_velocity) * FLT_MIN;
|
// uv_offset = normalize(sample_velocity) * FLT_MIN;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
double velocity_space_distance = dot(sample_velocity, uv_offset) / max(FLT_MIN, dot(sample_velocity, sample_velocity));
|
float velocity_space_distance = dot(sample_velocity, uv_offset) / max(FLT_MIN, dot(sample_velocity, sample_velocity));
|
||||||
|
|
||||||
double mid_point = params.motion_blur_intensity / 2;
|
float mid_point = params.motion_blur_intensity / 2;
|
||||||
|
|
||||||
double absolute_velocity_space_distance = abs(velocity_space_distance - mid_point);
|
float absolute_velocity_space_distance = abs(velocity_space_distance - mid_point);
|
||||||
|
|
||||||
double within_velocity_range = step(absolute_velocity_space_distance, mid_point);
|
float within_velocity_range = step(absolute_velocity_space_distance, mid_point);
|
||||||
|
|
||||||
vec2 perpen_offset = vec2(uv_offset.y, -uv_offset.x);
|
vec2 perpen_offset = vec2(uv_offset.y, -uv_offset.x);
|
||||||
|
|
||||||
double side_offset = abs(dot(perpen_offset, sample_velocity)) / max(FLT_MIN, dot(sample_velocity, sample_velocity));
|
float side_offset = abs(dot(perpen_offset, sample_velocity)) / max(FLT_MIN, dot(sample_velocity, sample_velocity));
|
||||||
|
|
||||||
double within_perpen_error_range = step(side_offset, params.perpen_error_thresh * params.motion_blur_intensity);
|
float within_perpen_error_range = step(side_offset, params.perpen_error_thresh * params.motion_blur_intensity);
|
||||||
|
|
||||||
return vec4(absolute_velocity_space_distance, velocity_space_distance, uv_sample.z, within_velocity_range * within_perpen_error_range);
|
return vec4(absolute_velocity_space_distance, velocity_space_distance, uv_sample.z, within_velocity_range * within_perpen_error_range);
|
||||||
}
|
}
|
||||||
@ -135,8 +133,6 @@ bool is_sample_better(vec4 a, vec4 b)
|
|||||||
vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec2 chosen_velocity, vec4 best_sample_fitness, vec2 render_size)
|
vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec2 chosen_velocity, vec4 best_sample_fitness, vec2 render_size)
|
||||||
{
|
{
|
||||||
//return vec4(chosen_uv, best_sample_fitness.x, 0);// comment this to enable backtracking
|
//return vec4(chosen_uv, best_sample_fitness.x, 0);// comment this to enable backtracking
|
||||||
|
|
||||||
int step_count = 16;
|
|
||||||
|
|
||||||
float smallest_step = 1 / max(render_size.x, render_size.y);
|
float smallest_step = 1 / max(render_size.x, render_size.y);
|
||||||
|
|
||||||
@ -152,9 +148,9 @@ vec4 get_backtracked_sample(vec2 uvn, vec2 chosen_uv, vec2 chosen_velocity, vec4
|
|||||||
|
|
||||||
int steps_to_compare = initial_steps_to_compare;
|
int steps_to_compare = initial_steps_to_compare;
|
||||||
|
|
||||||
for(int i = -step_count; i < step_count + 1; i++)
|
for(int i = -params.backtracking_sample_count; i < params.backtracking_sample_count + 1; i++)
|
||||||
{
|
{
|
||||||
float velocity_multiplier = general_velocity_multiplier * (1 + float(i) / float(step_count));
|
float velocity_multiplier = general_velocity_multiplier * (1 + float(i) / float(params.backtracking_sample_count));
|
||||||
|
|
||||||
if(velocity_multiplier > params.motion_blur_intensity + 0.2 || velocity_multiplier < FLT_MIN)
|
if(velocity_multiplier > params.motion_blur_intensity + 0.2 || velocity_multiplier < FLT_MIN)
|
||||||
{
|
{
|
||||||
|
@ -31,9 +31,15 @@ class_name MotionBlurSphynxJumpFlood
|
|||||||
@export var perpen_error_threshold : float = 0.3
|
@export var perpen_error_threshold : float = 0.3
|
||||||
|
|
||||||
## an initial step size that can increase the dilation radius proportionally, at the
|
## an initial step size that can increase the dilation radius proportionally, at the
|
||||||
## sacrifice of some quality in the final resolution of the dilation
|
## sacrifice of some quality in the final resolution of the dilation.[br][br]
|
||||||
|
## the formula for the maximum radius of the dilation (in pixels) is: pow(2, JFA_pass_count) * sample_step_multiplier
|
||||||
@export var sample_step_multiplier : float = 8
|
@export var sample_step_multiplier : float = 8
|
||||||
|
|
||||||
|
## how many steps along a range of 2 velocities from the
|
||||||
|
## dilation target velocity space do we go along to find a better fitting velocity sample
|
||||||
|
## higher samples meaning higher detail getting captured and blurred
|
||||||
|
@export var backtracking_sample_count : int = 8
|
||||||
|
|
||||||
## how sensitive the backtracking for velocities be
|
## how sensitive the backtracking for velocities be
|
||||||
@export var backtracking_velocity_match_threshold : float = 0.9
|
@export var backtracking_velocity_match_threshold : float = 0.9
|
||||||
|
|
||||||
@ -50,7 +56,8 @@ class_name MotionBlurSphynxJumpFlood
|
|||||||
@export var backtracbing_depth_match_threshold : float = 0.001
|
@export var backtracbing_depth_match_threshold : float = 0.001
|
||||||
|
|
||||||
## the number of passes performed by the jump flood algorithm based dilation,
|
## the number of passes performed by the jump flood algorithm based dilation,
|
||||||
## each pass added doubles the maximum radius of dilation available
|
## each pass added doubles the maximum radius of dilation available.[br][br]
|
||||||
|
## the formula for the maximum radius of the dilation (in pixels) is: pow(2, JFA_pass_count) * sample_step_multiplier
|
||||||
@export var JFA_pass_count : int = 3
|
@export var JFA_pass_count : int = 3
|
||||||
|
|
||||||
## wether this motion blur stays the same intensity below
|
## wether this motion blur stays the same intensity below
|
||||||
@ -180,8 +187,8 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
|||||||
return
|
return
|
||||||
|
|
||||||
ensure_texture(texture, render_scene_buffers)
|
ensure_texture(texture, render_scene_buffers)
|
||||||
ensure_texture(buffer_a, render_scene_buffers, true)#, Vector2(0.25, 0.25))
|
ensure_texture(buffer_a, render_scene_buffers)
|
||||||
ensure_texture(buffer_b, render_scene_buffers, true)#, Vector2(0.25, 0.25))
|
ensure_texture(buffer_b, render_scene_buffers)
|
||||||
ensure_texture(past_color, render_scene_buffers)
|
ensure_texture(past_color, render_scene_buffers)
|
||||||
|
|
||||||
rd.draw_command_begin_label("Motion Blur", Color(1.0, 1.0, 1.0, 1.0))
|
rd.draw_command_begin_label("Motion Blur", Color(1.0, 1.0, 1.0, 1.0))
|
||||||
@ -229,7 +236,7 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
|||||||
var jf_push_constants : PackedInt32Array = [
|
var jf_push_constants : PackedInt32Array = [
|
||||||
i,
|
i,
|
||||||
last_iteration_index,
|
last_iteration_index,
|
||||||
16,
|
backtracking_sample_count,
|
||||||
16
|
16
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -118,10 +118,15 @@ float get_velocity_curl(vec2 uv, vec2 render_size)
|
|||||||
|
|
||||||
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
|
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
|
// This function would return 1 if depth_x is bigger than depth_y by sze amount. meaning, it would return 1 if x is closer to camera
|
||||||
float soft_depth_compare(float depth_X, float depth_Y)
|
float soft_depth_compare(float depth_X, float depth_Y)
|
||||||
{
|
{
|
||||||
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
|
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
|
||||||
}
|
}
|
||||||
|
float soft_depth_compare_custom(float depth_X, float depth_Y, float csze)
|
||||||
|
{
|
||||||
|
return clamp(1 - (depth_X - depth_Y) / csze, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
float cone(vec2 X, vec2 Y, vec2 v)
|
float cone(vec2 X, vec2 Y, vec2 v)
|
||||||
{
|
{
|
||||||
@ -173,9 +178,9 @@ void main()
|
|||||||
|
|
||||||
vec3 naive_velocity = -textureLod(vector_sampler, uvn, 0.0).xyz;
|
vec3 naive_velocity = -textureLod(vector_sampler, uvn, 0.0).xyz;
|
||||||
|
|
||||||
float max_dialtion_radius = pow(2, params.last_iteration_index) * params.sample_step_multiplier / max(render_size.x, render_size.y);
|
float max_dialtion_radius = pow(2, params.last_iteration_index) * params.sample_step_multiplier * 2 / max(render_size.x, render_size.y);
|
||||||
|
|
||||||
if ((dot(velocity, velocity) == 0 || params.motion_blur_intensity == 0) && params.debug == 0) //(uvn.y > 0.5)//
|
if ((dot(velocity, velocity) == 0 || params.motion_blur_intensity == 0) && params.debug == 0)
|
||||||
{
|
{
|
||||||
imageStore(output_image, uvi, base);
|
imageStore(output_image, uvi, base);
|
||||||
imageStore(past_color_image, uvi, base);
|
imageStore(past_color_image, uvi, base);
|
||||||
@ -193,19 +198,21 @@ void main()
|
|||||||
//float d = 1.0 - min(1.0, 2.0 * distance(uvn, vec2(0.5)));
|
//float d = 1.0 - min(1.0, 2.0 * distance(uvn, vec2(0.5)));
|
||||||
//sample_step *= 1.0 - d * params.fade_padding.x;
|
//sample_step *= 1.0 - d * params.fade_padding.x;
|
||||||
|
|
||||||
float total_weight = 1;// max(0.0001, length(naive_velocity));
|
float total_weight = 1;
|
||||||
|
|
||||||
vec2 offset = vec2(sample_step * noise_offset);
|
vec2 offset = vec2(sample_step * noise_offset);//vec2(0);//
|
||||||
|
|
||||||
vec4 col = base * total_weight;
|
vec4 col = base * total_weight;
|
||||||
|
|
||||||
float depth = max(FLT_MIN, textureLod(depth_sampler, velocity_map_sample.xy, 0.0).x);
|
float depth = max(FLT_MIN, textureLod(depth_sampler, velocity_map_sample.xy, 0.0).x);
|
||||||
|
|
||||||
float naive_depth = max(FLT_MIN, textureLod(depth_sampler, uvn, 0.0).x);
|
float naive_depth = max(FLT_MIN, textureLod(depth_sampler, uvn, 0.0).x);
|
||||||
|
|
||||||
|
float naive_background = soft_depth_compare_custom(depth, naive_depth, 0.0001);
|
||||||
|
|
||||||
for (int i = 1; i < iteration_count; i++)
|
for (int i = 1; i < iteration_count; i++)
|
||||||
{
|
{
|
||||||
offset += sample_step.xy;// * interleaved_gradient_noise(uvi, int(params.frame) + i);
|
offset += sample_step.xy;
|
||||||
|
|
||||||
vec2 uvo = uvn + offset;
|
vec2 uvo = uvn + offset;
|
||||||
|
|
||||||
@ -220,17 +227,23 @@ void main()
|
|||||||
|
|
||||||
float current_depth = max(FLT_MIN, textureLod(depth_sampler, velocity_map_sample_step.xy, 0.0).x);
|
float current_depth = max(FLT_MIN, textureLod(depth_sampler, velocity_map_sample_step.xy, 0.0).x);
|
||||||
|
|
||||||
float sample_weight = 1;
|
float current_naive_depth = max(FLT_MIN, textureLod(depth_sampler, uvo, 0.0).x);
|
||||||
|
|
||||||
float motion_difference = get_motion_difference(velocity.xy, current_velocity.xy, 0.1);
|
float motion_difference = get_motion_difference(velocity.xy, current_velocity.xy, 0.1);
|
||||||
|
|
||||||
float foreground = soft_depth_compare(npd / current_depth, npd / depth);
|
float foreground = soft_depth_compare(npd / current_depth, npd / depth);
|
||||||
|
|
||||||
|
float naive_foreground = soft_depth_compare(npd / current_naive_depth - sze, npd / depth);//soft_depth_compare_custom(depth, current_naive_depth, 0.0001);//
|
||||||
|
|
||||||
|
float sample_weight = 1;
|
||||||
|
|
||||||
sample_weight *= 1 - (foreground * motion_difference);
|
sample_weight *= 1 - (foreground * motion_difference);
|
||||||
|
|
||||||
total_weight += sample_weight;
|
total_weight += sample_weight;
|
||||||
|
|
||||||
col += textureLod(color_sampler, uvo, 0.0) * sample_weight;
|
vec2 sample_uv = mix(uvo, uvn, 1 - max(naive_background, naive_foreground));//uvo;//
|
||||||
|
|
||||||
|
col += textureLod(color_sampler, sample_uv, 0.0) * sample_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
col /= total_weight;
|
col /= total_weight;
|
||||||
@ -244,7 +257,7 @@ void main()
|
|||||||
|
|
||||||
vec4 tl_col = vec4(abs(textureLod(vector_sampler, uvn, 0.0).xy) * 10, 0, 1);
|
vec4 tl_col = vec4(abs(textureLod(vector_sampler, uvn, 0.0).xy) * 10, 0, 1);
|
||||||
|
|
||||||
vec4 tr_col = vec4(abs(velocity.xy) * 10, 0, 1);
|
vec4 tr_col = vec4(abs(velocity.xy) * 10, 0, 1);//vec4(naive_background);//
|
||||||
|
|
||||||
vec4 bl_col = vec4(abs(velocity_map_sample.xyw - vec3(uvn, 0)) * vec3(10, 10, 1), 1);
|
vec4 bl_col = vec4(abs(velocity_map_sample.xyw - vec3(uvn, 0)) * vec3(10, 10, 1), 1);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user