Godot Version
4.5
Question
This question is heavy on compute shaders but I don’t think they actually play a role, I just describe completely what I do.
I made a little ball simulation. We have a world scene that contains a Camera2D which contains a Sprite2D. We use a compute shader for our little simulation to generate a texture for the Sprite2D (with a 25px buffer on each side so texture is slightly bigger than cam). This means we basically do:
(sorry for shit formatting but this editor sucks hard, somehow doesnt allow me to intend anything)
func create_texture():
var tformat := RDTextureFormat.new()
tformat.width = viewport_size[0] + 2 * buffer_size # your texture width
tformat.height = viewport_size[1] + 2 * buffer_size # your texture height
tformat.format = RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM
tformat.usage_bits = RenderingDevice.TEXTURE_USAGE_STORAGE_BIT | RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT | RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT
var tview := RDTextureView.new()
var texture_rid = rd.texture_create(tformat, tview)
var texture = Texture2DRD.new()
texture.texture_rd_rid = texture_rid
var tex_uniform := RDUniform.new()
tex_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
tex_uniform.binding = 1
tex_uniform.add_id(texture_rid)
return [tex_uniform, texture]
We send the texture to the shader and send the image to it:
imageStore(output_texture, pixel, color);
Note: This requires us to use the global RenderDevice (otherwise you can’t send textures to Texture2DRD).
Anyway, here’s the result: (there’s a fps label in the middle)
Vsync on: https://imgur.com/vGRNs8W
Vsync off: https://imgur.com/dpnN4iB
I’m curious as to why we see these jittery artifacts. I doubt it has anything to do with the compute shader. My refresh rate of my laptop monitor is 60hz and I use:
func _physics_process(delta):
# Run compute shader to update ball physics and render
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)
# Dispatch enough work groups to cover all pixels (local_size is 16x16)
var texture_width = viewport_size.x + 2 * buffer_size
var texture_height = viewport_size.y + 2 * buffer_size
var workgroups_x = (texture_width + 15) / 16
var workgroups_y = (texture_height + 15) / 16
rd.compute_list_dispatch(compute_list, workgroups_x, workgroups_y, 1)
rd.compute_list_end()
Which is set to do 60 calls/s to the shader.
So we generate 60 fps and have a refresh rate of 60hz.
Can someone tell me what’s going on here exactly?