mirror of
https://github.com/sphynx-owner/JFA_driven_motion_blur_addon.git
synced 2025-09-19 04:06:08 +08:00
Multiple fixes, Higher blur Quality
- better blending - handle velocity buffer projection edge case - handle blur edge cases
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
extends CompositorEffect
|
||||
class_name EnhancedCompositorEffect
|
||||
|
||||
var rd: RenderingDevice
|
||||
|
||||
@ -11,6 +10,26 @@ var context: StringName = "PostProcess"
|
||||
|
||||
var all_shader_stages : Dictionary
|
||||
|
||||
@export var debug : bool = false:
|
||||
set(value):
|
||||
if(debug == value):
|
||||
return
|
||||
|
||||
debug = value
|
||||
free_shaders.call_deferred()
|
||||
generate_shaders.call_deferred()
|
||||
|
||||
var debug_1 : String = "debug_1"
|
||||
var debug_2 : String = "debug_2"
|
||||
var debug_3 : String = "debug_3"
|
||||
var debug_4 : String = "debug_4"
|
||||
var debug_5 : String = "debug_5"
|
||||
var debug_6 : String = "debug_6"
|
||||
var debug_7 : String = "debug_7"
|
||||
var debug_8 : String = "debug_8"
|
||||
|
||||
var all_debug_images : Array[RID]
|
||||
|
||||
func _init():
|
||||
RenderingServer.call_on_render_thread(_initialize_compute)
|
||||
|
||||
@ -28,6 +47,18 @@ func _notification(what):
|
||||
if shader_stage.shader.is_valid():
|
||||
rd.free_rid(shader_stage.shader)
|
||||
|
||||
func free_shaders():
|
||||
for shader_stage in all_shader_stages.keys():
|
||||
if shader_stage.pipeline.is_valid():
|
||||
rd.free_rid(shader_stage.pipeline)
|
||||
if shader_stage.shader.is_valid():
|
||||
rd.free_rid(shader_stage.shader)
|
||||
|
||||
func generate_shaders():
|
||||
for shader_stage in all_shader_stages.keys():
|
||||
generate_shader_stage(shader_stage)
|
||||
|
||||
|
||||
func subscirbe_shader_stage(shader_stage : ShaderStageResource):
|
||||
if all_shader_stages.has(shader_stage):
|
||||
return
|
||||
@ -70,11 +101,35 @@ func _initialize_compute():
|
||||
|
||||
nearest_sampler = rd.sampler_create(sampler_state)
|
||||
|
||||
for shader_stage in all_shader_stages.keys():
|
||||
generate_shader_stage(shader_stage)
|
||||
generate_shaders()
|
||||
|
||||
|
||||
func generate_shader_stage(shader_stage : ShaderStageResource):
|
||||
var shader_spirv : RDShaderSPIRV = shader_stage.shader_file.get_spirv()
|
||||
var shader_spirv : RDShaderSPIRV
|
||||
if debug:
|
||||
var file = FileAccess.open(shader_stage.shader_file.resource_path, FileAccess.READ)
|
||||
var split_shader : PackedStringArray = file.get_as_text().split("#[compute]", true, 1)
|
||||
var content : String = split_shader[min(1, split_shader.size() - 1)]
|
||||
var all_split_parts : PackedStringArray = content.split("#version 450", true, 1)
|
||||
content = str(all_split_parts[0],
|
||||
"#version 450
|
||||
#define DEBUG
|
||||
layout(rgba16f, set = 0, binding = 10) uniform image2D debug_1_image;
|
||||
layout(rgba16f, set = 0, binding = 11) uniform image2D debug_2_image;
|
||||
layout(rgba16f, set = 0, binding = 12) uniform image2D debug_3_image;
|
||||
layout(rgba16f, set = 0, binding = 13) uniform image2D debug_4_image;
|
||||
layout(rgba16f, set = 0, binding = 14) uniform image2D debug_5_image;
|
||||
layout(rgba16f, set = 0, binding = 15) uniform image2D debug_6_image;
|
||||
layout(rgba16f, set = 0, binding = 16) uniform image2D debug_7_image;
|
||||
layout(rgba16f, set = 0, binding = 17) uniform image2D debug_8_image;",
|
||||
all_split_parts[1])
|
||||
var shader_source : RDShaderSource = RDShaderSource.new()
|
||||
shader_source.set_stage_source(RenderingDevice.SHADER_STAGE_COMPUTE, content)
|
||||
shader_spirv = rd.shader_compile_spirv_from_source(shader_source, false)
|
||||
print(content)
|
||||
else:
|
||||
shader_spirv = shader_stage.shader_file.get_spirv()
|
||||
|
||||
shader_stage.shader = rd.shader_create_from_spirv(shader_spirv)
|
||||
shader_stage.pipeline = rd.compute_pipeline_create(shader_stage.shader)
|
||||
|
||||
@ -91,9 +146,32 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
||||
|
||||
if render_size.x == 0 or render_size.y == 0:
|
||||
return
|
||||
|
||||
if debug:
|
||||
ensure_texture(debug_1, render_scene_buffers)
|
||||
ensure_texture(debug_2, render_scene_buffers)
|
||||
ensure_texture(debug_3, render_scene_buffers)
|
||||
ensure_texture(debug_4, render_scene_buffers)
|
||||
ensure_texture(debug_5, render_scene_buffers)
|
||||
ensure_texture(debug_6, render_scene_buffers)
|
||||
ensure_texture(debug_7, render_scene_buffers)
|
||||
ensure_texture(debug_8, render_scene_buffers)
|
||||
|
||||
var view_count = render_scene_buffers.get_view_count()
|
||||
|
||||
for view in range(view_count):
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_1, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_2, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_3, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_4, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_5, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_6, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_7, view, 0, 1, 1))
|
||||
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_8, view, 0, 1, 1))
|
||||
|
||||
_render_callback_2(render_size, render_scene_buffers, render_scene_data)
|
||||
|
||||
all_debug_images.clear()
|
||||
|
||||
func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSceneBuffersRD, render_scene_data : RenderSceneDataRD):
|
||||
pass
|
||||
@ -128,6 +206,11 @@ func get_sampler_uniform(image: RID, binding: int, linear : bool = true) -> RDUn
|
||||
func dispatch_stage(stage : ShaderStageResource, uniforms : Array[RDUniform], push_constants : PackedByteArray, dispatch_size : Vector3i, label : String = "DefaultLabel", view : int = 0, color : Color = Color(1, 1, 1, 1)):
|
||||
rd.draw_command_begin_label(label + " " + str(view), color)
|
||||
|
||||
if debug:
|
||||
for i in 8:
|
||||
var debug_image_index = i + view * 8;
|
||||
uniforms.append(get_image_uniform(all_debug_images[debug_image_index], 10 + i))
|
||||
|
||||
var tex_uniform_set = UniformSetCacheRD.get_cache(stage.shader, 0, uniforms)
|
||||
|
||||
var compute_list = rd.compute_list_begin()
|
||||
|
@ -1,5 +1,27 @@
|
||||
extends EnhancedCompositorEffect
|
||||
class_name MotionBlurCompositorEffect
|
||||
extends "res://addons/SphynxMotionBlurToolkit/BaseClasses/enhanced_compositor_effect.gd"
|
||||
|
||||
@export_group("Motion Blur")
|
||||
# diminishing returns over 16
|
||||
@export_range(4, 64) var samples: int = 16
|
||||
# you really don't want this over 0.5, but you can if you want to try
|
||||
@export_range(0, 0.5, 0.001, "or_greater") var intensity: float = 1
|
||||
@export_range(0, 1) var center_fade: float = 0.0
|
||||
|
||||
## wether this motion blur stays the same intensity below
|
||||
## target_constant_framerate
|
||||
@export var framerate_independent : bool = true
|
||||
|
||||
## Description: Removes clamping on motion blur scale to allow framerate independent motion
|
||||
## blur to scale longer than realistically possible when render framerate is higher
|
||||
## than target framerate.[br][br]
|
||||
## [color=yellow]Warning:[/color] Turning this on would allow over-blurring of pixels, which
|
||||
## produces inaccurate results, and would likely cause nausea in players over
|
||||
## long exposure durations, use with caution and out of artistic intent
|
||||
@export var uncapped_independence : bool = false
|
||||
|
||||
## if framerate_independent is enabled, the blur would simulate
|
||||
## sutter speeds at that framerate, and up.
|
||||
@export var target_constant_framerate : float = 30
|
||||
|
||||
func _init():
|
||||
set_deferred("context", "MotionBlur")
|
||||
|
Reference in New Issue
Block a user