mirror of
https://github.com/GarrettGunnell/Acerola-Compute.git
synced 2025-10-19 07:13:15 +00:00
Implement godot compositor tutorial
This commit is contained in:
commit
cc2c13b902
5 changed files with 193 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
||||||
|
/android/
|
||||||
|
|
||||||
|
/Ignored
|
||||||
|
|
||||||
|
icon.svg*
|
40
post_process.tscn
Normal file
40
post_process.tscn
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[gd_scene load_steps=8 format=3 uid="uid://ccgywstxl3rj6"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://post_process_shader.gd" id="1_g22wf"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c6jccoq62id4d" path="res://Ignored/tumblr_280d93eb9dac421ba08746f2d5362045_8c4f7d77_1280.jpg" id="2_lxnnh"]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_msfv3"]
|
||||||
|
|
||||||
|
[sub_resource type="CompositorEffect" id="CompositorEffect_5gbdv"]
|
||||||
|
resource_local_to_scene = false
|
||||||
|
resource_name = ""
|
||||||
|
enabled = true
|
||||||
|
effect_callback_type = 4
|
||||||
|
needs_motion_vectors = false
|
||||||
|
needs_normal_roughness = false
|
||||||
|
script = ExtResource("1_g22wf")
|
||||||
|
shader_code = "float gray = color.r * 0.2125 + color.g * 0.7154 + color.b * 0.0721;
|
||||||
|
color.rgb = vec3(gray);"
|
||||||
|
|
||||||
|
[sub_resource type="Compositor" id="Compositor_4ipny"]
|
||||||
|
compositor_effects = Array[CompositorEffect]([SubResource("CompositorEffect_5gbdv")])
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_in1jo"]
|
||||||
|
shading_mode = 0
|
||||||
|
albedo_texture = ExtResource("2_lxnnh")
|
||||||
|
billboard_mode = 1
|
||||||
|
|
||||||
|
[sub_resource type="QuadMesh" id="QuadMesh_yds3v"]
|
||||||
|
material = SubResource("StandardMaterial3D_in1jo")
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_msfv3")
|
||||||
|
compositor = SubResource("Compositor_4ipny")
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.01111)
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("QuadMesh_yds3v")
|
129
post_process_shader.gd
Normal file
129
post_process_shader.gd
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
@tool
|
||||||
|
extends CompositorEffect
|
||||||
|
class_name PostProcessShader
|
||||||
|
|
||||||
|
const template_shader : String = "#version 450
|
||||||
|
|
||||||
|
// Invocations in the (x, y, z) dimension (thread group sizes)
|
||||||
|
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||||
|
|
||||||
|
layout(rgba16f, set = 0, binding = 0) uniform image2D color_image;
|
||||||
|
|
||||||
|
// Our push constant (cbuffer??)
|
||||||
|
layout(push_constant, std430) uniform Params {
|
||||||
|
vec2 raster_size;
|
||||||
|
vec2 reserved;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
// main function/kernel?
|
||||||
|
void main() {
|
||||||
|
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
ivec2 size = ivec2(params.raster_size);
|
||||||
|
|
||||||
|
if (uv.x >= size.x || uv.y >= size.y) return;
|
||||||
|
|
||||||
|
vec4 color = imageLoad(color_image, uv);
|
||||||
|
|
||||||
|
#COMPUTE_CODE
|
||||||
|
|
||||||
|
imageStore(color_image, uv, color);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
@export_multiline var shader_code : String = "":
|
||||||
|
set(value):
|
||||||
|
mutex.lock()
|
||||||
|
shader_code = value
|
||||||
|
shader_is_dirty = true
|
||||||
|
mutex.unlock()
|
||||||
|
|
||||||
|
var rd : RenderingDevice
|
||||||
|
var shader : RID
|
||||||
|
var pipeline : RID
|
||||||
|
|
||||||
|
var mutex : Mutex = Mutex.new()
|
||||||
|
var shader_is_dirty : bool = true
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
effect_callback_type = EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
|
||||||
|
rd = RenderingServer.get_rendering_device()
|
||||||
|
|
||||||
|
func _notification(what):
|
||||||
|
if what == NOTIFICATION_PREDELETE:
|
||||||
|
if shader.is_valid():
|
||||||
|
rd.free_rid(shader)
|
||||||
|
|
||||||
|
|
||||||
|
func _check_shader() -> bool:
|
||||||
|
if not rd:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var new_shader_code : String = ""
|
||||||
|
|
||||||
|
mutex.lock()
|
||||||
|
if shader_is_dirty:
|
||||||
|
new_shader_code = shader_code
|
||||||
|
shader_is_dirty = false
|
||||||
|
mutex.unlock()
|
||||||
|
|
||||||
|
if new_shader_code.is_empty():
|
||||||
|
return pipeline.is_valid()
|
||||||
|
|
||||||
|
new_shader_code = template_shader.replace("#COMPUTE_CODE", new_shader_code);
|
||||||
|
|
||||||
|
if shader.is_valid():
|
||||||
|
rd.free_rid(shader)
|
||||||
|
shader = RID()
|
||||||
|
pipeline = RID()
|
||||||
|
|
||||||
|
var shader_source : RDShaderSource = RDShaderSource.new()
|
||||||
|
shader_source.language = RenderingDevice.SHADER_LANGUAGE_GLSL
|
||||||
|
shader_source.source_compute = new_shader_code
|
||||||
|
var shader_spirv : RDShaderSPIRV = rd.shader_compile_spirv_from_source(shader_source)
|
||||||
|
|
||||||
|
if shader_spirv.compile_error_compute != "":
|
||||||
|
push_error(shader_spirv.compile_error_compute)
|
||||||
|
push_error("In: " + new_shader_code)
|
||||||
|
return false
|
||||||
|
|
||||||
|
shader = rd.shader_create_from_spirv(shader_spirv)
|
||||||
|
if not shader.is_valid():
|
||||||
|
return false
|
||||||
|
|
||||||
|
pipeline = rd.compute_pipeline_create(shader)
|
||||||
|
return pipeline.is_valid()
|
||||||
|
|
||||||
|
func _render_callback(p_effect_callback_type, p_render_data):
|
||||||
|
if rd and p_effect_callback_type == EFFECT_CALLBACK_TYPE_POST_TRANSPARENT and _check_shader():
|
||||||
|
var render_scene_buffers : RenderSceneBuffersRD = p_render_data.get_render_scene_buffers()
|
||||||
|
if render_scene_buffers:
|
||||||
|
var size = render_scene_buffers.get_internal_size()
|
||||||
|
if size.x == 0 and size.y == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
var x_groups = (size.x - 1) / 8 + 1
|
||||||
|
var y_groups = (size.y - 1) / 8 + 1
|
||||||
|
var z_groups = 1
|
||||||
|
|
||||||
|
var push_constant : PackedFloat32Array = PackedFloat32Array()
|
||||||
|
push_constant.push_back(size.x)
|
||||||
|
push_constant.push_back(size.y)
|
||||||
|
push_constant.push_back(0.0)
|
||||||
|
push_constant.push_back(0.0)
|
||||||
|
|
||||||
|
var view_count = render_scene_buffers.get_view_count()
|
||||||
|
for view in range(view_count):
|
||||||
|
var input_image = render_scene_buffers.get_color_layer(view)
|
||||||
|
|
||||||
|
var uniform : RDUniform = RDUniform.new()
|
||||||
|
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
|
||||||
|
uniform.binding = 0
|
||||||
|
uniform.add_id(input_image)
|
||||||
|
var uniform_set = UniformSetCacheRD.get_cache(shader, 0, [uniform])
|
||||||
|
|
||||||
|
var compute_list := rd.compute_list_begin()
|
||||||
|
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
|
||||||
|
rd.compute_list_bind_uniform_set(compute_list, uniform_set, 0)
|
||||||
|
rd.compute_list_set_push_constant(compute_list, push_constant.to_byte_array(), push_constant.size() * 4)
|
||||||
|
rd.compute_list_dispatch(compute_list, x_groups, y_groups, z_groups)
|
||||||
|
rd.compute_list_end()
|
15
project.godot
Normal file
15
project.godot
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
; Engine configuration file.
|
||||||
|
; It's best edited using the editor UI and not directly,
|
||||||
|
; since the parameters that go here are not all obvious.
|
||||||
|
;
|
||||||
|
; Format:
|
||||||
|
; [section] ; section goes between []
|
||||||
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
|
config_version=5
|
||||||
|
|
||||||
|
[application]
|
||||||
|
|
||||||
|
config/name="Post Processing"
|
||||||
|
config/features=PackedStringArray("4.3", "Forward Plus")
|
||||||
|
config/icon="res://icon.svg"
|
Loading…
Add table
Add a link
Reference in a new issue