Skip to content

Commit

Permalink
Add demo showing the use of RenderingEffects to do post processing
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Sep 6, 2023
1 parent e9f0f75 commit d6d0fd8
Show file tree
Hide file tree
Showing 25 changed files with 1,189 additions and 0 deletions.
2 changes: 2 additions & 0 deletions compute/post_effects/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
2 changes: 2 additions & 0 deletions compute/post_effects/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Godot 4+ specific ignores
.godot/
11 changes: 11 additions & 0 deletions compute/post_effects/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Post effects

This demo shows how to implement post effects using the new RenderingEffect class.

Renderer: Forward Plus

> Note: this demo requires Godot 4.2 or later
## Screenshots

![Screenshot](screenshots/compute_texture.webp)
74 changes: 74 additions & 0 deletions compute/post_effects/gray_scale/gray_scale.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@tool
extends RenderingEffect
class_name RenderingEffectGrayScale

# This is a very simple effects demo that takes our color values and writes
# back gray scale values.

func _init():
effect_callback_type = RenderingEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
RenderingServer.call_on_render_thread(_initialize_compute)

func _notification(what):
if what == NOTIFICATION_PREDELETE:
# When this is called it should be safe to clean up our shader.
# If not we'll crash anyway because we can no longer call our _render_callback.
if shader.is_valid():
rd.free_rid(shader)

###############################################################################
# Everything after this point is designed to run on our rendering thread

var rd : RenderingDevice

var shader : RID
var pipeline : RID

func _initialize_compute():
rd = RenderingServer.get_rendering_device()
if !rd:
return

# Create our shader
var shader_file = load("res://gray_scale/gray_scale.glsl")
var shader_spirv: RDShaderSPIRV = shader_file.get_spirv()
shader = rd.shader_create_from_spirv(shader_spirv)
pipeline = rd.compute_pipeline_create(shader)

func _render_callback(p_effect_callback_type, p_render_data):
if rd and p_effect_callback_type == RenderingEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT:
# Get our render scene buffers object, this gives us access to our render buffers.
# Note that implementation differs per renderer hence the need for the cast.
var render_scene_buffers : RenderSceneBuffersRD = p_render_data.get_render_scene_buffers()
if render_scene_buffers:
# Get our render size, this is the 3D render resolution!
var size = render_scene_buffers.get_internal_size()
if size.x == 0 and size.y == 0:
return

# We can use a compute shader here
var x_groups = (size.x - 1) / 8 + 1
var y_groups = (size.y - 1) / 8 + 1

# Barrier
rd.barrier(RenderingDevice.BARRIER_MASK_ALL_BARRIERS, RenderingDevice.BARRIER_MASK_COMPUTE)

# Loop through views just in case we're doing stereo rendering. No extra cost if this is mono.
var view_count = render_scene_buffers.get_view_count()
for view in range(view_count):
# Get the RID for our color image, we will be reading from and writing to it.
var input_image = render_scene_buffers.get_color_layer(view)

# Create a uniform set, this will be cached, the cache will be cleared if our viewports configuration is changed
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 ])

# Run our compute shader
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_dispatch(compute_list, x_groups, y_groups, 1)
rd.compute_list_end()
18 changes: 18 additions & 0 deletions compute/post_effects/gray_scale/gray_scale.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[compute]
#version 450

// Invocations in the (x, y, z) dimension
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;

layout(rgba16f, set = 0, binding = 0) uniform image2D color_image;

// The code we want to execute in each invocation
void main() {
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);

vec4 color = imageLoad(color_image, uv);
float gray = max(max(color.r, color.b), color.g);
color.rgb = vec3(gray);

imageStore(color_image, uv, color);
}
14 changes: 14 additions & 0 deletions compute/post_effects/gray_scale/gray_scale.glsl.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[remap]

importer="glsl"
type="RDShaderFile"
uid="uid://cycdb7vyg3b6g"
path="res://.godot/imported/gray_scale.glsl-cdec27ad421b3dcac596053515285dc6.res"

[deps]

source_file="res://gray_scale/gray_scale.glsl"
dest_files=["res://.godot/imported/gray_scale.glsl-cdec27ad421b3dcac596053515285dc6.res"]

[params]

