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

HTML WebGL support #502

Open
TokisanGames opened this issue Sep 28, 2024 · 10 comments
Open

HTML WebGL support #502

TokisanGames opened this issue Sep 28, 2024 · 10 comments
Labels
bug Something isn't working building Related to compiling or packaging
Milestone

Comments

@TokisanGames
Copy link
Owner

TokisanGames commented Sep 28, 2024

Description

#500 brings support for the compatibility renderer. However, we haven't been successful getting an HTML export working. It's unclear if this is due to our process, or bugs in Terrain3D or Godot.

Here is the process so far.

A key point is that the terrain build, the export template, and export settings need to match the same thread support. All three marked on or off.

Docs

Building instructions
https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_for_web.html

Godot Export for web docs
https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html

Building

To build the extension for web you must install emscripten, set up the build environment, then build the web assembly version. I installed with scoop, which is how my python is also installed, per the Godot building instructions.

Emscripten seems to be very finicky about versions. Akien reports they are using v3.1.64 for 4.3 stable builds.

$ scoop install [email protected]

# then I restarted my terminal to get the updated path to finish installing emscripten

$ emsdk install 3.1.64
$ emsdk activate 3.1.64

# finally setup the build environment
$ source ~/scoop/apps/emscripten/current/emsdk_env.sh

# build
$ scons platform=web target=template_debug threads=no

