Skip to content

Commit

Permalink
Add web workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
TokisanGames committed Dec 27, 2024
1 parent d1c1d6e commit 177a39e
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 31 deletions.
19 changes: 19 additions & 0 deletions .github/actions/web-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Setup Base Dependencies
description: Setup Emscripten
runs:
using: "composite"
steps:
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v14
env:
EM_VERSION: 3.1.64
EM_CACHE_FOLDER: emsdk-cache
with:
version: ${{ env.EM_VERSION }}
actions-cache-folder: ${{ env.EM_CACHE_FOLDER }}
cache-key: emsdk-${{ matrix.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}

- name: Verify Emscripten setup
shell: bash
run: |
emcc -v
32 changes: 19 additions & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ jobs:
- identifier: linux
platform: linux
name: 🐧 Linux
runner: ubuntu-20.04
runner: ubuntu-latest
arch: x86_64

- identifier: windows
platform: windows
name: 🪟 Windows
runner: ubuntu-20.04
runner: ubuntu-latest
arch: x86_64

- identifier: macos
Expand All @@ -44,17 +44,17 @@ jobs:
runner: macos-latest
arch: universal

- identifier: android-arm64
- identifier: android
platform: android
name: 🤖 Android Arm64
runner: ubuntu-20.04
arch: arm64
name: 🤖 Android Arm
runner: ubuntu-latest
arch: [arm64, arm32]

- identifier: android-arm32
platform: android
name: 🤖 Android Arm32
runner: ubuntu-20.04
arch: arm32
- identifier: web
platform: web
name: 🌐 Web
runner: ubuntu-latest
threads: [yes, no]

steps:
- name: Checkout Terrain3D
Expand All @@ -73,6 +73,10 @@ jobs:
ndk-version: r23c
link-to-sdk: true

- name: Setup Web Dependencies
if: ${{ matrix.platform == 'web' }}
uses: ./.github/actions/web-deps

- name: Setup Base Dependencies
uses: ./.github/actions/base-deps

Expand All @@ -84,12 +88,14 @@ jobs:

- name: Build Terrain3D
env:
if: ${{ matrix.platform != 'web' }}
SCONS_CACHE: "${{ github.workspace }}/.scons-cache/"
TARGET: 'template_${{ matrix.target }}'
ARCH: '${{ matrix.arch }}'
ARCH: 'arch=${{ matrix.arch }}'
THREADS: 'threads=${{ matrix.threads }}'
shell: sh
run: |
scons target=$TARGET platform='${{ matrix.platform }}' arch=$ARCH debug_symbols=no -j2
scons target=$TARGET platform='${{ matrix.platform }}' $ARCH $THREADS debug_symbols=no -j2
- name: Strip Libraries (Windows/Linux)
if: ${{ matrix.platform == 'windows' || matrix.platform == 'linux' }}
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/web.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: 🌐 Web Builds
on: [ push, workflow_call, workflow_dispatch ]

jobs:
build:
name: 🌐 Web ${{ matrix.arch }} ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [web]
target: [debug, release]
threads: [no]
#threads: [yes, no]

steps:
- name: Checkout Terrain3D
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Web Dependencies
if: ${{ matrix.platform == 'web' }}
uses: ./.github/actions/web-deps

- name: Setup Base Dependencies
uses: ./.github/actions/base-deps

# - name: Setup Build Cache
# uses: ./.github/actions/build-cache
# with:
# cache-name: ${{ matrix.platform }}-${{ matrix.target }}-${{ matrix.threads }}
# continue-on-error: true

- name: Setup Build Cache
uses: ./.github/actions/build-cache
with:
cache-name: ${{ matrix.identifier }}-${{ matrix.target }}
continue-on-error: true

- name: Build Terrain3D
env:
SCONS_CACHE: "${{ github.workspace }}/.scons-cache/"
TARGET: 'template_${{ matrix.target }}'
shell: sh
run: |
scons target=$TARGET platform='${{ matrix.platform }}' threads='${{ matrix.threads }}' debug_symbols=no -j2
- name: Prepare Files
shell: sh
run: |
ls -l project/addons/terrain_3d/bin/
cp '${{ github.workspace }}/README.md' '${{ github.workspace }}/LICENSE.txt' ${{ github.workspace }}/project/addons/terrain_3d/
- name: Upload Package
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: t3d-${{ matrix.platform }}-${{ matrix.target }}
path: |
${{ github.workspace }}/project/
merge:
runs-on: ubuntu-latest
needs: build
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
include-hidden-files: true
name: ${{ github.event.repository.name }}
pattern: t3d-*
delete-merged: true
2 changes: 2 additions & 0 deletions Terrain3D.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
<ItemGroup>
<None Include=".github\actions\base-deps\action.yml" />
<None Include=".github\actions\build-cache\action.yml" />
<None Include=".github\actions\web-deps\action.yml" />
<None Include=".github\actions\windows-deps\action.yml" />
<None Include=".github\ISSUE_TEMPLATE\bug_report.yml" />
<None Include=".github\ISSUE_TEMPLATE\config.yml" />
Expand All @@ -183,6 +184,7 @@
<None Include=".github\workflows\ios.yml" />
<None Include=".github\workflows\linux.yml" />
<None Include=".github\workflows\macos.yml" />
<None Include=".github\workflows\web.yml" />
<None Include=".github\workflows\windows.yml" />
<None Include=".gitignore" />
<None Include="AUTHORS.md" />
Expand Down
3 changes: 3 additions & 0 deletions Terrain3D.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@
<None Include="doc\docs\introduction.md">
<Filter>2. Docs</Filter>
</None>
<None Include=".github\workflows\web.yml">
<Filter>1. Project Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include=".readthedocs.yaml">
Expand Down
26 changes: 14 additions & 12 deletions doc/docs/collision.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
Collision
=======================

One of the most important things about a terrain is knowing where it is. Terrain3D provides several methods for detecting terrain height.
One of the most important things about a terrain is knowing where it is. Using physics based collision is not the only way, nor even the best or fastest way. There are at least 5 ways to detect terrain height: Physics based raycasting on collision, raymarching, the GPU depth texture, get_height(), and reading the heightmap directly.

You should use raycasting only when you don't already know the X, Z of the collision point (eg not vertical).

Using collision is not the only way, nor even the best or fastest way. But we'll start with it as it is the most common.

## Physics Based Collision & Raycasting

Collision is generated at runtime using the physics server. Regular PhysicsBodies will interact with this collision as expected. To detect ground height, use a [ray cast](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html). However, outside of regions, there is no collision, so raycasts won't hit.
Collision is generated at runtime using the physics server. Regular PhysicsBodies will interact with this collision as expected. To detect ground height, use a [ray cast](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html). There is no collision outside of regions, so raycasts won't hit.

Normally the editor doesn't generate collision, but some addons or other activities do need editor collision. To generate it, enable `Terrain3D/Collision/Collision Mode`, or set `Terrain3D.collision_mode`. Set this to `Full / Editor`. You can run in game with this enabled.
Normally the editor doesn't generate collision, but some addons or other activities do need editor collision. To generate it, set `Terrain3D/Collision/Collision Mode`, or `Terrain3D.collision_mode`, to `Full / Editor`. You can run in game with this enabled.

This editor option will generate collision one time when enabled or at startup. If the terrain is sculpted afterwards, this collision will be inaccurate to the visual mesh until collision is disabled and enabled again. On a Core-i9 12900H, generating collision takes about 145ms per 1024m region, so updating it several times per second while sculpting is not practical. Currently all regions are regenerated, rather than only modified regions so it is not optimal. You can follow [PR#278](https://github.com/TokisanGames/Terrain3D/pull/278) for an improved system.
This option will generate collision one time when enabled or at startup. If the terrain is sculpted afterwards, this collision will be inaccurate to the visual mesh until collision is disabled and enabled again. On a Core-i9 12900H, generating collision takes about 145ms per 1024m region, so updating it several times per second while sculpting is not practical. Currently all regions are regenerated, rather than only modified regions so it is not optimal. You can follow [PR#278](https://github.com/TokisanGames/Terrain3D/pull/278) for an improved system.

See the [Terrain3D API](../api/class_terrain3d.rst) for various functions that configure the collision priority, layers, and mask.

## Raycasting Without Physics
Finally, Godot Physics is far from perfect. If you have issues with raycasts or other physics calculations, try switching to Jolt. Also if your raycast is perfectly vertical, you can try angling it ever so slightly, or use get_height().

It is possible to cast a ray from any position and any direction and detect the collision point on the terrain using the GPU instead of the physics engine.

Sending the source point and ray direction to [Terrain3D.get_intersection()](../api/class_terrain3d.rst#class-terrain3d-method-get-intersection) will return the intersection point on success.
## Raycasting Without Physics

It is possible to cast a ray from any position and direction to detect the collision point on the terrain without using the physics engine. We have two methods for that: raymarching and using the GPU.

Being GPU based, this function works outside of regions.
Sending the source point and ray direction to [Terrain3D.get_intersection()](../api/class_terrain3d.rst#class-terrain3d-method-get-intersection) will return the intersection point. This function has two modes:

This function works fine if called *only once per frame*, such as for a mouse pointer detecting terrain position. More than once per frame will produce conflicts.
In raymarching mode it iterates over get_height() until an intersection is reached. This only works within regions, and is a bit heavy compared to the other modes.

You can review [editor.gd](https://github.com/TokisanGames/Terrain3D/blob/v0.9.1-beta/project/addons/terrain_3d/editor/editor.gd#L129-L143) to see an example of projecting the mouse position onto the terrain using this function.
In GPU mode, it "looks" at the terrain using the GPU depth texture. This works outside of regions, even on the WorldNoise. However there are caveats. It returns values for the previous frame, so can only used continuously or used with `await`, and no more than once per frame.

Use it only when you don't already know the X, Z collision point.
Be sure to read the link above to understand all caveats. Review [editor_plugin.gd](https://github.com/TokisanGames/Terrain3D/blob/main/project/addons/terrain_3d/src/editor_plugin.gd#L184-L188) to see an example of using this function to project the mouse position onto the terrain.


## Query Height At Any Position
Expand Down
7 changes: 2 additions & 5 deletions doc/docs/platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,7 @@ Further reading:

## WebGL

The Terrain3D library can be exported to WebGL, however the terrain will not currently render. It requires the [Compatibility Renderer (read more)](#compatibility), which is now supported, and but there are some additional shader elements that need to be sorted out before it will work.

Further reading:
* [Issue 502](https://github.com/TokisanGames/Terrain3D/issues/502)
Web Exports are very experimental. We have a working test environment. It requires [Compatibility Renderer (read more)](#compatibility). See the progress and setup in [Issue 502](https://github.com/TokisanGames/Terrain3D/issues/502).


Supported Renderers
Expand Down Expand Up @@ -151,7 +148,7 @@ The OpenGLES 3.0 Compatibility renderer is mostly supported from Terrain3D 0.9.3

`Godot_v4.3-stable_win64_console.exe --rendering-driver opengl3 -e project.godot --terrain3d-renderer=compatibility`

* Textures that are imported with `VRAM Compressed` are forced uncompressed and a warning issued. You can disable the warning by manually selecting `VRAM Uncompressed` or `Lossless` on the Import tab and reimport for all of your textures. Compression seems to be fixed in 4.4.
* Textures that are imported with `VRAM Compressed` are forced uncompressed and a warning issued. You can disable the warning by manually selecting `VRAM Uncompressed` or `Lossless` on the Import tab and reimport for all of your textures. VRAM compression seems to be fixed in 4.4.

Further reading:

Expand Down
5 changes: 4 additions & 1 deletion project/addons/terrain_3d/terrain.gdextension
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ android.debug.arm64 = "res://addons/terrain_3d/bin/libterrain.android.debug.arm6
android.release.arm64 = "res://addons/terrain_3d/bin/libterrain.android.release.arm64.so"

ios.debug = "res://addons/terrain_3d/bin/libterrain.ios.debug.universal.dylib"
ios.release = "res://addons/terrain_3d/bin/libterrain.ios.release.universal.dylib"
ios.release = "res://addons/terrain_3d/bin/libterrain.ios.release.universal.dylib"

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

0 comments on commit 177a39e

Please sign in to comment.