mirror of
https://github.com/sphynx-owner/JFA_driven_motion_blur_addon.git
synced 2025-09-19 04:06:08 +08:00
better guertin, new experimental blur
- Improved on guertin's original blurring scheme for better realizm - working experimental retrospective blur with fake transparency
This commit is contained in:
@ -0,0 +1,200 @@
|
||||
#[compute]
|
||||
#version 450
|
||||
|
||||
#define FLT_MAX 3.402823466e+38
|
||||
#define FLT_MIN 1.175494351e-38
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D color_sampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D velocity_sampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D neighbor_max;
|
||||
layout(set = 0, binding = 3) uniform sampler2D tile_variance;
|
||||
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_color;
|
||||
|
||||
|
||||
layout(push_constant, std430) uniform Params
|
||||
{
|
||||
float minimum_user_threshold;
|
||||
float importance_bias;
|
||||
float maximum_jitter_value;
|
||||
float nan8;
|
||||
int tile_size;
|
||||
int sample_count;
|
||||
int frame;
|
||||
int nan4;
|
||||
} params;
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
|
||||
// ----------------------------------------------------------
|
||||
float soft_depth_compare(float depth_X, float depth_Y, float sze)
|
||||
{
|
||||
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
|
||||
}
|
||||
|
||||
float cone(float T, float v)
|
||||
{
|
||||
return clamp(1 - T / v, 0, 1);
|
||||
}
|
||||
|
||||
float cylinder(float T, float v)
|
||||
{
|
||||
return 1.0 - smoothstep(0.95 * v, 1.05 * v, T);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
|
||||
// ----------------------------------------------------------
|
||||
float z_compare(float a, float b, float sze)
|
||||
{
|
||||
return clamp(1. - sze * (a - b), 0, 1);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://www.shadertoy.com/view/ftKfzc
|
||||
// ----------------------------------------------------------
|
||||
float interleaved_gradient_noise(vec2 uv){
|
||||
uv += float(params.frame) * (vec2(47, 17) * 0.695);
|
||||
|
||||
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
|
||||
|
||||
return fract(magic.z * fract(dot(uv, magic.xy)));
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://github.com/bradparks/KinoMotion__unity_motion_blur/tree/master
|
||||
// ----------------------------------------------------------
|
||||
vec2 safenorm(vec2 v)
|
||||
{
|
||||
float l = max(length(v), 1e-6);
|
||||
return v / l * int(l >= 0.5);
|
||||
}
|
||||
|
||||
vec2 jitter_tile(vec2 uvi)
|
||||
{
|
||||
float rx, ry;
|
||||
float angle = interleaved_gradient_noise(uvi + vec2(2, 0)) * M_PI * 2;
|
||||
rx = cos(angle);
|
||||
ry = sin(angle);
|
||||
return vec2(rx, ry) / textureSize(neighbor_max, 0) / 4;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
|
||||
ivec2 tile_render_size = ivec2(textureSize(neighbor_max, 0));
|
||||
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
|
||||
|
||||
vec4 vnzw = textureLod(neighbor_max, x + vec2(params.tile_size / 2) / vec2(render_size) + jitter_tile(uvi), 0.0) * vec4(render_size / 2., 1, 1);
|
||||
|
||||
vec2 vn = vnzw.xy;
|
||||
|
||||
float vn_length = length(vn);
|
||||
|
||||
vec4 base_color = textureLod(color_sampler, x, 0.0);
|
||||
|
||||
if(vn_length < 0.5)
|
||||
{
|
||||
imageStore(output_color, uvi, base_color);
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, base_color);
|
||||
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
|
||||
imageStore(debug_3_image, uvi, vec4(0));
|
||||
imageStore(debug_4_image, uvi, vec4(0));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 wn = safenorm(vn);
|
||||
|
||||
vec4 vxzw = textureLod(velocity_sampler, x, 0.0) * vec4(render_size / 2., 1, 1);
|
||||
|
||||
vec2 vx = vxzw.xy;
|
||||
|
||||
float vx_length = max(0.5, length(vx));
|
||||
|
||||
vec2 wx = safenorm(vx);
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) * 2. - 1.;
|
||||
|
||||
float zx = vxzw.w;
|
||||
|
||||
float weight = 1e-6;
|
||||
|
||||
vec4 sum = base_color * weight;
|
||||
|
||||
float nai_weight = 1e-6;
|
||||
|
||||
vec4 nai_sum = base_color * nai_weight;
|
||||
|
||||
for(int i = 0; i < params.sample_count; i++)
|
||||
{
|
||||
float t = mix(-1.0, 1.0, (i + j * params.maximum_jitter_value + 1.0) / (params.sample_count + 1.0));
|
||||
|
||||
bool use_vn = ((i % 2) == 0);
|
||||
|
||||
vec2 d = use_vn ? vn : vx;
|
||||
|
||||
float dz = use_vn ? vnzw.z : vxzw.z;
|
||||
|
||||
vec2 wd = use_vn ? wn : wx;
|
||||
|
||||
float T = abs(t * vn_length);
|
||||
|
||||
vec2 y = x + t * d / render_size;
|
||||
|
||||
float wa = abs(dot(wx, wd));
|
||||
|
||||
vec4 vyzw = textureLod(velocity_sampler, y, 0.0) * vec4(render_size / 2, 1, 1);
|
||||
|
||||
vec2 vy = vyzw.xy - dz * t;
|
||||
|
||||
float vy_length = max(0.5, length(vy));
|
||||
|
||||
float zy = vyzw.w;
|
||||
|
||||
float f = z_compare(-zy, -zx, 20000);
|
||||
float b = z_compare(-zx, -zy, 20000);
|
||||
|
||||
float wb = abs(dot(vy / vy_length, wd));
|
||||
|
||||
if(use_vn)
|
||||
{
|
||||
float ay = f * step(T, vy_length * wb);
|
||||
|
||||
weight += ay;
|
||||
|
||||
sum += textureLod(color_sampler, y, 0.0) * ay;
|
||||
}
|
||||
|
||||
float nai_ay = b * step(T, vx_length * wa);
|
||||
|
||||
nai_weight += nai_ay;
|
||||
|
||||
nai_sum += textureLod(color_sampler, y, 0.0) * nai_ay;
|
||||
}
|
||||
|
||||
sum /= weight;
|
||||
|
||||
weight /= params.sample_count / 2;
|
||||
|
||||
nai_sum /= nai_weight;
|
||||
|
||||
sum = mix(nai_sum, sum, weight);
|
||||
|
||||
imageStore(output_color, uvi, sum);
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, sum);
|
||||
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
|
||||
imageStore(debug_3_image, uvi, vnzw);
|
||||
imageStore(debug_4_image, uvi, vxzw);
|
||||
#endif
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://br71y0l0rxt8h"
|
||||
path="res://.godot/imported/guertin_experimental_blur.glsl-196a1037ea9a4eb1095033202fe161a7.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_experimental_blur.glsl"
|
||||
dest_files=["res://.godot/imported/guertin_experimental_blur.glsl-196a1037ea9a4eb1095033202fe161a7.res"]
|
||||
|
||||
[params]
|
||||
|
@ -95,7 +95,7 @@ void main()
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) * 2. - 1.;
|
||||
|
||||
vec4 vnzw = textureLod(neighbor_max, x + jitter_tile(uvi), 0.0) * vec4(render_size / 2., 1, 1);
|
||||
vec4 vnzw = textureLod(neighbor_max, x + vec2(params.tile_size / 2) / vec2(render_size) + jitter_tile(uvi), 0.0) * vec4(render_size / 2., 1, 1);
|
||||
|
||||
vec2 vn = vnzw.xy;
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
[gd_resource type="Resource" script_class="ShaderStageResource" load_steps=3 format=3 uid="uid://ca45noqewsyvp"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/SphynxMotionBlurToolkit/BaseClasses/shader_pass_resource.gd" id="1_kvtxq"]
|
||||
[ext_resource type="RDShaderFile" uid="uid://br71y0l0rxt8h" path="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_experimental_blur.glsl" id="2_ykr12"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_kvtxq")
|
||||
shader_file = ExtResource("2_ykr12")
|
@ -1,5 +1,5 @@
|
||||
extends "res://addons/SphynxMotionBlurToolkit/Guertin/base_guertin_motion_blur.gd"
|
||||
class_name GuertinMotionBlur
|
||||
class_name OldGuertinMotionBlur
|
||||
|
||||
@export_group("Shader Stages")
|
||||
@export var blur_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_blur_stage.tres"):
|
||||
|
@ -0,0 +1,228 @@
|
||||
extends "res://addons/SphynxMotionBlurToolkit/Guertin/base_guertin_motion_blur.gd"
|
||||
class_name GuertinMotionBlur
|
||||
|
||||
@export_group("Shader Stages")
|
||||
@export var blur_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_experimental_blur_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(blur_stage)
|
||||
blur_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
@export var overlay_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_overlay_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(overlay_stage)
|
||||
overlay_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
@export var tile_max_x_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_tile_max_x_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(tile_max_x_stage)
|
||||
tile_max_x_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
@export var tile_max_y_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_tile_max_y_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(tile_max_y_stage)
|
||||
tile_max_y_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
@export var neighbor_max_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_neighbor_max_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(neighbor_max_stage)
|
||||
neighbor_max_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
@export var tile_variance_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Guertin/guertin_tile_variance_stage.tres"):
|
||||
set(value):
|
||||
unsubscribe_shader_stage(tile_variance_stage)
|
||||
tile_variance_stage = value
|
||||
subscirbe_shader_stage(value)
|
||||
|
||||
var output_color: StringName = "output_color"
|
||||
|
||||
var tile_max_x : StringName = "tile_max_x"
|
||||
|
||||
var tile_max : StringName = "tile_max"
|
||||
|
||||
var neighbor_max : StringName = "neighbor_max"
|
||||
|
||||
var tile_variance : StringName = "tile_variance"
|
||||
|
||||
var custom_velocity : StringName = "custom_velocity"
|
||||
|
||||
var freeze : bool = false
|
||||
|
||||
func _get_max_dilation_range() -> float:
|
||||
return tile_size;
|
||||
|
||||
func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSceneBuffersRD, render_scene_data : RenderSceneDataRD):
|
||||
ensure_texture(tile_max_x, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16B16A16_SFLOAT, Vector2(1. / tile_size, 1.))
|
||||
ensure_texture(tile_max, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16B16A16_SFLOAT, Vector2(1. / tile_size, 1. / tile_size))
|
||||
ensure_texture(neighbor_max, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16B16A16_SFLOAT, Vector2(1. / tile_size, 1. / tile_size))
|
||||
ensure_texture(tile_variance, render_scene_buffers, RenderingDevice.DATA_FORMAT_R16G16B16A16_SFLOAT, Vector2(1. / tile_size, 1. / tile_size))
|
||||
ensure_texture(custom_velocity, render_scene_buffers)
|
||||
ensure_texture(output_color, render_scene_buffers)
|
||||
|
||||
rd.draw_command_begin_label("Motion Blur", Color(1.0, 1.0, 1.0, 1.0))
|
||||
|
||||
var tile_max_x_push_constants: PackedFloat32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var int_tile_max_x_push_constants : PackedInt32Array = [
|
||||
tile_size,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var tile_max_x_push_constants_byte_array = tile_max_x_push_constants.to_byte_array()
|
||||
tile_max_x_push_constants_byte_array.append_array(int_tile_max_x_push_constants.to_byte_array())
|
||||
|
||||
var tile_max_y_push_constants: PackedFloat32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var int_tile_max_y_push_constants : PackedInt32Array = [
|
||||
tile_size,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var tile_max_y_push_constants_byte_array = tile_max_y_push_constants.to_byte_array()
|
||||
tile_max_y_push_constants_byte_array.append_array(int_tile_max_y_push_constants.to_byte_array())
|
||||
|
||||
var neighbor_max_push_constants: PackedFloat32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var int_neighbor_max_push_constants : PackedInt32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var neighbor_max_push_constants_byte_array = neighbor_max_push_constants.to_byte_array()
|
||||
neighbor_max_push_constants_byte_array.append_array(int_neighbor_max_push_constants.to_byte_array())
|
||||
|
||||
var tile_variance_push_constants: PackedFloat32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var int_tile_variance_push_constants : PackedInt32Array = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
var tile_variance_push_constants_byte_array = tile_variance_push_constants.to_byte_array()
|
||||
tile_variance_push_constants_byte_array.append_array(int_tile_variance_push_constants.to_byte_array())
|
||||
|
||||
var blur_push_constants: PackedFloat32Array = [
|
||||
minimum_user_threshold,
|
||||
importance_bias,
|
||||
maximum_jitter_value,
|
||||
0,
|
||||
]
|
||||
var int_blur_push_constants : PackedInt32Array = [
|
||||
tile_size,
|
||||
samples,
|
||||
Engine.get_frames_drawn() % 8,
|
||||
0
|
||||
]
|
||||
var blur_push_constants_byte_array = blur_push_constants.to_byte_array()
|
||||
blur_push_constants_byte_array.append_array(int_blur_push_constants.to_byte_array())
|
||||
|
||||
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 output_color_image := render_scene_buffers.get_texture_slice(context, output_color, view, 0, 1, 1)
|
||||
var tile_max_x_image := render_scene_buffers.get_texture_slice(context, tile_max_x, view, 0, 1, 1)
|
||||
var tile_max_image := render_scene_buffers.get_texture_slice(context, tile_max, view, 0, 1, 1)
|
||||
var neighbor_max_image := render_scene_buffers.get_texture_slice(context, neighbor_max, view, 0, 1, 1)
|
||||
var tile_variance_image := render_scene_buffers.get_texture_slice(context, tile_variance, view, 0, 1, 1)
|
||||
var custom_velocity_image := render_scene_buffers.get_texture_slice(context, custom_velocity, view, 0, 1, 1)
|
||||
|
||||
var x_groups := floori((render_size.x / tile_size - 1) / 16 + 1)
|
||||
var y_groups := floori((render_size.y - 1) / 16 + 1)
|
||||
|
||||
dispatch_stage(tile_max_x_stage,
|
||||
[
|
||||
get_sampler_uniform(custom_velocity_image, 0, false),
|
||||
get_sampler_uniform(depth_image, 1, false),
|
||||
get_image_uniform(tile_max_x_image, 2)
|
||||
],
|
||||
tile_max_x_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"TileMaxX",
|
||||
view)
|
||||
|
||||
x_groups = floori((render_size.x / tile_size - 1) / 16 + 1)
|
||||
y_groups = floori((render_size.y / tile_size - 1) / 16 + 1)
|
||||
|
||||
dispatch_stage(tile_max_y_stage,
|
||||
[
|
||||
get_sampler_uniform(tile_max_x_image, 0, false),
|
||||
get_image_uniform(tile_max_image, 1)
|
||||
],
|
||||
tile_max_y_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"TileMaxY",
|
||||
view)
|
||||
|
||||
dispatch_stage(neighbor_max_stage,
|
||||
[
|
||||
get_sampler_uniform(tile_max_image, 0, false),
|
||||
get_image_uniform(neighbor_max_image, 1)
|
||||
],
|
||||
neighbor_max_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"NeighborMax",
|
||||
view)
|
||||
|
||||
dispatch_stage(tile_variance_stage,
|
||||
[
|
||||
get_sampler_uniform(tile_max_image, 0, false),
|
||||
get_image_uniform(tile_variance_image, 1)
|
||||
],
|
||||
tile_variance_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"TileVariance",
|
||||
view)
|
||||
|
||||
x_groups = floori((render_size.x - 1) / 16 + 1)
|
||||
y_groups = floori((render_size.y - 1) / 16 + 1)
|
||||
|
||||
dispatch_stage(blur_stage,
|
||||
[
|
||||
get_sampler_uniform(color_image, 0, false),
|
||||
get_sampler_uniform(custom_velocity_image, 1, false),
|
||||
get_sampler_uniform(neighbor_max_image, 2, false),
|
||||
get_sampler_uniform(tile_variance_image, 3, true),
|
||||
get_image_uniform(output_color_image, 4),
|
||||
],
|
||||
blur_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"Blur",
|
||||
view)
|
||||
|
||||
dispatch_stage(overlay_stage,
|
||||
[
|
||||
get_sampler_uniform(output_color_image, 0, false),
|
||||
get_image_uniform(color_image, 1)
|
||||
],
|
||||
[],
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
"Overlay result",
|
||||
view)
|
||||
|
||||
rd.draw_command_end_label()
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://bcivntgn7ipwo"
|
||||
path="res://.godot/imported/jf_neighbor_depth_max.glsl-d20bc4da7a00b27ca7e046fc2a191610.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/Archive/jf_neighbor_depth_max.glsl"
|
||||
dest_files=["res://.godot/imported/jf_neighbor_depth_max.glsl-d20bc4da7a00b27ca7e046fc2a191610.res"]
|
||||
|
||||
[params]
|
||||
|
@ -0,0 +1,201 @@
|
||||
#[compute]
|
||||
#version 450
|
||||
|
||||
#define FLT_MAX 3.402823466e+38
|
||||
#define FLT_MIN 1.175494351e-38
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D tile_max_sampler;
|
||||
layout(rgba16f, set = 0, binding = 1) uniform writeonly image2D buffer_a;
|
||||
layout(rgba16f, set = 0, binding = 2) uniform writeonly image2D buffer_b;
|
||||
layout(set = 0, binding = 3) uniform sampler2D buffer_a_sampler;
|
||||
layout(set = 0, binding = 4) uniform sampler2D buffer_b_sampler;
|
||||
|
||||
layout(set = 0, binding = 5, std430) restrict buffer MyDataBuffer {
|
||||
int iteration_index;
|
||||
}
|
||||
iteration_data;
|
||||
|
||||
layout(push_constant, std430) uniform Params
|
||||
{
|
||||
int nan0;//iteration_index;
|
||||
int last_iteration_index;
|
||||
int nan1;
|
||||
int nan2;
|
||||
float perpen_error_thresh;
|
||||
float sample_step_multiplier;
|
||||
float motion_blur_intensity;
|
||||
float nan_fl_5;
|
||||
float nan_fl_4;
|
||||
float nan_fl_3;
|
||||
float nan_fl_6;
|
||||
float step_exponent_modifier;
|
||||
float nan_fl_0;//step_size;
|
||||
float max_dilation_radius;
|
||||
float nan_fl_1;
|
||||
float nan_fl_2;
|
||||
} params;
|
||||
|
||||
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, 0),
|
||||
vec2(1, 0),
|
||||
vec2(0, -1),
|
||||
vec2(0, 1),
|
||||
vec2(-1, 1),
|
||||
vec2(1, -1),
|
||||
vec2(1, 1),
|
||||
vec2(-1, -1),
|
||||
};
|
||||
|
||||
vec2 get_value(bool a, vec2 uv)
|
||||
{
|
||||
if(a)
|
||||
{
|
||||
return textureLod(buffer_a_sampler, uv, 0.0).xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return textureLod(buffer_b_sampler, uv, 0.0).xy;
|
||||
}
|
||||
}
|
||||
|
||||
void set_value(bool a, ivec2 uvi, vec4 value)
|
||||
{
|
||||
if(a)
|
||||
{
|
||||
imageStore(buffer_a, uvi, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
imageStore(buffer_b, uvi, value);
|
||||
}
|
||||
}
|
||||
|
||||
void sample_fitness(vec2 uv_offset, vec4 uv_sample, vec2 render_size, inout vec4 current_sample_fitness)
|
||||
{
|
||||
vec2 sample_velocity = -uv_sample.xy;
|
||||
|
||||
// if (dot(sample_velocity, sample_velocity) <= FLT_MIN || uv_sample.w == 0)
|
||||
// {
|
||||
// current_sample_fitness = vec4(10, 10, 0, 0);
|
||||
// return;
|
||||
// }
|
||||
|
||||
float velocity_space_distance = dot(sample_velocity, uv_offset) / dot(sample_velocity, sample_velocity);
|
||||
|
||||
float mid_point = params.motion_blur_intensity / 2 + 1e-5;
|
||||
|
||||
float absolute_velocity_space_distance = abs(velocity_space_distance - mid_point);
|
||||
|
||||
float within_velocity_range = step(absolute_velocity_space_distance, mid_point);
|
||||
|
||||
float side_offset = abs(dot(vec2(uv_offset.y, -uv_offset.x), sample_velocity)) / dot(sample_velocity, sample_velocity);
|
||||
|
||||
float within_perpen_error_range = step(side_offset, params.perpen_error_thresh * params.motion_blur_intensity);
|
||||
|
||||
current_sample_fitness = vec4(/*max(absolute_velocity_space_distance, side_offset)*/absolute_velocity_space_distance, velocity_space_distance, uv_sample.w + uv_sample.z * velocity_space_distance, within_velocity_range * within_perpen_error_range);
|
||||
}
|
||||
|
||||
//float is_sample_better(vec4 a, vec4 b)
|
||||
//{
|
||||
// return 1. - step(b.x * a.w, a.x * b.w);//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));
|
||||
//}
|
||||
|
||||
//vec4 backtrack_sample(vec2 chosen_uv, vec4 best_sample_fitness)
|
||||
//{
|
||||
// vec4 velocity = textureLod(tile_max_sampler, chosen_uv, 0.0);
|
||||
//
|
||||
// vec2 uv_candidate = chosen_uv + velocity.xy;
|
||||
//
|
||||
// vec4 velocity_candidate = textureLod(tile_max_sampler, uv_candidate, 0.0);
|
||||
//
|
||||
// if((dot(velocity, velocity_candidate) / dot(velocity, velocity)) > 0.5 && velocity_candidate.w > 0)
|
||||
// {
|
||||
// return vec4(uv_candidate, 0, 0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return vec4(chosen_uv, 0, 0);
|
||||
// }
|
||||
//}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(tile_max_sampler, 0));
|
||||
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size;
|
||||
|
||||
vec2 step_size = vec2(round(pow(2 + params.step_exponent_modifier, params.last_iteration_index - iteration_data.iteration_index)));
|
||||
|
||||
vec2 uv_step = vec2(round(step_size)) / render_size;
|
||||
|
||||
vec4 best_sample_fitness = vec4(10, 10, 0, 0);
|
||||
|
||||
vec2 chosen_uv = uvn;
|
||||
|
||||
bool set_a = !bool(step(0.5, float(iteration_data.iteration_index % 2)));
|
||||
|
||||
iteration_data.iteration_index += 1;
|
||||
|
||||
vec2 step_offset;
|
||||
|
||||
vec2 check_uv;
|
||||
|
||||
vec4 uv_sample;
|
||||
|
||||
vec4 current_sample_fitness;
|
||||
|
||||
for(int i = 0; i < kernel_size; i++)
|
||||
{
|
||||
step_offset = check_step_kernel[i] * uv_step;
|
||||
check_uv = uvn + step_offset;
|
||||
|
||||
if(any(notEqual(check_uv, clamp(check_uv, vec2(0.0), vec2(1.0)))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if(iteration_data.iteration_index > 0)
|
||||
// {
|
||||
check_uv = get_value(!set_a, check_uv).xy;
|
||||
|
||||
step_offset = check_uv - uvn;
|
||||
// }
|
||||
|
||||
uv_sample = textureLod(tile_max_sampler, check_uv, 0.0);
|
||||
|
||||
sample_fitness(step_offset, uv_sample, render_size, current_sample_fitness);
|
||||
|
||||
float sample_better = 1. - step(current_sample_fitness.z * current_sample_fitness.w, best_sample_fitness.z * best_sample_fitness.w);
|
||||
best_sample_fitness = mix(best_sample_fitness, current_sample_fitness, sample_better);
|
||||
chosen_uv = mix(chosen_uv, check_uv, sample_better);
|
||||
}
|
||||
|
||||
// if(params.iteration_index < params.last_iteration_index)
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float depth = textureLod(tile_max_sampler, uvn, 0.0).w;
|
||||
//
|
||||
// if(params.iteration_index == params.last_iteration_index && (best_sample_fitness.w < 0.5 || depth > best_sample_fitness.z))
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(uvn, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
|
||||
set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
|
||||
// vec4 backtracked_sample = backtrack_sample(chosen_uv, best_sample_fitness);
|
||||
//
|
||||
// set_value(set_a, uvi, backtracked_sample);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://brlr85tfh5tv2"
|
||||
path="res://.godot/imported/jf_simple_archive_17_8_24.glsl-e91ee2bf9d7e74579e89e443fc0e02d3.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/Archive/jf_simple_archive_17_8_24.glsl"
|
||||
dest_files=["res://.godot/imported/jf_simple_archive_17_8_24.glsl-e91ee2bf9d7e74579e89e443fc0e02d3.res"]
|
||||
|
||||
[params]
|
||||
|
@ -0,0 +1,192 @@
|
||||
#[compute]
|
||||
#version 450
|
||||
|
||||
#define FLT_MAX 3.402823466e+38
|
||||
#define FLT_MIN 1.175494351e-38
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D tile_max_sampler;
|
||||
layout(rgba16f, set = 0, binding = 1) uniform writeonly image2D buffer_a;
|
||||
layout(rgba16f, set = 0, binding = 2) uniform writeonly image2D buffer_b;
|
||||
layout(set = 0, binding = 3) uniform sampler2D buffer_a_sampler;
|
||||
layout(set = 0, binding = 4) uniform sampler2D buffer_b_sampler;
|
||||
|
||||
layout(push_constant, std430) uniform Params
|
||||
{
|
||||
int iteration_index;
|
||||
int last_iteration_index;
|
||||
int nan1;
|
||||
int nan2;
|
||||
float perpen_error_thresh;
|
||||
float sample_step_multiplier;
|
||||
float motion_blur_intensity;
|
||||
float nan_fl_5;
|
||||
float nan_fl_4;
|
||||
float nan_fl_3;
|
||||
float nan_fl_6;
|
||||
float step_exponent_modifier;
|
||||
float step_size;
|
||||
float max_dilation_radius;
|
||||
float nan_fl_1;
|
||||
float nan_fl_2;
|
||||
} params;
|
||||
|
||||
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, 0),
|
||||
vec2(1, 0),
|
||||
vec2(0, -1),
|
||||
vec2(0, 1),
|
||||
vec2(-1, 1),
|
||||
vec2(1, -1),
|
||||
vec2(1, 1),
|
||||
vec2(-1, -1),
|
||||
};
|
||||
|
||||
vec2 get_value(bool a, vec2 uv)
|
||||
{
|
||||
if(a)
|
||||
{
|
||||
return textureLod(buffer_a_sampler, uv, 0.0).xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return textureLod(buffer_b_sampler, uv, 0.0).xy;
|
||||
}
|
||||
}
|
||||
|
||||
void set_value(bool a, ivec2 uvi, vec4 value)
|
||||
{
|
||||
if(a)
|
||||
{
|
||||
imageStore(buffer_a, uvi, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
imageStore(buffer_b, uvi, value);
|
||||
}
|
||||
}
|
||||
|
||||
void sample_fitness(vec2 uv_offset, vec4 uv_sample, vec2 render_size, inout vec4 current_sample_fitness)
|
||||
{
|
||||
vec2 sample_velocity = -uv_sample.xy;
|
||||
|
||||
// if (dot(sample_velocity, sample_velocity) <= FLT_MIN || uv_sample.w == 0)
|
||||
// {
|
||||
// current_sample_fitness = vec4(10, 10, 0, 0);
|
||||
// return;
|
||||
// }
|
||||
|
||||
float velocity_space_distance = dot(sample_velocity, uv_offset) / dot(sample_velocity, sample_velocity);
|
||||
|
||||
float mid_point = params.motion_blur_intensity / 2 + 1e-5;
|
||||
|
||||
float absolute_velocity_space_distance = abs(velocity_space_distance - mid_point);
|
||||
|
||||
float within_velocity_range = step(absolute_velocity_space_distance, mid_point);
|
||||
|
||||
float side_offset = abs(dot(vec2(uv_offset.y, -uv_offset.x), sample_velocity)) / dot(sample_velocity, sample_velocity);
|
||||
|
||||
float within_perpen_error_range = step(side_offset, params.perpen_error_thresh * params.motion_blur_intensity);
|
||||
|
||||
current_sample_fitness = vec4(/*max(absolute_velocity_space_distance, side_offset)*/absolute_velocity_space_distance, velocity_space_distance, uv_sample.w + uv_sample.z * velocity_space_distance, within_velocity_range * within_perpen_error_range);
|
||||
}
|
||||
|
||||
//float is_sample_better(vec4 a, vec4 b)
|
||||
//{
|
||||
// return 1. - step(b.x * a.w, a.x * b.w);//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));
|
||||
//}
|
||||
|
||||
//vec4 backtrack_sample(vec2 chosen_uv, vec4 best_sample_fitness)
|
||||
//{
|
||||
// vec4 velocity = textureLod(tile_max_sampler, chosen_uv, 0.0);
|
||||
//
|
||||
// vec2 uv_candidate = chosen_uv + velocity.xy;
|
||||
//
|
||||
// vec4 velocity_candidate = textureLod(tile_max_sampler, uv_candidate, 0.0);
|
||||
//
|
||||
// if((dot(velocity, velocity_candidate) / dot(velocity, velocity)) > 0.5 && velocity_candidate.w > 0)
|
||||
// {
|
||||
// return vec4(uv_candidate, 0, 0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return vec4(chosen_uv, 0, 0);
|
||||
// }
|
||||
//}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(tile_max_sampler, 0));
|
||||
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size;
|
||||
|
||||
vec2 uv_step = vec2(round(params.step_size)) / render_size;
|
||||
|
||||
vec4 best_sample_fitness = vec4(10, 10, 0, 0);
|
||||
|
||||
vec2 chosen_uv = uvn;
|
||||
|
||||
bool set_a = !bool(step(0.5, float(params.iteration_index % 2)));
|
||||
|
||||
vec2 step_offset;
|
||||
|
||||
vec2 check_uv;
|
||||
|
||||
vec4 uv_sample;
|
||||
|
||||
vec4 current_sample_fitness;
|
||||
|
||||
for(int i = 0; i < kernel_size; i++)
|
||||
{
|
||||
step_offset = check_step_kernel[i] * uv_step;
|
||||
check_uv = uvn + step_offset;
|
||||
|
||||
if(any(notEqual(check_uv, clamp(check_uv, vec2(0.0), vec2(1.0)))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(params.iteration_index > 0)
|
||||
{
|
||||
check_uv = get_value(!set_a, check_uv).xy;
|
||||
|
||||
step_offset = check_uv - uvn;
|
||||
}
|
||||
|
||||
uv_sample = textureLod(tile_max_sampler, check_uv, 0.0);
|
||||
|
||||
sample_fitness(step_offset, uv_sample, render_size, current_sample_fitness);
|
||||
|
||||
float sample_better = 1. - step(current_sample_fitness.z * current_sample_fitness.w, best_sample_fitness.z * best_sample_fitness.w);
|
||||
best_sample_fitness = mix(best_sample_fitness, current_sample_fitness, sample_better);
|
||||
chosen_uv = mix(chosen_uv, check_uv, sample_better);
|
||||
}
|
||||
|
||||
// if(params.iteration_index < params.last_iteration_index)
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float depth = textureLod(tile_max_sampler, uvn, 0.0).w;
|
||||
//
|
||||
// if(params.iteration_index == params.last_iteration_index && (best_sample_fitness.w < 0.5 || depth > best_sample_fitness.z))
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(uvn, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
|
||||
set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
|
||||
// vec4 backtracked_sample = backtrack_sample(chosen_uv, best_sample_fitness);
|
||||
//
|
||||
// set_value(set_a, uvi, backtracked_sample);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://c7q41dxu78i8o"
|
||||
path="res://.godot/imported/jfp_simple_push_based_archive.glsl-a99001e07de7540b5869f83d2e3643a4.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/Archive/jfp_simple_push_based_archive.glsl"
|
||||
dest_files=["res://.godot/imported/jfp_simple_push_based_archive.glsl-a99001e07de7540b5869f83d2e3643a4.res"]
|
||||
|
||||
[params]
|
||||
|
@ -3,12 +3,12 @@
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://dc6r26wwdjceq"
|
||||
path="res://.godot/imported/jump_flood_mcguire_blur.glsl-01a8aea5f4a3ebff22641db3a49ace6c.res"
|
||||
path="res://.godot/imported/jump_flood_mcguire_blur.glsl-db182d03471f2a14ff66b8fcdafe8dc6.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/jump_flood_mcguire_blur.glsl"
|
||||
dest_files=["res://.godot/imported/jump_flood_mcguire_blur.glsl-01a8aea5f4a3ebff22641db3a49ace6c.res"]
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/Archive/jump_flood_mcguire_blur.glsl"
|
||||
dest_files=["res://.godot/imported/jump_flood_mcguire_blur.glsl-db182d03471f2a14ff66b8fcdafe8dc6.res"]
|
||||
|
||||
[params]
|
||||
|
@ -0,0 +1,452 @@
|
||||
#[compute]
|
||||
#version 450
|
||||
|
||||
#define FLT_MAX 3.402823466e+38
|
||||
#define FLT_MIN 1.175494351e-38
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
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 velocity_sampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D velocity_map;
|
||||
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_image;
|
||||
layout(set = 0, binding = 5) uniform sampler2D tile_max;
|
||||
layout(set = 0, binding = 6) uniform sampler2D past_color_sampler;
|
||||
layout(set = 0, binding = 7) uniform sampler2D past_velocity_sampler;
|
||||
|
||||
layout(push_constant, std430) uniform Params
|
||||
{
|
||||
float motion_blur_samples;
|
||||
float motion_blur_intensity;
|
||||
float motion_blur_center_fade;
|
||||
float frame;
|
||||
float last_iteration_index;
|
||||
float sample_step_multiplier;
|
||||
float step_exponent_modifier;
|
||||
float max_dilation_radius;
|
||||
int nan0;
|
||||
int nan1;
|
||||
int nan2;
|
||||
int nan3;
|
||||
} params;
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
|
||||
// ----------------------------------------------------------
|
||||
float soft_depth_compare(float depth_X, float depth_Y, float sze)
|
||||
{
|
||||
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
|
||||
}
|
||||
|
||||
float cone(float T, float v)
|
||||
{
|
||||
return clamp(1 - T / v, 0, 1);
|
||||
}
|
||||
|
||||
float cylinder(float T, float v)
|
||||
{
|
||||
return 1.0 - smoothstep(0.95 * v, 1.05 * v, T);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
|
||||
// ----------------------------------------------------------
|
||||
float z_compare(float a, float b, float sze)
|
||||
{
|
||||
return clamp(1. - sze * (a - b), 0, 1);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://www.shadertoy.com/view/ftKfzc
|
||||
// ----------------------------------------------------------
|
||||
float interleaved_gradient_noise(vec2 uv){
|
||||
uv += float(params.frame) * (vec2(47, 17) * 0.695);
|
||||
|
||||
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
|
||||
|
||||
return fract(magic.z * fract(dot(uv, magic.xy)));
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://github.com/bradparks/KinoMotion__unity_motion_blur/tree/master
|
||||
// ----------------------------------------------------------
|
||||
vec2 safenorm(vec2 v)
|
||||
{
|
||||
float l = max(length(v), 1e-6);
|
||||
return v / l * int(l >= 0.5);
|
||||
}
|
||||
|
||||
vec2 jitter_tile(vec2 uvi)
|
||||
{
|
||||
float rx, ry;
|
||||
float angle = interleaved_gradient_noise(uvi + vec2(2, 0)) * M_PI * 2;
|
||||
rx = cos(angle);
|
||||
ry = sin(angle);
|
||||
return vec2(rx, ry) / textureSize(tile_max, 0) / 4;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
|
||||
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
|
||||
|
||||
vec2 velocity_map_sample = textureLod(velocity_map, x + jitter_tile(uvi), 0.0).xy;
|
||||
|
||||
vec3 vnz = textureLod(tile_max, velocity_map_sample, 0.0).xyz * vec3(render_size, 1);
|
||||
|
||||
float vn_length = max(0.5, length(vnz.xy));
|
||||
|
||||
float multiplier = clamp(vn_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vn_length);
|
||||
|
||||
vnz.xyz *= multiplier;
|
||||
|
||||
vn_length *= multiplier;
|
||||
|
||||
vec2 vn = vnz.xy;
|
||||
|
||||
vec4 col_x = textureLod(color_sampler, x, 0.0);
|
||||
|
||||
vec2 wn = safenorm(vn);
|
||||
|
||||
vec4 vxz = textureLod(velocity_sampler, x, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float vx_length = max(0.5, length(vxz.xy));
|
||||
|
||||
multiplier = clamp(vx_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vx_length);
|
||||
|
||||
vxz.xyz *= multiplier;
|
||||
|
||||
vx_length *= multiplier;
|
||||
|
||||
vec2 vx = vxz.xy;
|
||||
|
||||
if(vn_length <= 0.5)
|
||||
{
|
||||
imageStore(output_image, uvi, col_x);
|
||||
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, col_x);
|
||||
imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.25);
|
||||
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
vnz = mix(vnz, vxz.xyz, velocity_match);
|
||||
|
||||
float zx = vxz.w;
|
||||
|
||||
vec2 wx = safenorm(vx);
|
||||
|
||||
float weight = 0;
|
||||
|
||||
vec4 sum = col_x * weight;
|
||||
|
||||
float total_back_weight = 1e-10;
|
||||
|
||||
vec4 back_sum = col_x * total_back_weight;
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) - 0.5;
|
||||
|
||||
vec4 past_vxz = textureLod(past_velocity_sampler, x, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
vec2 past_vx = past_vxz.xy;
|
||||
|
||||
vec4 past_col_x = textureLod(past_color_sampler, x, 0.0);
|
||||
|
||||
for(int i = 0; i < params.motion_blur_samples; i++)
|
||||
{
|
||||
float nai_t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
float nai_T = abs(nai_t * vx_length);
|
||||
|
||||
vec2 nai_y = x + (vx / render_size) * nai_t;
|
||||
|
||||
if(nai_y.x < 0 || nai_y.x > 1 || nai_y.y < 0 || nai_y.y > 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vec4 nai_vy = textureLod(velocity_sampler, nai_y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float nai_zy = nai_vy.w - vxz.z * nai_t;
|
||||
|
||||
float nai_b = z_compare(-zx, -nai_zy, 20000);
|
||||
|
||||
float nai_f = z_compare(-nai_zy, -zx, 20000);
|
||||
|
||||
float nai_ay = nai_b + (1 - nai_f);
|
||||
|
||||
float past_t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
vec2 past_y = x + (past_vx / render_size) * past_t;
|
||||
|
||||
float alpha = z_compare(-past_vxz.w, -vxz.w, 20000); // may need to be a step
|
||||
|
||||
vec4 past_vy = mix(textureLod(past_velocity_sampler, past_y, 0.0) * vec4(render_size, 1, 1), textureLod(velocity_sampler, past_y, 0.0) * vec4(render_size, 1, 1), alpha);
|
||||
|
||||
float past_zy = past_vy.w - past_vxz.z * past_t;
|
||||
|
||||
float past_b = z_compare(-past_vxz.w, -past_zy, 20000);
|
||||
|
||||
vec4 nai_col_y = mix(textureLod(color_sampler, nai_y, 0.0), mix(textureLod(past_color_sampler, x, 0.0), mix(textureLod(past_color_sampler, past_y, 0.0), textureLod(color_sampler, past_y, 0.0), alpha), past_b), (1 - nai_f));
|
||||
|
||||
total_back_weight += nai_ay;
|
||||
|
||||
back_sum += nai_col_y * nai_ay;
|
||||
|
||||
float t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
float T = abs(t * vn_length);
|
||||
|
||||
vec2 y = x + (vn / render_size) * t;
|
||||
|
||||
if(y.x < 0 || y.x > 1 || y.y < 0 || y.y > 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vec4 vy = textureLod(velocity_sampler, y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float vy_length = max(0.5, length(vy.xy));
|
||||
|
||||
float zy = vy.w - vnz.z * t;
|
||||
|
||||
float f = z_compare(-zy, -zx, 20000);
|
||||
|
||||
float wa = abs(max(0, dot(vy.xy / vy_length, wn)));
|
||||
|
||||
float ay_trail = f * step(T, vy_length * wa);
|
||||
|
||||
vec4 col_y = textureLod(color_sampler, y, 0.0);
|
||||
|
||||
weight += ay_trail;
|
||||
|
||||
sum += col_y * ay_trail;
|
||||
}
|
||||
|
||||
back_sum *= (params.motion_blur_samples - weight) / total_back_weight;
|
||||
|
||||
sum /= params.motion_blur_samples;
|
||||
|
||||
back_sum /= params.motion_blur_samples;
|
||||
|
||||
imageStore(output_image, uvi, sum + back_sum);
|
||||
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, sum + back_sum);
|
||||
imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
imageStore(debug_6_image, uvi, past_col_x);
|
||||
imageStore(debug_7_image, uvi, past_col_x);
|
||||
imageStore(debug_8_image, uvi, back_sum);
|
||||
#endif
|
||||
}
|
||||
|
||||
//void main()
|
||||
//{
|
||||
// ivec2 render_size = ivec2(textureSize(color_sampler, 0));
|
||||
// ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
// if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
|
||||
//
|
||||
// vec2 velocity_map_sample = textureLod(velocity_map, x + jitter_tile(uvi), 0.0).xy;
|
||||
//
|
||||
// vec3 vnz = textureLod(tile_max, velocity_map_sample, 0.0).xyz * vec3(render_size, 1);// * 2;
|
||||
//
|
||||
// vec2 vn = vnz.xy;
|
||||
//
|
||||
// float vn_length = max(0.5, length(vn));
|
||||
//
|
||||
// vec2 wn = safenorm(vn);
|
||||
//
|
||||
// vec4 col_x = textureLod(color_sampler, x, 0.0);
|
||||
//
|
||||
// vec3 vxz = textureLod(vector_sampler, x, 0.0).xyz * vec3(render_size, 1);// * 2;
|
||||
//
|
||||
// vec2 vx = vxz.xy;
|
||||
//
|
||||
// vec3 past_vxz = textureLod(past_velocity_sampler, x, 0.0).xyz * vec3(render_size, 1);
|
||||
//
|
||||
// vec2 past_vx = past_vxz.xy;
|
||||
//
|
||||
// vec4 past_col_x = textureLod(past_color_sampler, x, 0.0);
|
||||
//
|
||||
// float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.5);
|
||||
//
|
||||
// vn = mix(vn, vx, velocity_match);
|
||||
//
|
||||
// vnz = mix(vnz, vxz, velocity_match);
|
||||
//
|
||||
// if(vn_length <= 0.5)
|
||||
// {
|
||||
// imageStore(output_image, uvi, col_x);
|
||||
//
|
||||
//#ifdef DEBUG
|
||||
// imageStore(debug_1_image, uvi, col_x);
|
||||
// imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
// imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
// imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
// imageStore(debug_5_image, uvi, col_x);
|
||||
// imageStore(debug_6_image, uvi, past_col_x);
|
||||
// imageStore(debug_7_image, uvi, past_col_x);
|
||||
// imageStore(debug_8_image, uvi, abs(vec4(past_vx / render_size * 10, past_vxz.z * 100, 1)));
|
||||
//#endif
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float zx = -0.05 / max(FLT_MIN, textureLod(depth_sampler, x, 0.0).x);
|
||||
//
|
||||
// float vx_length = max(0.5, length(vx));
|
||||
//
|
||||
// vec2 wx = safenorm(vx);
|
||||
//
|
||||
// vec2 wp = vec2(-wn.y, wn.x);
|
||||
//
|
||||
// if(dot(wp, vx) < 0)
|
||||
// {
|
||||
// wp = -wp;
|
||||
// }
|
||||
//
|
||||
// vec2 wc = safenorm(mix(wp, wx, clamp((vx_length - 0.5) / 1.5, 0, 1)));
|
||||
//
|
||||
// float weight = 0;// params.motion_blur_samples / (40 * vx_length);
|
||||
//
|
||||
// vec4 sum = col_x * weight;
|
||||
//
|
||||
// float j = interleaved_gradient_noise(uvi) - 0.5;
|
||||
//
|
||||
// int vnvx = 2;//int(vn_length / (10 + vx_length)) + 2;
|
||||
//
|
||||
// float total_back_weight = 1e-10;
|
||||
//
|
||||
// vec4 back_sum = col_x * total_back_weight;
|
||||
//
|
||||
// for(int i = 0; i < params.motion_blur_samples; i++)
|
||||
// {
|
||||
// float t = mix(-1., 0.0, (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
//
|
||||
// float T = abs(t * vn_length);
|
||||
//
|
||||
// float Tx = abs((t + 0.5) * vn_length);
|
||||
//
|
||||
// bool sample_main_v = !(((i - 1) % vnvx) == 0);
|
||||
//
|
||||
// vec2 d = vn;//sample_main_v ? vn : vx;
|
||||
//
|
||||
// vec2 nai_d = vx;
|
||||
//
|
||||
// vec2 nai_wd = safenorm(nai_d);
|
||||
//
|
||||
// float nai_dz = vxz.z;
|
||||
//
|
||||
// vec2 past_nai_d = past_vx;
|
||||
//
|
||||
// float dz = vnz.z;//sample_main_v ? vnz.z : vxz.z;
|
||||
//
|
||||
// vec2 wd = safenorm(d);
|
||||
//
|
||||
// vec2 y = x + (d / render_size) * t;
|
||||
//
|
||||
// vec2 nai_y = x + (nai_d / render_size) * t;
|
||||
//
|
||||
// vec2 past_nai_y = x + (past_nai_d / render_size) * t;
|
||||
//
|
||||
// float nai_y_length = max(0.5, length(nai_y));
|
||||
//
|
||||
// vec2 vy = textureLod(vector_sampler, y, 0.0).xy * render_size;// * 2;
|
||||
//
|
||||
// float vy_length = max(0.5, length(vy));
|
||||
//
|
||||
// vec2 nai_vy = textureLod(vector_sampler, nai_y, 0.0).xy * render_size;
|
||||
//
|
||||
// float nai_vy_length = max(0.5, length(nai_vy));
|
||||
//
|
||||
// float zy = -0.05 / max(FLT_MIN, textureLod(depth_sampler, y, 0.0).x - dz * t);
|
||||
//
|
||||
// float nai_zy = -0.05 / max(FLT_MIN, textureLod(depth_sampler, nai_y, 0.0).x - nai_dz * t);
|
||||
//
|
||||
// float f = z_compare(zy, zx, 15);
|
||||
// float b = z_compare(zx, zy, 15);
|
||||
//
|
||||
// float wa = abs(max(0, dot(vy / vy_length, wd)));
|
||||
//
|
||||
// float wb = abs((dot(wc, wd)));
|
||||
//
|
||||
// float cone_x = cone(T, vx_length);
|
||||
//
|
||||
// float cone_y = cone(T, vy_length);
|
||||
//
|
||||
// float nai_f = z_compare(nai_zy, zx, 15);
|
||||
//
|
||||
// float nai_b = z_compare(zx, nai_zy, 15);
|
||||
//
|
||||
// float nai_wa = abs(max(0, dot(nai_vy / nai_vy_length, nai_wd)));
|
||||
//
|
||||
// float nai_wb = abs((dot(wc, nai_wd)));
|
||||
//
|
||||
// float nai_cone_y = cone(T, nai_vy_length);
|
||||
//
|
||||
// float ay_trail = f * wa * step(FLT_MIN, cone_y);
|
||||
//
|
||||
// float ay_lead = (1 - f) * wb * step(FLT_MIN, cone_x);
|
||||
//
|
||||
// float nai_ay = nai_b;//max(nai_b, nai_f * nai_wa * step(FLT_MIN, nai_cone_y));
|
||||
//
|
||||
// vec4 col_y = textureLod(color_sampler, y, 0.0);
|
||||
//
|
||||
// vec4 past_col_y = textureLod(past_color_sampler, past_nai_y, 0.0);
|
||||
//
|
||||
// vec4 nai_col_y = textureLod(color_sampler, nai_y, 0.0);
|
||||
//
|
||||
// vec4 col_back = nai_col_y;
|
||||
//
|
||||
// total_back_weight += nai_ay;
|
||||
//
|
||||
// back_sum += col_back * nai_ay;
|
||||
//
|
||||
// weight += ay_trail + ay_lead;
|
||||
//
|
||||
// sum += col_y * ay_trail + past_col_y * ay_lead;
|
||||
// }
|
||||
//
|
||||
// back_sum *= (params.motion_blur_samples - weight) / total_back_weight;
|
||||
//
|
||||
// sum /= params.motion_blur_samples;
|
||||
//
|
||||
// back_sum /= params.motion_blur_samples;
|
||||
//
|
||||
// imageStore(output_image, uvi, sum + back_sum);
|
||||
//
|
||||
//#ifdef DEBUG
|
||||
// imageStore(debug_1_image, uvi, sum + back_sum);
|
||||
// imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
// imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
// imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
// imageStore(debug_5_image, uvi, col_x);//sum + back_sum);
|
||||
// imageStore(debug_6_image, uvi, past_col_x);
|
||||
// imageStore(debug_7_image, uvi, past_col_x);
|
||||
// imageStore(debug_8_image, uvi, abs(vec4(past_vx / render_size * 10, past_vxz.z * 100, 1)));
|
||||
//#endif
|
||||
//}
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://4vnw7nqk2lmb"
|
||||
path="res://.godot/imported/jump_flood_past_experimental_blur.glsl-75b0138dd1cf1e624e753e1e20d4e672.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/Archive/jump_flood_past_experimental_blur.glsl"
|
||||
dest_files=["res://.godot/imported/jump_flood_past_experimental_blur.glsl-75b0138dd1cf1e624e753e1e20d4e672.res"]
|
||||
|
||||
[params]
|
||||
|
@ -1,14 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://bcivntgn7ipwo"
|
||||
path="res://.godot/imported/jf_neighbor_depth_max.glsl-412337591574185d763ac95625cd98ac.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/jf_neighbor_depth_max.glsl"
|
||||
dest_files=["res://.godot/imported/jf_neighbor_depth_max.glsl-412337591574185d763ac95625cd98ac.res"]
|
||||
|
||||
[params]
|
||||
|
@ -24,7 +24,7 @@ layout(push_constant, std430) uniform Params
|
||||
float nan_fl_3;
|
||||
float nan_fl_6;
|
||||
float step_exponent_modifier;
|
||||
float step_size;
|
||||
float nan_fl_0;
|
||||
float max_dilation_radius;
|
||||
float nan_fl_1;
|
||||
float nan_fl_2;
|
||||
@ -81,7 +81,7 @@ void sample_fitness(vec2 uv_offset, vec4 uv_sample, vec2 render_size, inout vec4
|
||||
|
||||
float velocity_space_distance = dot(sample_velocity, uv_offset) / dot(sample_velocity, sample_velocity);
|
||||
|
||||
float mid_point = params.motion_blur_intensity / 2 + 1e-5;
|
||||
float mid_point = params.motion_blur_intensity / 2;
|
||||
|
||||
float absolute_velocity_space_distance = abs(velocity_space_distance - mid_point);
|
||||
|
||||
@ -91,30 +91,7 @@ void sample_fitness(vec2 uv_offset, vec4 uv_sample, vec2 render_size, inout vec4
|
||||
|
||||
float within_perpen_error_range = step(side_offset, params.perpen_error_thresh * params.motion_blur_intensity);
|
||||
|
||||
current_sample_fitness = vec4(/*max(absolute_velocity_space_distance, side_offset)*/absolute_velocity_space_distance, velocity_space_distance, uv_sample.w + uv_sample.z * velocity_space_distance, within_velocity_range * within_perpen_error_range);
|
||||
}
|
||||
|
||||
float is_sample_better(vec4 a, vec4 b)
|
||||
{
|
||||
return 1. - step(b.x * a.w, a.x * b.w);//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));
|
||||
}
|
||||
|
||||
vec4 backtrack_sample(vec2 chosen_uv, vec4 best_sample_fitness)
|
||||
{
|
||||
vec4 velocity = textureLod(tile_max_sampler, chosen_uv, 0.0);
|
||||
|
||||
vec2 uv_candidate = chosen_uv + velocity.xy;
|
||||
|
||||
vec4 velocity_candidate = textureLod(tile_max_sampler, uv_candidate, 0.0);
|
||||
|
||||
if((dot(velocity, velocity_candidate) / dot(velocity, velocity)) > 0.5 && velocity_candidate.w > 0)
|
||||
{
|
||||
return vec4(uv_candidate, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return vec4(chosen_uv, 0, 0);
|
||||
}
|
||||
current_sample_fitness = vec4(absolute_velocity_space_distance, velocity_space_distance, uv_sample.w + uv_sample.z * velocity_space_distance, within_velocity_range * within_perpen_error_range);
|
||||
}
|
||||
|
||||
void main()
|
||||
@ -128,7 +105,9 @@ void main()
|
||||
|
||||
vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size;
|
||||
|
||||
vec2 uv_step = vec2(round(params.step_size)) / render_size;
|
||||
vec2 step_size = vec2(round(pow(2 + params.step_exponent_modifier, params.last_iteration_index - params.iteration_index)));
|
||||
|
||||
vec2 uv_step = vec2(round(step_size)) / render_size;
|
||||
|
||||
vec4 best_sample_fitness = vec4(10, 10, 0, 0);
|
||||
|
||||
@ -154,40 +133,18 @@ void main()
|
||||
continue;
|
||||
}
|
||||
|
||||
if(params.iteration_index > 0)
|
||||
{
|
||||
check_uv = get_value(!set_a, check_uv).xy;
|
||||
check_uv = get_value(!set_a, check_uv).xy;
|
||||
|
||||
step_offset = check_uv - uvn;
|
||||
}
|
||||
step_offset = check_uv - uvn;
|
||||
|
||||
uv_sample = textureLod(tile_max_sampler, check_uv, 0.0);
|
||||
|
||||
sample_fitness(step_offset, uv_sample, render_size, current_sample_fitness);
|
||||
|
||||
float sample_better = 1. - step(best_sample_fitness.x * current_sample_fitness.w, current_sample_fitness.x * best_sample_fitness.w);
|
||||
float sample_better = 1. - step(current_sample_fitness.z * current_sample_fitness.w, best_sample_fitness.z * best_sample_fitness.w);
|
||||
best_sample_fitness = mix(best_sample_fitness, current_sample_fitness, sample_better);
|
||||
chosen_uv = mix(chosen_uv, check_uv, sample_better);
|
||||
|
||||
}
|
||||
|
||||
// if(params.iteration_index < params.last_iteration_index)
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float depth = textureLod(tile_max_sampler, uvn, 0.0).w;
|
||||
//
|
||||
// if(params.iteration_index == params.last_iteration_index && (best_sample_fitness.w < 0.5 || depth > best_sample_fitness.z))
|
||||
// {
|
||||
// set_value(set_a, uvi, vec4(uvn, 0, 0));
|
||||
// return;
|
||||
// }
|
||||
|
||||
set_value(set_a, uvi, vec4(chosen_uv, 0, 0));
|
||||
|
||||
// vec4 backtracked_sample = backtrack_sample(chosen_uv, best_sample_fitness);
|
||||
//
|
||||
// set_value(set_a, uvi, backtracked_sample);
|
||||
}
|
@ -10,11 +10,12 @@ layout(rgba16f, set = 0, binding = 3) uniform image2D past_color;
|
||||
// ----------------------------------------------------------
|
||||
float z_compare(float a, float b, float sze)
|
||||
{
|
||||
return clamp(1. - sze * (a - b) / min(a, b), 0, 1);
|
||||
return clamp(1. - sze * (a - b), 0, 1);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(velocity_sampler, 0));
|
||||
@ -34,11 +35,11 @@ void main()
|
||||
|
||||
vec4 past_col_x = textureLod(color_sampler, x, 0.0);
|
||||
|
||||
float alpha = 1 - z_compare(past_vx_vx.w, past_vx.w, 15);
|
||||
float alpha = 1 - z_compare(-past_vx.w, -past_vx_vx.w, 20000);
|
||||
|
||||
vec4 final_past_col = mix(past_col_vx, past_col_x, alpha);
|
||||
|
||||
vec4 final_past_vx = mix(past_vx_vx, past_vx, alpha);
|
||||
vec4 final_past_vx = mix(vec4(past_vx_vx.xyz, past_vx.w), past_vx, alpha);
|
||||
|
||||
imageStore(past_color, uv, final_past_col);
|
||||
imageStore(past_velocity, uv, final_past_vx);
|
||||
|
@ -6,8 +6,7 @@
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
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(set = 0, binding = 2) uniform sampler2D velocity_sampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D velocity_map;
|
||||
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_image;
|
||||
layout(set = 0, binding = 5) uniform sampler2D tile_max;
|
||||
@ -54,7 +53,7 @@ float cylinder(float T, float v)
|
||||
// ----------------------------------------------------------
|
||||
float z_compare(float a, float b, float sze)
|
||||
{
|
||||
return clamp(1. - sze * (a - b) / min(a, b), 0, 1);
|
||||
return clamp(1. - sze * (a - b), 0, 1);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
@ -74,7 +73,7 @@ float interleaved_gradient_noise(vec2 uv){
|
||||
vec2 safenorm(vec2 v)
|
||||
{
|
||||
float l = max(length(v), 1e-6);
|
||||
return v / l * int(1 >= 0.5);
|
||||
return v / l * int(l >= 0.5);
|
||||
}
|
||||
|
||||
vec2 jitter_tile(vec2 uvi)
|
||||
@ -87,18 +86,6 @@ vec2 jitter_tile(vec2 uvi)
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
float get_motion_difference(vec2 V, vec2 V2, float power)
|
||||
{
|
||||
vec2 VO = V - V2;
|
||||
float difference = dot(VO, V) / max(FLT_MIN, dot(V, V));
|
||||
return pow(clamp(difference, 0, 1), power);
|
||||
}
|
||||
|
||||
vec2 sample_random_offset(vec2 uv, float j)
|
||||
{
|
||||
return vec2(0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
|
||||
@ -112,31 +99,33 @@ void main()
|
||||
|
||||
vec2 velocity_map_sample = textureLod(velocity_map, x + jitter_tile(uvi), 0.0).xy;
|
||||
|
||||
vec3 vnz = textureLod(tile_max, velocity_map_sample, 0.0).xyz * vec3(render_size, 1);// * 2;
|
||||
vec3 vnz = textureLod(tile_max, velocity_map_sample, 0.0).xyz * vec3(render_size, 1);
|
||||
|
||||
float vn_length = max(0.5, length(vnz.xy));
|
||||
|
||||
float multiplier = clamp(vn_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vn_length);
|
||||
|
||||
vnz.xyz *= multiplier;
|
||||
|
||||
vn_length *= multiplier;
|
||||
|
||||
vec2 vn = vnz.xy;
|
||||
|
||||
float vn_length = max(0.5, length(vn));
|
||||
|
||||
vec2 wn = safenorm(vn);
|
||||
|
||||
vec4 col_x = textureLod(color_sampler, x, 0.0);
|
||||
|
||||
vec3 vxz = textureLod(vector_sampler, x, 0.0).xyz * vec3(render_size, 1);// * 2;
|
||||
vec4 vxz = textureLod(velocity_sampler, x, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float vx_length = max(0.5, length(vxz.xy));
|
||||
|
||||
//multiplier = clamp(vx_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vx_length);
|
||||
|
||||
vxz.xyz *= multiplier;
|
||||
|
||||
vx_length *= multiplier;
|
||||
|
||||
vec2 vx = vxz.xy;
|
||||
|
||||
vec3 past_vxz = textureLod(past_velocity_sampler, x, 0.0).xyz * vec3(render_size, 1);
|
||||
|
||||
vec2 past_vx = past_vxz.xy;
|
||||
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.5);
|
||||
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
vnz = mix(vnz, vxz, velocity_match);
|
||||
|
||||
vec4 past_col_x = textureLod(past_color_sampler, x, 0.0);
|
||||
vec2 wx = safenorm(vx);
|
||||
|
||||
if(vn_length <= 0.5)
|
||||
{
|
||||
@ -148,144 +137,180 @@ void main()
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
imageStore(debug_6_image, uvi, past_col_x);
|
||||
imageStore(debug_7_image, uvi, past_col_x);
|
||||
imageStore(debug_8_image, uvi, abs(vec4(past_vx / render_size * 10, past_vxz.z * 100, 1)));
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float zx = -0.05 / max(FLT_MIN, textureLod(depth_sampler, x, 0.0).x);
|
||||
vec3 wvnz = normalize(vnz.xyz);
|
||||
|
||||
float vx_length = max(0.5, length(vx));
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 1 / (10000 * pow(abs(vnz.z), 2)));
|
||||
|
||||
vec2 wx = safenorm(vx);
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
vec2 wp = vec2(-wn.y, wn.x);
|
||||
vnz = mix(vnz, vxz.xyz, velocity_match);
|
||||
|
||||
if(dot(wp, vx) < 0)
|
||||
{
|
||||
wp = -wp;
|
||||
}
|
||||
vec2 wn = safenorm(vn);
|
||||
|
||||
vec2 wc = safenorm(mix(wp, wx, clamp((vx_length - 0.5) / 1.5, 0, 1)));
|
||||
|
||||
float weight = 0;// params.motion_blur_samples / (40 * vx_length);
|
||||
|
||||
vec4 sum = col_x * weight;
|
||||
float zx = vxz.w;
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) - 0.5;
|
||||
|
||||
int vnvx = 2;//int(vn_length / (10 + vx_length)) + 2;
|
||||
vec4 past_vxz = textureLod(past_velocity_sampler, x, 0.0) * vec4(render_size * multiplier, 1 * multiplier, 1);
|
||||
|
||||
float total_back_weight = 1e-10;
|
||||
vec2 past_vx = past_vxz.xy;
|
||||
|
||||
vec4 back_sum = col_x * total_back_weight;
|
||||
vec4 past_col_x = textureLod(past_color_sampler, x, 0.0);
|
||||
|
||||
float t;
|
||||
float back_t;
|
||||
float T;
|
||||
vec2 y;
|
||||
float y_inside;
|
||||
vec4 nai_vy;
|
||||
vec2 nai_y;
|
||||
vec2 nai_back_y;
|
||||
float nai_zy;
|
||||
float nai_b;
|
||||
float nai_ay;
|
||||
float nai_y_inside;
|
||||
vec4 vy;
|
||||
float vy_length;
|
||||
float zy;
|
||||
float f;
|
||||
float wa;
|
||||
float ay_trail;
|
||||
float past_t;
|
||||
vec2 past_y;
|
||||
vec2 past_back_y;
|
||||
float past_ay;
|
||||
float alpha;
|
||||
vec4 past_vy;
|
||||
float past_zy;
|
||||
float past_b;
|
||||
float past_y_inside;
|
||||
float nai_T;
|
||||
float nai_vy_length;
|
||||
float nai_wa;
|
||||
|
||||
float weight = 1e-5;
|
||||
|
||||
vec4 sum = col_x * weight;
|
||||
|
||||
float nai_weight = 1e-5;
|
||||
|
||||
float nai_sub_weight = 1e-5;
|
||||
|
||||
vec4 nai_sum = col_x * nai_sub_weight;
|
||||
|
||||
float past_weight = 1e-5;
|
||||
|
||||
float past_sub_weight = 1e-5;
|
||||
|
||||
vec4 past_sum = past_col_x * past_sub_weight;
|
||||
|
||||
float final_sample_count = params.motion_blur_samples + 1e-5;
|
||||
|
||||
for(int i = 0; i < params.motion_blur_samples; i++)
|
||||
{
|
||||
float t = mix(-1., 0.0, (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
float T = abs(t * vn_length);
|
||||
back_t = mix(1, 0, (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
float Tx = abs((t + 0.5) * vn_length);
|
||||
T = abs(t * vn_length);
|
||||
|
||||
bool sample_main_v = !(((i - 1) % vnvx) == 0);
|
||||
y = x + (vn / render_size) * t;
|
||||
|
||||
vec2 d = vn;//sample_main_v ? vn : vx;
|
||||
nai_T = abs(t * vx_length);
|
||||
|
||||
vec2 nai_d = vx;
|
||||
nai_y = x + (vx / render_size) * t;
|
||||
|
||||
vec2 nai_wd = safenorm(nai_d);
|
||||
nai_back_y = x + (vx / render_size) * back_t;
|
||||
|
||||
float nai_dz = vxz.z;
|
||||
nai_vy = textureLod(velocity_sampler, nai_y, 0.0) * vec4(render_size * multiplier, 1 * multiplier, 1);
|
||||
|
||||
vec2 past_nai_d = past_vx;
|
||||
nai_vy_length = max(0.5, length(nai_vy.xy));
|
||||
|
||||
float dz = vnz.z;//sample_main_v ? vnz.z : vxz.z;
|
||||
nai_zy = nai_vy.w - vxz.z * t;
|
||||
|
||||
vec2 wd = safenorm(d);
|
||||
nai_b = z_compare(-zx, -nai_zy, 20000);
|
||||
|
||||
vec2 y = x + (d / render_size) * t;
|
||||
float nai_f = z_compare(-nai_zy, -zx, 20000);
|
||||
|
||||
vec2 nai_y = x + (nai_d / render_size) * t;
|
||||
nai_wa = abs(max(0, dot(nai_vy.xy / vy_length, wx)));
|
||||
|
||||
vec2 past_nai_y = x + (past_nai_d / render_size) * t;
|
||||
nai_ay = max(nai_b, 0);//step(nai_T, nai_vy_length * nai_wa));
|
||||
|
||||
float nai_y_length = max(0.5, length(nai_y));
|
||||
nai_weight += 1;
|
||||
|
||||
vec2 vy = textureLod(vector_sampler, y, 0.0).xy * render_size;// * 2;
|
||||
nai_sub_weight += 1;
|
||||
|
||||
float vy_length = max(0.5, length(vy));
|
||||
nai_y_inside = step(0, nai_y.x) * step(nai_y.x, 1) * step(0, nai_y.y) * step(nai_y.y, 1);
|
||||
|
||||
vec2 nai_vy = textureLod(vector_sampler, nai_y, 0.0).xy * render_size;
|
||||
nai_sum += mix(textureLod(color_sampler, nai_back_y, 0.0), textureLod(color_sampler, nai_y, 0.0), nai_ay * nai_y_inside);
|
||||
|
||||
float nai_vy_length = max(0.5, length(nai_vy));
|
||||
past_y = x + (past_vx / render_size) * t;
|
||||
|
||||
float zy = -0.05 / max(FLT_MIN, textureLod(depth_sampler, y, 0.0).x - dz * t);
|
||||
past_back_y = x + (past_vx / render_size) * back_t;
|
||||
|
||||
float nai_zy = -0.05 / max(FLT_MIN, textureLod(depth_sampler, nai_y, 0.0).x - nai_dz * t);
|
||||
alpha = z_compare(-past_vxz.w, -vxz.w, 20000);
|
||||
|
||||
float f = z_compare(zy, zx, 15);
|
||||
float b = z_compare(zx, zy, 15);
|
||||
past_vy = textureLod(past_velocity_sampler, past_y, 0.0) * vec4(render_size * multiplier, 1 * multiplier, 1);
|
||||
|
||||
float wa = abs(max(0, dot(vy / vy_length, wd)));
|
||||
past_zy = past_vy.w - past_vxz.z * t;
|
||||
|
||||
float wb = abs((dot(wc, wd)));
|
||||
past_b = z_compare(-past_vxz.w, -past_zy, 20000);
|
||||
|
||||
float cone_x = cone(T, vx_length);
|
||||
past_ay = (1 - step(nai_T, nai_vy_length * nai_wa)) * (1 - alpha);
|
||||
|
||||
float cone_y = cone(T, vy_length);
|
||||
past_weight += past_ay;
|
||||
|
||||
float nai_f = z_compare(nai_zy, zx, 15);
|
||||
past_sub_weight += 1;
|
||||
|
||||
float nai_b = z_compare(zx, nai_zy, 15);
|
||||
past_y_inside = step(0, past_y.x) * step(past_y.x, 1) * step(0, past_y.y) * step(past_y.y, 1);
|
||||
|
||||
float nai_wa = abs(max(0, dot(nai_vy / nai_vy_length, nai_wd)));
|
||||
past_sum += mix(textureLod(past_color_sampler, past_back_y, 0.0), textureLod(past_color_sampler, past_y, 0.0), past_b * past_y_inside);
|
||||
|
||||
float nai_wb = abs((dot(wc, nai_wd)));
|
||||
vy = textureLod(velocity_sampler, y, 0.0) * vec4(render_size * multiplier, 1 * multiplier, 1);
|
||||
|
||||
float nai_cone_y = cone(T, nai_vy_length);
|
||||
vy_length = max(0.5, length(vy.xy));
|
||||
|
||||
float ay_trail = f * wa * step(FLT_MIN, cone_y);
|
||||
zy = vy.w - vnz.z * t;
|
||||
|
||||
float ay_lead = (1 - f) * wb * step(FLT_MIN, cone_x);
|
||||
f = z_compare(-zy, -zx, 20000);
|
||||
|
||||
float nai_ay = nai_b;//max(nai_b, nai_f * nai_wa * step(FLT_MIN, nai_cone_y));
|
||||
wa = abs(max(0, dot(vy.xy / vy_length, wn)));
|
||||
|
||||
vec4 col_y = textureLod(color_sampler, y, 0.0);
|
||||
ay_trail = f * step(T, vy_length * wa);
|
||||
|
||||
vec4 past_col_y = textureLod(past_color_sampler, past_nai_y, 0.0);
|
||||
y_inside = step(0, y.x) * step(y.x, 1) * step(0, y.y) * step(y.y, 1);
|
||||
|
||||
vec4 nai_col_y = textureLod(color_sampler, nai_y, 0.0);
|
||||
weight += ay_trail * y_inside;
|
||||
|
||||
vec4 col_back = nai_col_y;
|
||||
|
||||
total_back_weight += nai_ay;
|
||||
|
||||
back_sum += col_back * nai_ay;
|
||||
|
||||
weight += ay_trail + ay_lead;
|
||||
|
||||
sum += col_y * ay_trail + past_col_y * ay_lead;
|
||||
sum += textureLod(color_sampler, y, 0.0) * ay_trail * y_inside;
|
||||
}
|
||||
|
||||
back_sum *= (params.motion_blur_samples - weight) / total_back_weight;
|
||||
sum /= weight;
|
||||
|
||||
sum /= params.motion_blur_samples;
|
||||
weight /= final_sample_count;
|
||||
|
||||
back_sum /= params.motion_blur_samples;
|
||||
nai_sum /= nai_sub_weight;
|
||||
|
||||
imageStore(output_image, uvi, sum + back_sum);
|
||||
nai_weight /= final_sample_count;
|
||||
|
||||
past_sum /= past_sub_weight;
|
||||
|
||||
past_weight /= final_sample_count;
|
||||
|
||||
sum = mix(mix(nai_sum, past_sum, past_weight), sum, weight);
|
||||
|
||||
imageStore(output_image, uvi, sum);
|
||||
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, sum + back_sum);
|
||||
imageStore(debug_1_image, uvi, sum);
|
||||
imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);//sum + back_sum);
|
||||
imageStore(debug_6_image, uvi, past_col_x);
|
||||
imageStore(debug_7_image, uvi, past_col_x);
|
||||
imageStore(debug_8_image, uvi, abs(vec4(past_vx / render_size * 10, past_vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
#endif
|
||||
}
|
@ -141,7 +141,7 @@ void main()
|
||||
return;
|
||||
}
|
||||
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.25);
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.5);
|
||||
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
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 velocity_sampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D velocity_map;
|
||||
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_image;
|
||||
@ -141,7 +140,7 @@ void main()
|
||||
return;
|
||||
}
|
||||
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.25);
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 0.5);
|
||||
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
@ -161,61 +160,67 @@ void main()
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) - 0.5;
|
||||
|
||||
int back_amount = 0;
|
||||
|
||||
int nai_back_i = 1;
|
||||
float nai_t;
|
||||
float nai_T;
|
||||
vec2 nai_y;
|
||||
float t;
|
||||
float T;
|
||||
vec2 y;
|
||||
vec4 nai_vy;
|
||||
float nai_zy;
|
||||
float nai_b;
|
||||
float nai_ay;
|
||||
vec4 nai_col_y;
|
||||
vec4 vy;
|
||||
float vy_length;
|
||||
float zy;
|
||||
float f;
|
||||
float wa;
|
||||
float ay_trail;
|
||||
vec4 col_y;
|
||||
|
||||
for(int i = 0; i < params.motion_blur_samples; i++)
|
||||
{
|
||||
float nai_t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
float nai_T = abs(nai_t * vx_length);
|
||||
nai_y = x + (vx / render_size) * t;
|
||||
|
||||
vec2 nai_y = x + (vx / render_size) * nai_t;
|
||||
T = abs(t * vn_length);
|
||||
|
||||
if(nai_y.x < 0 || nai_y.x > 1 || nai_y.y < 0 || nai_y.y > 1)
|
||||
y = x + (vn / render_size) * t;
|
||||
|
||||
if(nai_y.x < 0 || nai_y.x > 1 || nai_y.y < 0 || nai_y.y > 1 || y.x < 0 || y.x > 1 || y.y < 0 || y.y > 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float nai_zy = textureLod(depth_sampler, nai_y, 0.0).x - vxz.z * nai_t;
|
||||
nai_vy = textureLod(velocity_sampler, nai_y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float nai_b = z_compare(-zx, -nai_zy, 20000);
|
||||
nai_zy = nai_vy.w - vxz.z * t;
|
||||
|
||||
vec4 nai_vy = textureLod(velocity_sampler, nai_y, 0.0) * vec4(render_size, 1, 1);
|
||||
nai_b = z_compare(-zx, -nai_zy, 20000);
|
||||
|
||||
float nai_ay = nai_b;
|
||||
nai_ay = nai_b;
|
||||
|
||||
vec4 nai_col_y = textureLod(color_sampler, nai_y, 0.0);
|
||||
nai_col_y = textureLod(color_sampler, nai_y, 0.0);
|
||||
|
||||
total_back_weight += nai_ay;
|
||||
|
||||
back_sum += nai_col_y * nai_ay;
|
||||
|
||||
float t = mix(0., -1., (i - back_amount + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
vy = textureLod(velocity_sampler, y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float T = abs(t * vn_length);
|
||||
vy_length = max(0.5, length(vy.xy));
|
||||
|
||||
vec2 y = x + (vn / render_size) * t;
|
||||
zy = vy.w - vnz.z * t;
|
||||
|
||||
if(y.x < 0 || y.x > 1 || y.y < 0 || y.y > 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
f = z_compare(-zy, -zx, 20000);
|
||||
|
||||
vec4 vy = textureLod(velocity_sampler, y, 0.0) * vec4(render_size, 1, 1);
|
||||
wa = abs(max(0, dot(vy.xy / vy_length, wn)));
|
||||
|
||||
float vy_length = max(0.5, length(vy.xy));
|
||||
ay_trail = f * step(T, vy_length * wa);
|
||||
|
||||
float zy = vy.w - vnz.z * t;
|
||||
|
||||
float f = z_compare(-zy, -zx, 20000);
|
||||
|
||||
float wa = abs(max(0, dot(vy.xy / vy_length, wn)));
|
||||
|
||||
float ay_trail = f * step(T, vy_length * wa);
|
||||
|
||||
vec4 col_y = textureLod(color_sampler, y, 0.0);
|
||||
col_y = textureLod(color_sampler, y, 0.0);
|
||||
|
||||
weight += ay_trail;
|
||||
|
||||
|
@ -0,0 +1,239 @@
|
||||
#[compute]
|
||||
#version 450
|
||||
|
||||
#define FLT_MAX 3.402823466e+38
|
||||
#define FLT_MIN 1.175494351e-38
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D color_sampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D velocity_sampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D velocity_map;
|
||||
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_image;
|
||||
layout(set = 0, binding = 5) uniform sampler2D tile_max;
|
||||
|
||||
layout(push_constant, std430) uniform Params
|
||||
{
|
||||
float motion_blur_samples;
|
||||
float motion_blur_intensity;
|
||||
float motion_blur_center_fade;
|
||||
float frame;
|
||||
float last_iteration_index;
|
||||
float sample_step_multiplier;
|
||||
float step_exponent_modifier;
|
||||
float max_dilation_radius;
|
||||
int nan0;
|
||||
int nan1;
|
||||
int nan2;
|
||||
int nan3;
|
||||
} params;
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
|
||||
// ----------------------------------------------------------
|
||||
float soft_depth_compare(float depth_X, float depth_Y, float sze)
|
||||
{
|
||||
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
|
||||
}
|
||||
|
||||
float cone(float T, float v)
|
||||
{
|
||||
return clamp(1 - T / v, 0, 1);
|
||||
}
|
||||
|
||||
float cylinder(float T, float v)
|
||||
{
|
||||
return 1.0 - smoothstep(0.95 * v, 1.05 * v, T);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
|
||||
// ----------------------------------------------------------
|
||||
float z_compare(float a, float b, float sze)
|
||||
{
|
||||
return clamp(1. - sze * (a - b), 0, 1);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://www.shadertoy.com/view/ftKfzc
|
||||
// ----------------------------------------------------------
|
||||
float interleaved_gradient_noise(vec2 uv){
|
||||
uv += float(params.frame) * (vec2(47, 17) * 0.695);
|
||||
|
||||
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
|
||||
|
||||
return fract(magic.z * fract(dot(uv, magic.xy)));
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// from https://github.com/bradparks/KinoMotion__unity_motion_blur/tree/master
|
||||
// ----------------------------------------------------------
|
||||
vec2 safenorm(vec2 v)
|
||||
{
|
||||
float l = max(length(v), 1e-6);
|
||||
return v / l * int(l >= 0.5);
|
||||
}
|
||||
|
||||
vec2 jitter_tile(vec2 uvi)
|
||||
{
|
||||
float rx, ry;
|
||||
float angle = interleaved_gradient_noise(uvi + vec2(2, 0)) * M_PI * 2;
|
||||
rx = cos(angle);
|
||||
ry = sin(angle);
|
||||
return vec2(rx, ry) / textureSize(tile_max, 0) / 4;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
|
||||
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
|
||||
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
|
||||
|
||||
vec2 velocity_map_sample = textureLod(velocity_map, x + jitter_tile(uvi), 0.0).xy;
|
||||
|
||||
vec3 vnz = textureLod(tile_max, velocity_map_sample, 0.0).xyz * vec3(render_size, 1);
|
||||
|
||||
float vn_length = max(0.5, length(vnz.xy));
|
||||
|
||||
float multiplier = clamp(vn_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vn_length);
|
||||
|
||||
vnz.xyz *= multiplier;
|
||||
|
||||
vn_length *= multiplier;
|
||||
|
||||
vec2 vn = vnz.xy;
|
||||
|
||||
vec4 col_x = textureLod(color_sampler, x, 0.0);
|
||||
|
||||
vec2 wn = safenorm(vn);
|
||||
|
||||
vec4 vxz = textureLod(velocity_sampler, x, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
float vx_length = max(0.5, length(vxz.xy));
|
||||
|
||||
multiplier = clamp(vx_length, 0, min(params.max_dilation_radius, vn_length * params.motion_blur_intensity)) / max(FLT_MIN, vx_length);
|
||||
|
||||
vxz.xyz *= multiplier;
|
||||
|
||||
vx_length *= multiplier;
|
||||
|
||||
vec2 vx = vxz.xy;
|
||||
|
||||
if(vn_length <= 0.5)
|
||||
{
|
||||
imageStore(output_image, uvi, col_x);
|
||||
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, col_x);
|
||||
imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float velocity_match = pow(clamp(dot(vx, vn) / dot(vn, vn), 0, 1), 1 / (1000 * abs(vnz.z)));
|
||||
|
||||
vn = mix(vn, vx, velocity_match);
|
||||
|
||||
vnz = mix(vnz, vxz.xyz, velocity_match);
|
||||
|
||||
float zx = vxz.w;
|
||||
|
||||
float j = interleaved_gradient_noise(uvi) - 0.5;
|
||||
|
||||
vec2 nai_y;
|
||||
float t;
|
||||
float T;
|
||||
vec2 y;
|
||||
vec4 nai_vy;
|
||||
float nai_zy;
|
||||
float nai_b;
|
||||
float nai_ay;
|
||||
vec4 vy;
|
||||
float vy_length;
|
||||
float zy;
|
||||
float f;
|
||||
float wa;
|
||||
float ay_trail;
|
||||
float y_inside;
|
||||
|
||||
float weight = 1e-5;
|
||||
|
||||
vec4 sum = col_x * weight;
|
||||
|
||||
float nai_weight = 1e-5;
|
||||
|
||||
vec4 nai_sum = col_x * weight;
|
||||
|
||||
float final_sample_count = params.motion_blur_samples;
|
||||
|
||||
for(int i = 0; i < params.motion_blur_samples; i++)
|
||||
{
|
||||
t = mix(0., -1., (i + j + 1.0) / (params.motion_blur_samples + 1.0));
|
||||
|
||||
nai_y = x + (vx / render_size) * t;
|
||||
|
||||
T = abs(t * vn_length);
|
||||
|
||||
y = x + (vn / render_size) * t;
|
||||
|
||||
nai_vy = textureLod(velocity_sampler, nai_y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
nai_zy = nai_vy.w - vxz.z * t;
|
||||
|
||||
nai_b = z_compare(-zx, -nai_zy, 20000);
|
||||
|
||||
nai_ay = nai_b;
|
||||
|
||||
nai_weight += 1;
|
||||
|
||||
nai_sum += mix(col_x, textureLod(color_sampler, nai_y, 0.0), nai_ay);
|
||||
|
||||
vy = textureLod(velocity_sampler, y, 0.0) * vec4(render_size, 1, 1);
|
||||
|
||||
vy_length = max(0.5, length(vy.xy));
|
||||
|
||||
zy = vy.w - vnz.z * t;
|
||||
|
||||
f = z_compare(-zy, -zx, 20000);
|
||||
|
||||
wa = abs(max(0, dot(vy.xy / vy_length, wn)));
|
||||
|
||||
ay_trail = f * step(T, vy_length * wa);
|
||||
|
||||
y_inside = step(0, y.x) * step(y.x, 1) * step(0, y.y) * step(y.y, 1);
|
||||
|
||||
weight += ay_trail * y_inside;
|
||||
|
||||
sum += textureLod(color_sampler, y, 0.0) * ay_trail * y_inside;
|
||||
}
|
||||
|
||||
sum /= weight;
|
||||
|
||||
weight /= final_sample_count;
|
||||
|
||||
nai_sum /= nai_weight;
|
||||
|
||||
nai_weight /= final_sample_count;
|
||||
|
||||
sum = mix(nai_sum, sum, weight);
|
||||
|
||||
imageStore(output_image, uvi, sum);
|
||||
|
||||
#ifdef DEBUG
|
||||
imageStore(debug_1_image, uvi, sum);
|
||||
imageStore(debug_2_image, uvi, abs(vec4(vn / render_size * 10, vnz.z * 100, 1)));
|
||||
imageStore(debug_3_image, uvi, abs(vec4(velocity_map_sample - x, 0, 1)));
|
||||
imageStore(debug_4_image, uvi, abs(vec4(vx / render_size * 10, vxz.z * 100, 1)));
|
||||
imageStore(debug_5_image, uvi, col_x);
|
||||
#endif
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://c1vndulne5a5r"
|
||||
path="res://.godot/imported/jump_flood_simple_new_blur.glsl-eae32754cec4350c64665a4ed0291739.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/jump_flood_simple_new_blur.glsl"
|
||||
dest_files=["res://.godot/imported/jump_flood_simple_new_blur.glsl-eae32754cec4350c64665a4ed0291739.res"]
|
||||
|
||||
[params]
|
||||
|
@ -181,8 +181,7 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
dispatch_stage(tile_max_x_stage,
|
||||
[
|
||||
get_sampler_uniform(custom_velocity_image, 0, false),
|
||||
get_sampler_uniform(depth_image, 1, false),
|
||||
get_image_uniform(tile_max_x_image, 2)
|
||||
get_image_uniform(tile_max_x_image, 1)
|
||||
],
|
||||
tile_max_x_push_constants_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
@ -210,8 +209,6 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
16
|
||||
]
|
||||
|
||||
var step_size : float = round(pow(2 + step_exponent_modifier, last_iteration_index - i));
|
||||
|
||||
var jf_float_push_constants_test : PackedFloat32Array = [
|
||||
perpen_error_threshold,
|
||||
sample_step_multiplier,
|
||||
@ -221,12 +218,11 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
0,
|
||||
0,
|
||||
step_exponent_modifier,
|
||||
step_size,
|
||||
0,
|
||||
max_dilation_radius,
|
||||
0,
|
||||
0
|
||||
]
|
||||
|
||||
var jf_byte_array = jf_push_constants.to_byte_array()
|
||||
jf_byte_array.append_array(jf_float_push_constants_test.to_byte_array())
|
||||
|
||||
@ -236,7 +232,7 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
get_image_uniform(buffer_a_image, 1),
|
||||
get_image_uniform(buffer_b_image, 2),
|
||||
get_sampler_uniform(buffer_a_image, 3, false),
|
||||
get_sampler_uniform(buffer_b_image, 4, false)
|
||||
get_sampler_uniform(buffer_b_image, 4, false),
|
||||
],
|
||||
jf_byte_array,
|
||||
Vector3i(x_groups, y_groups, 1),
|
||||
|
@ -1,8 +1,8 @@
|
||||
[gd_resource type="Resource" script_class="ShaderStageResource" load_steps=3 format=3 uid="uid://bk5yd5plopwi2"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/SphynxMotionBlurToolkit/BaseClasses/shader_pass_resource.gd" id="1_ljx3c"]
|
||||
[ext_resource type="RDShaderFile" uid="uid://bdm5t4l1y3ts7" path="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/jump_flood_simple_blur.glsl" id="2_ase62"]
|
||||
[ext_resource type="RDShaderFile" uid="uid://c1vndulne5a5r" path="res://addons/SphynxMotionBlurToolkit/JumpFlood/ShaderFiles/jump_flood_simple_new_blur.glsl" id="2_i8sdd"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_ljx3c")
|
||||
shader_file = ExtResource("2_ase62")
|
||||
shader_file = ExtResource("2_i8sdd")
|
||||
|
@ -193,8 +193,6 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
16
|
||||
]
|
||||
|
||||
var step_size : float = round(pow(2 + step_exponent_modifier, last_iteration_index - i));
|
||||
|
||||
var jf_float_push_constants_test : PackedFloat32Array = [
|
||||
perpen_error_threshold,
|
||||
sample_step_multiplier,
|
||||
@ -204,12 +202,11 @@ func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSce
|
||||
0,
|
||||
0,
|
||||
step_exponent_modifier,
|
||||
step_size,
|
||||
0,
|
||||
max_dilation_radius,
|
||||
0,
|
||||
0
|
||||
]
|
||||
|
||||
var jf_byte_array = jf_push_constants.to_byte_array()
|
||||
jf_byte_array.append_array(jf_float_push_constants_test.to_byte_array())
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://ojudxyx6f4rx"
|
||||
path="res://.godot/imported/pre_blur_processor.glsl-5b87a82e9bf310f86ebf23e533cacd1d.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/PreBlurProcessing/Shaders/pre_blur_processor.glsl"
|
||||
dest_files=["res://.godot/imported/pre_blur_processor.glsl-5b87a82e9bf310f86ebf23e533cacd1d.res"]
|
||||
|
||||
[params]
|
||||
|
@ -1,7 +1,7 @@
|
||||
[gd_resource type="Resource" script_class="ShaderStageResource" load_steps=3 format=3 uid="uid://c8ulad7utgrg7"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/SphynxMotionBlurToolkit/BaseClasses/shader_pass_resource.gd" id="1_8hijg"]
|
||||
[ext_resource type="RDShaderFile" uid="uid://ojudxyx6f4rx" path="res://addons/SphynxMotionBlurToolkit/PreBlurProcessing/pre_blur_processor.glsl" id="2_w54vd"]
|
||||
[ext_resource type="RDShaderFile" uid="uid://ojudxyx6f4rx" path="res://addons/SphynxMotionBlurToolkit/PreBlurProcessing/Shaders/pre_blur_processor.glsl" id="2_w54vd"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_8hijg")
|
||||
|
@ -1,14 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="glsl"
|
||||
type="RDShaderFile"
|
||||
uid="uid://ojudxyx6f4rx"
|
||||
path="res://.godot/imported/pre_blur_processor.glsl-1e488552a0780ca6b7db6c45f5370f53.res"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/SphynxMotionBlurToolkit/PreBlurProcessing/pre_blur_processor.glsl"
|
||||
dest_files=["res://.godot/imported/pre_blur_processor.glsl-1e488552a0780ca6b7db6c45f5370f53.res"]
|
||||
|
||||
[params]
|
||||
|
Reference in New Issue
Block a user