$ ls project/addons/terrain_3d/bin/*.wasm
project/addons/terrain_3d/bin/libterrain.web.debug.wasm32.wasm

This file needs to be added to terrain.gdextension

web = "res://addons/terrain_3d/bin/libterrain.web.debug.wasm32.wasm"

These are also untested possibilities:

web.debug = "res://addons/terrain_3d/bin/libterrain.web.debug.wasm32.wasm"
web.release = "res://addons/terrain_3d/bin/libterrain.web.release.wasm32.wasm"

web.wasm32.nothreads = "res://addons/terrain_3d/bin/libterrain.web.debug.wasm32.nothreads.wasm"
web.debug = "res://addons/terrain_3d/bin/libterrain.web.debug.wasm32.wasm"

Exporting

  • Select custom template debug: web_dlink_nothreads_debug.zip, which I found here: C:/Users/Cory/AppData/Roaming/Godot/export_templates/4.3.stable/web_dlink_nothreads_debug.zip
  • Enable Extensions Support
  • Ensure Threads Support is disabled to match the other settings
  • Vram compressed textures don't work for me on Edge. They don't load in the log. They stop complaining with VRam uncompressed.

Upload to Webserver

After export, the full package must be uploaded to a webserver. Itch or your own. That server must be configured with SharedArrayBuffer & Cross Origin Isolation.
In nginx this can be enabled with:

    location ^~ /terrain3d/ {
        add_header "Cross-Origin-Opener-Policy" "same-origin";
        add_header "Cross-Origin-Embedder-Policy" "require-corp";
    }

On Itch.io , edit game, find the Embed Options section and enable:

SharedArrayBuffer support - (Experimental) This may break parts of the page or your project. Only enable if you know you need it.

Running

I built w/ 4.2.2 and seemed to mostly load but error messages complained that my scene files were built for 4.3?? So I built and exported everything with 4.3: godot source, godot-cpp, Godot binary, Godot export templates.

Edge complained about being unable to load the textures if compressed with vram compressed. But no complains using vram uncompressed.

Currently it loads to the godot logo, then our demo scene w/ player and blue sky, but the terrain doesn't render and has no collision.


Errors & Solutions

Uncaught (in promise) LinkError: WebAssembly.instantiate(): Import #0 "env" "memory": mismatch in shared state of memory, declared = 1, imported = 0

This is a mismatch of thread options: godotengine/godot#94537
Ensure all builds and settings are set to not threaded (or all threaded, untested).

@TokisanGames TokisanGames added bug Something isn't working building Related to compiling or packaging labels Sep 28, 2024
@TokisanGames TokisanGames added this to the Beta 0.9.x milestone Sep 28, 2024
@Xtarsia
Copy link
Contributor

Xtarsia commented Sep 28, 2024

for refrence, this project is a working example of GDextension exported to web, and is under MIT

https://github.com/kiwijuice56/sand-slide - working example in chrome browser in itch.io too!

@TokisanGames
Copy link
Owner Author

TokisanGames commented Sep 28, 2024

Ok, I have the demo scene building and loading. Updated instructions in Op.

However there are three problems:

  • The mouse isn't captured, so the camera doesn't move (but the mouse wheel does work)
  • Terrain collision doesn't work. But it works on the tunnel.
  • The terrain doesn't render. The console reports a problem with shader compilation:
 USER ERROR: SceneShaderGLES3: Vertex shader compilation failed:
 ERROR: 0:460: 'usampler2DArray' : No precision specified
 WARNING: 0:718: '/' : Zero divided by zero during constant folding generated NaN
 
    at: _display_error_with_code (drivers/gles3/shader_gles3.cpp:254)
 USER ERROR: Method/function failed.
    at: _compile_specialization (drivers/gles3/shader_gles3.cpp:348)

@TokisanGames
Copy link
Owner Author

New url. Back tick ` will also capture the mouse, and arrow keys will turn the camera.
https://tokisan.com/terrain3d_demo/demo.html

It seems that all the samplers need highp. Including those in uniforms.glsl.

Here's the full console log, after adding additional highps:
console_log.txt

The last remaining shader error is:

demo.js:474  ERROR: 0:528: '[' : array index for samplers must be constant integral expressions
also 535, 536.

These lines are:

demo.js:459 528: 			vec2 m_decal_uv=(((vec2(((m_cosa * m_uv.x) - (m_sina * m_uv.y)), ((m_sina * m_uv.x) + (m_cosa * m_uv.y))) - (vec2(((m_cosa * m_dus_editor_decal_position[m_i].x) - (m_sina * m_dus_editor_decal_position[m_i].y)), ((m_sina * m_dus_editor_decal_position[m_i].x) + (m_cosa * m_dus_editor_decal_position[m_i].y))) * m_dus_vertex_density)) * m_size) * m_dus_vertex_spacing);

demo.js:459 535: 			float m_decal=smoothstep(0.10000000149012, 1.0, texture(m_dus_editor_decal[m_i], (m_decal_uv + 0.5)).r);
demo.js:459 536: 			m_albedo=mix(m_albedo, m_dus_editor_decal_color[m_i].rgb, (m_decal * m_dus_editor_decal_color[m_i].a));

I'm not sure why webgl doesn't like these array indices compared to our other array indices.

texture(m_dus_editor_decal[m_i], (m_decal_uv + 0.5)).r`

I think this should be texture(_editor_decal, vec3(decal_uv + 0.5, float(i))). In my own custom shader, accessing an array index this way was working, but when I put this into the glsl file and compiled, Godot reports this in the desktop. Didn't try webgl yet:
SHADER ERROR: Invalid arguments for the built-in function: "texture(sampler2D[3],vec3)".

@TokisanGames
Copy link
Owner Author

Alright, next error is 256 instances of this before it stops:

GL_INVALID_OPERATION: Mismatch between texture format and sampler type (signed/unsigned/float/shadow).
WebGL: too many errors, no more errors will be reported to the console for this context.

I changed controlmap to sampler2DArray and put in floatBitsToUint() around the calls. However that didn't fix it or change the number of errors. I don't have any shader dumps or identification as to what line it doesn't like.

@Xtarsia
Copy link
Contributor

Xtarsia commented Sep 29, 2024

did you catch all 5 instances of the control map reads?

@TokisanGames
Copy link
Owner Author

No, I have 7 instances. 5 in main, 1 editor functions, 1 debug views. Worked on desktop.

@Xtarsia
Copy link
Contributor

Xtarsia commented Sep 29, 2024

theres actually a few more in debug views now you mention that, but those shouldnt cause problems unless they are on.

@TokisanGames
Copy link
Owner Author

TokisanGames commented Oct 3, 2024

I have it rendering something now.

https://tokisan.com/terrain3d_demo/demo.html

{A5AE0F17-FE72-4E99-95EB-C272633D455C}

This is using the minimum shader with a gradient color applied.

Albedo is only blue. These grey spots appear only near the camera, and they are usually constantly moving around, even when the camera is still. But at some angles they are still.

Removing source_color from the mouse depth didn't help

Just highp with a usampler didn't work. This needed highp and sampler/floatbitstouint.

Holes work surprisingly. I thought it complained about dividing by 0 before, but it doesn't care about it now.

Here's my working minimum.txt shader.

This full_shader.txt produces the errors noted above.

@TokisanGames
Copy link
Owner Author

image

This version of the full shader works. working_shader.txt

@TokisanGames
Copy link
Owner Author

TokisanGames commented Oct 5, 2024

#512 has a working web build.
On Chrome I get 45-60fps, no artifacts.
On Edge I got 1fps no artifacts. I restarted it and got what I got before, 45-60fps with grey artifacts.

@TokisanGames TokisanGames modified the milestones: 0.9, 1.0 Oct 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working building Related to compiling or packaging
Projects
Status: In Progress
Development

No branches or pull requests

2 participants