Compute shader experiments
All checks were successful
linting & formatting / build (push) Successful in 37s

This commit is contained in:
Rob Kelly 2025-08-29 16:04:56 -06:00
parent a597857367
commit 784576c3fc
5 changed files with 116 additions and 0 deletions

View File

@ -0,0 +1,74 @@
extends Node
@export var mask_texture: Texture2D
var shader: RID
var pipeline: RID
var output_buffer: PackedByteArray
var output_uniform: RDUniform
var texture_uniform: RDUniform
func _ready() -> void:
RenderingServer.call_on_render_thread(init_compute_shader)
func init_compute_shader() -> void:
# Rendering device handle
var rd := RenderingServer.get_rendering_device()
# Load shader
var shader_file: RDShaderFile = load("res://utilities/compute_shader_sandbox/compute_sum.glsl")
# Compile shader
shader = rd.shader_create_from_spirv(shader_file.get_spirv())
# Create pipeline
pipeline = rd.compute_pipeline_create(shader)
# Build output buffer uniform
output_buffer = PackedInt32Array([0]).to_byte_array()
var storage_buffer := rd.storage_buffer_create(output_buffer.size(), output_buffer)
output_uniform = RDUniform.new()
output_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
output_uniform.binding = 0
output_uniform.add_id(storage_buffer)
# Build texture uniform
texture_uniform = RDUniform.new()
texture_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
texture_uniform.binding = 1
var tex_view := RDTextureView.new()
var tex_fmt := RDTextureFormat.new()
tex_fmt.width = 64
tex_fmt.height = 64
tex_fmt.format = RenderingDevice.DATA_FORMAT_R8_UINT
tex_fmt.usage_bits = (
RenderingDevice.TEXTURE_USAGE_STORAGE_BIT + RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT
)
var image := mask_texture.get_image()
image.convert(Image.FORMAT_R8)
var texture := rd.texture_create(tex_fmt, tex_view, [image.get_data()])
texture_uniform.add_id(texture)
func _process(_delta: float) -> void:
RenderingServer.call_on_render_thread(dispatch_compute)
# Get result
var out_data := output_buffer.to_int32_array()
print(out_data)
func dispatch_compute() -> void:
# Rendering device handle
var rd := RenderingServer.get_rendering_device()
# Prepare shader context
var uniform_set := rd.uniform_set_create([output_uniform, texture_uniform], shader, 0)
# Bind context
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, 32, 32, 1)
rd.compute_list_end()

View File

@ -0,0 +1 @@
uid://bpkwaloqvlvod

View File

@ -0,0 +1,8 @@
[gd_scene load_steps=3 format=3 uid="uid://ywmbsmw2em5n"]
[ext_resource type="Script" uid="uid://bpkwaloqvlvod" path="res://utilities/compute_shader_sandbox/compute_shader_sandbox.gd" id="1_0g1hn"]
[ext_resource type="Texture2D" uid="uid://wqqwtmtmp147" path="res://levels/ghost_ship/level/mess_hall/overhead_light_mask_C.png" id="2_ckeim"]
[node name="ComputeShaderSandbox" type="Node"]
script = ExtResource("1_0g1hn")
mask_texture = ExtResource("2_ckeim")

View File

@ -0,0 +1,19 @@
#[compute]
#version 450
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout(set = 0, binding = 0, std430) restrict buffer outputBuffer {
uint sum_value;
} out_data;
layout(set = 0, binding = 1, r8ui) uniform readonly uimage2D inputTexture;
void main() {
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
uint value = imageLoad(inputTexture, uv).r + 1;
out_data.sum_value = atomicAdd(out_data.sum_value, value);
//out_data.sum_value += value;
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://bc34sy37cdf6k"
path="res://.godot/imported/compute_sum.glsl-65c025c095b2ca4b78b25d3c010d401d.res"
[deps]
source_file="res://utilities/compute_shader_sandbox/compute_sum.glsl"
dest_files=["res://.godot/imported/compute_sum.glsl-65c025c095b2ca4b78b25d3c010d401d.res"]
[params]