1 change: 1 addition & 0 deletions compute/post_effects/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions compute/post_effects/icon.svg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://cm88hfhyutq2d"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
52 changes: 52 additions & 0 deletions compute/post_effects/main.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
extends Node3D

@onready var sssr_button = $UI/MarginContainer/VBoxContainer/SSSR
@onready var gray_scale_button = $UI/MarginContainer/VBoxContainer/GrayScaleBtn

var create_depth_mips_effect : RenderingEffectCreateDepthMips
var apply_sssr_effect : RenderingEffectApplySSSR
var gray_scale_effect : RenderingEffectGrayScale

# Called when the node enters the scene tree for the first time.
func _ready():
var environment : Environment = $WorldEnvironment.environment
for effect in environment.rendering_effects:
if effect.get_script() == RenderingEffectCreateDepthMips:
create_depth_mips_effect = effect
elif effect.get_script() == RenderingEffectApplySSSR:
apply_sssr_effect = effect
elif effect.get_script() == RenderingEffectGrayScale:
gray_scale_effect = effect

if create_depth_mips_effect and apply_sssr_effect:
sssr_button.button_pressed = create_depth_mips_effect.enabled

if gray_scale_effect:
gray_scale_button.button_pressed = gray_scale_effect.enabled

var cam_x = 0.0
var cam_y = 0.0

func _input(event):
if event is InputEventMouseMotion:
var mouse_event : InputEventMouseMotion = event

if mouse_event.button_mask & MOUSE_BUTTON_MASK_LEFT:
cam_x = clamp(cam_x + mouse_event.relative.y * 0.01, -PI * 0.1, PI * 0.25)
cam_y -= mouse_event.relative.x * 0.01

var b1 : Basis = Basis(Vector3.UP, cam_y)
var b2 : Basis = Basis(Vector3.LEFT, cam_x)

$Pivot.transform.basis = b1 * b2

func _on_simple_ssr_toggled(toggled_on):
if create_depth_mips_effect and apply_sssr_effect:
create_depth_mips_effect.enabled = toggled_on
apply_sssr_effect.enabled = toggled_on

func _on_gray_scale_btn_toggled(toggled_on):
if gray_scale_effect:
gray_scale_effect.enabled = toggled_on


161 changes: 161 additions & 0 deletions compute/post_effects/main.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
[gd_scene load_steps=23 format=3 uid="uid://hay7hbv1cp62"]

[ext_resource type="Script" path="res://gray_scale/gray_scale.gd" id="1_di38g"]
[ext_resource type="Script" path="res://main.gd" id="1_ekxfu"]
[ext_resource type="Texture2D" uid="uid://bshdn70nudsun" path="res://pattern.png" id="2_d1qxb"]
[ext_resource type="Script" path="res://simple_ssr/create_depth_mips.gd" id="2_lv16x"]
[ext_resource type="Script" path="res://simple_ssr/apply_sssr.gd" id="3_ygheb"]
[ext_resource type="Texture2D" uid="uid://d0e66wb8yplkw" path="res://uv.jpg" id="5_ybioc"]

[sub_resource type="RenderingEffect" id="RenderingEffect_rprpc"]
resource_local_to_scene = false
resource_name = ""
enabled = true
effect_callback_type = 0
access_resolved_color = false
access_resolved_depth = true
needs_motion_vectors = false
needs_normal_roughness = false
script = ExtResource("2_lv16x")

[sub_resource type="RenderingEffect" id="RenderingEffect_sm2nk"]
resource_local_to_scene = false
resource_name = ""
enabled = true
effect_callback_type = 2
access_resolved_color = false
access_resolved_depth = false
needs_motion_vectors = false
needs_normal_roughness = true
needs_separate_specular = true
script = ExtResource("3_ygheb")
max_distance = 1.0
max_steps = 32

[sub_resource type="RenderingEffect" id="RenderingEffect_jcxua"]
resource_local_to_scene = false
resource_name = ""
enabled = false
effect_callback_type = 4
needs_motion_vectors = false
needs_normal_roughness = false
script = ExtResource("1_di38g")

