Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lacking compute support (HTML5) #2177

Closed
tavurth opened this issue Jan 24, 2021 · 17 comments
Closed

Lacking compute support (HTML5) #2177

tavurth opened this issue Jan 24, 2021 · 17 comments

Comments

@tavurth
Copy link

tavurth commented Jan 24, 2021

Describe the project you are working on

A water depth & velocity simulation shader in 2D (from above).

Describe the problem or limitation you are having in your project

I've run into many issues while dealing with Godot's shader language, and I wanted to start this post as part of my documentation of such. When dealing with the current shader implementation I feel like my hands are tied many times, which leads me to believe that the current shader implementation keeps Godot far behind other engines.

No compute support (or inconsistent)

I've been using a lot of compute shaders using Viewports & only clearing the screen on the next render. This is extremely useful for people making CA (cellular automata), however at present support in Godot is lacking or buggy.

An example of this can be found here.

FBO (viewport) is not currently fully cross compatible to the WEBASM version of Godot, which means we lose portability.

### Describe the feature / enhancement and how it helps to overcome the problem or limitation See above

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

See above

If this enhancement will not be used often, can it be worked around with a few lines of script?

This enhancement will affect anyone who has more than a passing interest in shaders.

Is there a reason why this should be core and not an add-on in the asset library?

Shader language improvements must be core.

@tavurth tavurth changed the title Lacking compute support (HTML5) [Shaders] Lacking compute support (HTML5) Jan 24, 2021
@Calinou
Copy link
Member

Calinou commented Jan 24, 2021

WebGL 2.0 is a subset of OpenGL ES 3.0, which itself doesn't support compute shaders. This feature is impossible to support until WebGPU comes around, and that won't happen before 4.0 (if not later).

The same applies to the GLES3 and GLES2 renderers on desktop.

@tavurth
Copy link
Author

tavurth commented Jan 24, 2021

Yep that makes sense why it wasn't working in the HTML5 version!

However I have found a workaround, as can bee seen at the end of the docs for this project.

@Calinou Calinou changed the title [Shaders] Lacking compute support (HTML5) Add particle-as-compute shader support for HTML5 Jan 24, 2021
@tavurth tavurth changed the title Add particle-as-compute shader support for HTML5 Lacking compute support (HTML5) Jan 24, 2021
@Calinou
Copy link
Member

Calinou commented Jan 24, 2021

@tavurth Godot doesn't have "true" compute shader support in 3.x. Reading your proposals, it seems you're using particle shaders as a hack for compute shader functionality, hence the issue title I applied.

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

Almost, I'm using canvas shaders (2d texture rendering, rather than vertex rendering), and yes I would say it's lacking, however this issue should still be relevant when moving to the new 4.0 backend. (unless work is done on this)

@clayjohn
Copy link
Member

Are you saying that Viewports are broken in HTML5? If so, this sounds like it needs to be a bug report rather than a proposal.

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

At the current moment a sprite which is a child of a viewport cannot set it's texture to the parent viewport in HTML5.

image

I guess you might be right, this could be a bug, but may be a limitation of the current rendering engine.

@Faless
Copy link

Faless commented Jan 25, 2021

I guess you might be right, this could be a bug, but may be a limitation of the current rendering engine.

Can you provide some information on your OS and browser?
And possibly a screenshot showing what is the result on other platforms on HTML5?

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

Screenshot 2021-01-25 at 20 40 48

Screenshot 2021-01-25 at 20 41 01

Screenshot 2021-01-25 at 20 42 21

Here's an exported template of this repo

GameOfLife.zip

Unzip then run python3 -m http.server from the folder.

The code works just fine in Godot, but when exporting to HTML5 it breaks.

Workaround version (TextureRect + SCREEN_TEXTURE) can be found here

@Faless
Copy link

Faless commented Jan 25, 2021

Did you try other browsers?
See:

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

I tried just now in Firefox and the game of life example does not work.

It's not related to the above bug report, as I just tried the following structure:

ViewportContainer
  - Viewport
      - Label

And everything seems to be working as expected:

Screenshot 2021-01-25 at 21 03 43

@Faless
Copy link

Faless commented Jan 25, 2021

I'm seeing the following warning with that project running in Firefox:
WebGL warning: drawElementsInstanced: Texture level 0 would be read by TEXTURE_2D unit 0, but written by framebuffer attachment COLOR_ATTACHMENT0, which would be illegal feedback.

@clayjohn
Copy link
Member

clayjohn commented Jan 25, 2021

This is very clearly a limitation of WebGL. I'm surprised it even works on desktop.

To do GPGPU using framebuffers you should always use 2 framebuffers and rotate between them.

This should be moved to the Godot repo and tagged as a documentation issue.

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

@clayjohn interesting, so basically double buffering.
You would suggest swapping out the renderer between two viewports before each frame?

@clayjohn
Copy link
Member

Essentially yes.

Rendering to the same Viewport that you are reading from is not well supported (and I'm pretty sure the OpenGL specification forbids it).

Instead you should use what is often called a "ping pong" approach.

The Sprite under Viewport A reads from Viewport B. While the Sprite under Viewport B reads from Viewport A.

Depending on your program the Sprite in Viewport B may simply just copy the contents of Viewport A into Viewport B (e.g. for simulating the game of life). While for other effects (e.g. blur) you may apply your effect in both Viewports.

This is the approach you will find used in all OpenGL programs prior to the introduction of general purpose compute.

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

Unfortunately this approach does not seem to be well supported in Godot either:

Screenshot 2021-01-25 at 22 18 43

Produces an error from the first Renderer

Screenshot 2021-01-25 at 22 18 56

However the project happily runs under these conditions, and works in the HTML Export also (with some visual bugs)

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

It seems like Godot was not happy with the Viewport being picked from the Sprite's Texture drop-down menu.
I loaded the Texture from code and no more warnings, however this seems like another bug.

A third bug I seem to have run into is that the Clear color of the main Godot screen does not support alpha blending. If you set a clear color with vec4(1.0, 0.0, 0.0, 0.0) it will still render as Red.

@tavurth
Copy link
Author

tavurth commented Jan 25, 2021

I will submit these as bug reports in time after I've tested a bit more.
For now I will mark this as closed since I was going about it wrong.

The demo is updated here:
https://tavurth.itch.io/godot-gpu-game-of-life

Thanks for your help @clayjohn @Faless!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants