CompositorEffect postprocessing with mipmapped screen texture

Godot Version

4.6.3

Question

I try to create a simple “blur” post processing compositor, using mipmaps but I don’t know how to pass in a sampler that contains the mipmaps. I basically do:

var sampler_state := RDSamplerState.new()
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
sampler_state.mip_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler = rd.sampler_create(sampler_state)
.
.
var input_image: RID = render_scene_buffers.get_color_layer(0)
.
.
var uniform_sampler := RDUniform.new()
uniform_sampler.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
uniform_sampler.binding = 0
uniform_sampler.add_id(linear_sampler)
uniform_sampler.add_id(input_image)

and in the shader:

layout (set = 0, binding = 0) uniform sampler2D color_texture;
.
.
vec3 vScreenCol = textureLod(color_texture, uv, fScreenBlur).rgb;

I also tried to use render_scene_buffers.get_color_texture(), but this doesn’t make a difference.

btw: using a simple canvaslayer with color rect works perfect (eg: https://bun3d.com/tutorials/misc/godot_blur_shader/#full-shader) but I thought having it as compositor gives more flexbility.

The engine won’t create a copy of the screen texture with mipmaps unless necessary. The Environment glow effect creates it for example.

You can get the screen texture with mipmaps with RenderSceneBuffersRD.get_texture() like render_scene_buffers.get_texture("render_buffers", "blur_0")

I’ve not tested it but I’m pretty sure that this will only work in the post-transparent pass.

no, it doesn’t seem to work. interestingly, the first time

render_scene_buffers.get_texture(&"render_buffers", &"blur_0") is called, it gives and error:

  ERROR: servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp:390 - Condition "!named_textures.has(key)" is true. Returning: RID()

but the 2nd time, it returns a black/empty texture. and I think from then on it’s kind of cached?

Right, my bad. Looks like glow happens after applying the compositor effects so the texture is invalid.

In that case the only option I can think of is using the screen texture in a material so the engine copies the screen before the compositor effects are applied.

Something like:

shader_type spatial;

uniform sampler2D screen_texture: hint_screen_texture, filter_linear_mipmap;

void fragment() {
	vec4 color = texture(screen_texture, SCREEN_UV);
}

Applied to mesh should be enough to trigger it.

I did it with a quad mesh of size 0,0

thanks. that works, as long as the quad is visible; so I added it as a child of the camera.

I just realized that it “copies” the screen before the transparent objects are rendered, even if the post process uses POST_TRANSPARENT. It also doesn’t help if I set the instance to transparent or modify the alpha channel.

Yes, hint_screen_texture runs before the transparent pass.

You could do the blur yourself or open a proposal in the proposals repo if you find it necessary.