[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ptioq"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)

[sub_resource type="Sky" id="Sky_gkygq"]
sky_material = SubResource("ProceduralSkyMaterial_ptioq")

[sub_resource type="Environment" id="Environment_kx13e"]
background_mode = 2
sky = SubResource("Sky_gkygq")
tonemap_mode = 2
ssr_depth_tolerance = 3.41
glow_enabled = true
rendering_effects = Array[RenderingEffect]([SubResource("RenderingEffect_rprpc"), SubResource("RenderingEffect_sm2nk"), SubResource("RenderingEffect_jcxua")])

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tvupy"]
albedo_texture = ExtResource("5_ybioc")
metallic = 0.5
roughness = 0.75
uv1_scale = Vector3(5, 5, 5)

[sub_resource type="PlaneMesh" id="PlaneMesh_fbrjs"]
size = Vector2(20, 20)

[sub_resource type="SphereMesh" id="SphereMesh_nqw7b"]

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mwci7"]
albedo_texture = ExtResource("2_d1qxb")
metallic = 0.78
roughness = 0.24

[sub_resource type="SphereMesh" id="SphereMesh_lau6s"]

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qdjdj"]
albedo_color = Color(1, 0.298039, 0.247059, 1)
albedo_texture = ExtResource("2_d1qxb")
metallic = 0.26
roughness = 0.59

[sub_resource type="CylinderMesh" id="CylinderMesh_jepk0"]

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xkdqw"]
albedo_color = Color(0.580392, 0.658824, 1, 1)
albedo_texture = ExtResource("2_d1qxb")
metallic = 0.86
roughness = 0.29

[sub_resource type="BoxMesh" id="BoxMesh_syokj"]

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_chobt"]
albedo_color = Color(0.588235, 0.282353, 0.443137, 1)
albedo_texture = ExtResource("2_d1qxb")
metallic = 0.52
roughness = 0.42

[node name="Main" type="Node3D"]
script = ExtResource("1_ekxfu")

[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_kx13e")

[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.959131, 0.245052, -0.141481, -0.0849703, 0.726354, 0.682048, 0.269902, -0.642152, 0.717491, 0, 1.94732, 0)
shadow_enabled = true

[node name="Pivot" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.553607, 0.779114, 0)

[node name="Camera3D" type="Camera3D" parent="Pivot"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3)

[node name="Floor" type="MeshInstance3D" parent="."]
material_override = SubResource("StandardMaterial3D_tvupy")
mesh = SubResource("PlaneMesh_fbrjs")

[node name="MetalSphere" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.721009, 0)
mesh = SubResource("SphereMesh_nqw7b")
surface_material_override/0 = SubResource("StandardMaterial3D_mwci7")

[node name="RedSphere" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.17882, 0.628256, -0.532507)
mesh = SubResource("SphereMesh_lau6s")
surface_material_override/0 = SubResource("StandardMaterial3D_qdjdj")

[node name="Cylinder" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.29466, 0, 0.409778)
mesh = SubResource("CylinderMesh_jepk0")
surface_material_override/0 = SubResource("StandardMaterial3D_xkdqw")

[node name="Box" type="MeshInstance3D" parent="."]
transform = Transform3D(0.682049, -0.297997, -0.667837, -1.49012e-08, 0.913212, -0.407486, 0.731306, 0.277925, 0.622855, 2.41454, 0.500351, 0.0996274)
mesh = SubResource("BoxMesh_syokj")
surface_material_override/0 = SubResource("StandardMaterial3D_chobt")

[node name="UI" type="CanvasLayer" parent="."]

[node name="MarginContainer" type="MarginContainer" parent="UI"]
offset_right = 40.0
offset_bottom = 40.0
theme_override_constants/margin_left = 5
theme_override_constants/margin_top = 5
theme_override_constants/margin_right = 5
theme_override_constants/margin_bottom = 5

[node name="VBoxContainer" type="VBoxContainer" parent="UI/MarginContainer"]
layout_mode = 2

[node name="SSSR" type="CheckBox" parent="UI/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "SSSR"

[node name="GrayScaleBtn" type="CheckBox" parent="UI/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "Gray scale"

[connection signal="toggled" from="UI/MarginContainer/VBoxContainer/SSSR" to="." method="_on_simple_ssr_toggled"]
[connection signal="toggled" from="UI/MarginContainer/VBoxContainer/GrayScaleBtn" to="." method="_on_gray_scale_btn_toggled"]
Binary file added compute/post_effects/pattern.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit d6d0fd8

Please sign in to comment.