godot: GLES2 WebGL DEPTH_TEXTURE Feedback loop error

Issue description: I am trying to use this snippet https://docs.godotengine.org/en/3.2/tutorials/shading/screen-reading_shaders.html#depth-texture to create post-processing shader which uses pixels world position to calculate new color.

It doesn’t seem to work on browser with GLES2 if modifying ALBEDO and console gets filled with: GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.

However it seems to work with GLES3 on HTML5 but isn’t GLES3 going to be deprecated for browser? Also for me HTML5 GLES3 projects loads longer when starting it.

Here is the shader:

shader_type spatial;

void vertex() {
	POSITION = vec4(VERTEX, 1.0);
}

void fragment() {
	// https://docs.godotengine.org/en/3.2/tutorials/shading/screen-reading_shaders.html#depth-texture
	float depth = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;
	vec4 upos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
	vec3 pixel_position = upos.xyz / upos.w;
	
	// Lines below triggers the bug (on browser only)
	ALBEDO = vec3(1.0, 1.0, 1.0) * pixel_position.x;
}

On native and Godot editor the shader works as expected and you should see this: bug

Godot version: 3.2.3.stable.official

OS/device including version: Linux with Nvidia Drivers (460.39) - WebGL with GLES2 Chromium 89

Minimal reproduction project: GLES2 Webgl Bug.zip

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 1
  • Comments: 16 (9 by maintainers)

Most upvoted comments

Oh yep, still seems to be occurring in 3.6 beta 4. I’ll see if I can build the web version and work out why.

UPDATE: So far in my tests the PR #80481 seems to be working fine as intended. But it was designed to fix issue in #61632 (which is subtlety different afaik, although the error message is the same), so might not fix this one.

It resets and clears the active textures in set_current_render_target() as with clayjohn’s draft.

I have tried clearing all the texture slots in the reset, and that doesn’t fix the problem here in web build, so the logic for which active textures are in use seems unlikely to be the source of this continuing bug.

It may be that we need to call reset() in a different additional place (if indeed the hardware is capable of reading this depth texture on HTML5). But the error message is kind of vague so the problem may not be exactly the same. Will keep investigating.

UPDATE: Resetting both before and after rendering each scene item doesn’t fix it.

Firefox generates a more useful error message:

WebGL warning: drawArraysInstanced: Texture level 0 would be read by TEXTURE_2D unit 60, but written by framebuffer attachment DEPTH_ATTACHMENT, which would be illegal feedback.

I suspect the problem is it is trying to read from depth while also writing to depth at the same time in the same shader, maybe this is not supported on web, I’m not really expert in this area.

depth

Graphics Frame Analyzer shows on desktop the input texture (2033) is also the output depth (2033). This may not be supported. In order to do this you might need to write depth on one pass, then read on a separate pass with a different depth output maybe. But I’m not really familiar with this area.

Thanks for bearing with me.

CC @lawnjelly

Do you have any workaround ideas for this? I am trying to create shader for positional fog which affects all nodes in certain area. Similar to fog in WorldEnvironment but with static position.

You can place a procedural plane or cube in the world using MeshInstance + SpatialMaterial, then enable Proximity Fade on the SpatialMaterial and increase the fade distance. You can change the fog color by changing the material’s albedo color, and toggle unshaded mode if you don’t want lighting to impact fog. This should give you a nice fixed-position fog effect as long as the camera doesn’t enter the volume.