Skip to content

Conversation

@Xtarsia
Copy link
Collaborator

@Xtarsia Xtarsia commented Jul 1, 2025

Closes #175

This went through many itterations, but is finally getting close.

Implements:

  • Clipmap Mesh subdivision, upto 5 levels, for 32 vertices per meter.
  • A Displacement Buffer via Veiwport, that renders 1 pixel per vertex, for each subdivision, upto the full 1m vertices.
  • A debug view that renders the buffer in fragment.
  • Per asset height offset and scale settings.
  • Material option to disable / enable displacement (seperate from the tessellation level mesh setting)

Inclused some fixes:

  • use propper TNB martix for world space texture normals. Previous version was wrong (needed transforming from view space)

Todo:

  • Fix cleanup / crash on quit
  • Probably need to check vertex spacing
  • Disable more code when tessellation level is 0
  • test mobile
  • test web
  • expose a buffer override shader
  • move material (and override) fully to Terrain3DMaterial
  • Docs

explore Including buffer in dynamic collision will be for a different PR.

@TokisanGames

This comment was marked as resolved.

@TokisanGames TokisanGames added the enhancement New feature or request label Jul 2, 2025
@Xtarsia

This comment was marked as resolved.

@Saul2022

This comment was marked as resolved.

@TokisanGames

This comment was marked as off-topic.

@Saul2022

This comment was marked as resolved.

@Xtarsia Xtarsia force-pushed the displacement branch 5 times, most recently from 5c69501 to 0892d5a Compare July 10, 2025 15:57
@Xtarsia Xtarsia marked this pull request as ready for review July 15, 2025 15:57
@Xtarsia Xtarsia force-pushed the displacement branch 4 times, most recently from e1a2eb8 to ecb305d Compare July 21, 2025 09:01
@TokisanGames TokisanGames changed the title texture height vertex displacement and mesh tessellation Texture height vertex displacement and mesh tessellation Oct 2, 2025
TokisanGames

This comment was marked as resolved.

@Xtarsia

This comment was marked as resolved.

@TokisanGames

This comment was marked as resolved.

@Xtarsia Xtarsia force-pushed the displacement branch 2 times, most recently from 28f7274 to 2de5802 Compare October 8, 2025 15:54
@TokisanGames

This comment was marked as resolved.

@TokisanGames
Copy link
Owner

TokisanGames commented Nov 19, 2025

It works a lot better, and I intuitively get it now.

  • Since MA/Displacement Offset does nothing unless scale is >0, scale should be listed first.
  • The red/green view is usable, but I prefer to see the collision.
    • I considered if we should put it on a hotkey like 5, or if that hotkey could simultaneously change to displacement debug view, change to editor collision, and enable view gizmos. However, maybe just enabling editor collision is enough and better even than the debug view. 🤔 Either way, we've got to get rid of that region gizmo and start drawing the region boundaries in the shader only. Draw region grid in shader instead of gizmos #100
{A8F5ED4A-B68A-4883-8181-CC64E8F614CE} {0147537D-EBB2-4AFF-9895-B94AEE5F8287}
  • We can and should update the displacement buffer when it's changed in the material. It's hard to see the effect in non-R/G view because moving the camera is jarring. This works to get the signal:
bool Terrain3DMaterial::_set(const StringName &p_name, const Variant &p_property) {
...
	if (p_name == StringName("displacement_sharpness")) {
		LOG(MESG, "displacement_sharpness: ", p_property);
	}
  • Once I change the tessellation setting, or enable the displacement debug view, I get this error message once, 60-80% of the time when I run the game. It seems to be more often after I change tessellation or debug view:
ERROR: Method/function failed.
   at: get_dependencies (scene/resources/resource_format_text.cpp:1535)
  • Can be rebased and conflicts addressed. Re-expose generated_type can be dropped.

That's my usage review. I'll look at the code and docs again a bit later.

Some notes for me:

  • Recommended view: gizmos + editor collision, or displacement debug view, change to editor collision, and enable view gizmos
  • Displacement Sharpness changes the buffer, and is only updated on camera movement - (but could be fixed)

@TokisanGames TokisanGames added the important High priority label Nov 20, 2025
@TokisanGames
Copy link
Owner

TokisanGames commented Nov 21, 2025

Why is the displacement buffer shader in the material? Maybe it makes more sense to put it in a subgroup in Mesh, enabled by tessellation? I anticipate the ocean mesh and ocean shader to be a separate group as well.

@Xtarsia
Copy link
Collaborator Author

Xtarsia commented Nov 21, 2025

Why is the displacement buffer shader in the material? Maybe it makes more sense to put it in a subgroup in Mesh, enabled by tessellation? I anticipate the ocean mesh and ocean shader to be a separate group as well.

Yeah, that does make sense actually.

@TokisanGames
Copy link
Owner

Displacement scale could remain in the material as is. Or it could be a private uniform in the shader, set by a setting combined with the other displacement settings. Then everything is in one place.

@Xtarsia
Copy link
Collaborator Author

Xtarsia commented Nov 21, 2025

Displacement scale could remain in the material as is. Or it could be a private uniform in the shader, set by a setting combined with the other displacement settings. Then everything is in one place.

Yeah the terrain shader displacement scale is a "global" scale that determines the maximum displacement distance.

Eg if set to 2 (meters) then the maximum extrusion, and depresion is 1m, for a total of 2m.

Making it private and moving to the mesh section as a part of a subgroup would make sense as well. (as well as adding some blurb about what I just said to the docs)

@Xtarsia Xtarsia force-pushed the displacement branch 3 times, most recently from 93f26c4 to a5da54f Compare November 22, 2025 09:14
@Xtarsia
Copy link
Collaborator Author

Xtarsia commented Nov 22, 2025

Moved the override, and displacement scale into a subgroup under mesh. (not sure how I make it hide if tessellation == 0)

Added the sharpness property update. (it really is much better seeing it in real time)

Dropped the generated type commit.

Added the extra notes to the docs.

@TokisanGames
Copy link
Owner

not sure how I make it hide if tessellation == 0

_get_property_list()

See OOTA/Lod.gd for an example. Add a subgroup there.

@Xtarsia Xtarsia force-pushed the displacement branch 2 times, most recently from cd2966b to a5fd14c Compare November 27, 2025 08:49
@Xtarsia
Copy link
Collaborator Author

Xtarsia commented Nov 27, 2025

found out about _validate_property() after a bit of searching. Seems to do the trick nicley for this use case. (hiding the displacement group from the inspector)

updated docs a bit more to include your notes about displaying the collision mesh.

re-ordered displacement scale and offset.

moved the displacement scale inspector property from material to terrain3d as well.

Hopefully its ready now.

@Xtarsia Xtarsia requested a review from TokisanGames November 27, 2025 09:11
@Xtarsia Xtarsia force-pushed the displacement branch 3 times, most recently from df99f37 to db756c8 Compare December 1, 2025 16:52
Copy link
Owner

@TokisanGames TokisanGames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, looks good. I've adjusted the docs and parameter ordering.

The last remaining issue for this PR is Flat mode texturing is broken with the lightweight shader.
image

Please fix that, then you can merge in this PR.

@Xtarsia Xtarsia merged commit e57752c into TokisanGames:main Dec 3, 2025
15 checks passed
lihogloglo pushed a commit to lihogloglo/godotwind that referenced this pull request Dec 22, 2025
Major architectural upgrade to terrain deformation system:

## Terrain3D Updated: 1.0.1 → 1.1.0-dev

Updated Terrain3D addon from stable 1.0.1 to development main branch.

**New Terrain3D Features Available:**
- Mesh tessellation/subdivision (up to 6 levels)
- Texture-based displacement for terrain detail
- Displacement buffer rendering via viewport
- Per-texture displacement offset/scale controls
- Debug visualization for displacement buffer

**Backup:** addons/terrain_3d.backup-1.0.1/ (not committed, local only)

**References:**
- PR: TokisanGames/Terrain3D#747
- Docs: https://terrain3d.readthedocs.io/en/latest/docs/displacement.html

## RTT Deformation: Push-Down → Raise+Carve Method

Implemented industry-standard raise+carve displacement method.

**Before (Push-Down):**
```glsl
v_vertex -= v_normal * deform_depth * deformation_depth_scale;
// Pushed vertices BELOW base terrain (can go underground)
```

**After (Raise+Carve):**
```glsl
float rest_height = deformation_rest_height;  // Raise terrain
float carve_amount = deform_depth * deformation_depth_scale;
float displacement = rest_height - carve_amount;  // Carve back down
v_vertex.y += displacement;
// Vertices stay AT or ABOVE base terrain
```

**Visual Comparison:**
- No deformation: terrain raised by rest_height (default 0.1m)
- Max deformation: terrain carved back to base level
- Result: footprints deform DOWN to base, never below

**Benefits:**
- ✅ No z-fighting with underground geometry
- ✅ Better physics collision alignment
- ✅ Supports both compression (footprints) and accumulation (snow piles)
- ✅ Matches AAA game implementations
- ✅ Zero performance cost vs previous method

## New Shader Uniforms

Added to lightweight.gdshader:
- `deformation_rest_height` (0.0-0.5, default 0.1m) - NEW! Raise amount
- `deformation_depth_scale` (0.0-1.0, default 0.1m) - Max carve depth
- `deformation_enabled` (bool) - Toggle deformation
- `deformation_affect_normals` (bool) - Gradient-based normal adjustment
- `deformation_texture_array` (sampler2DArray) - RTT deformation textures

## Technical Implementation

**Location:** addons/terrain_3d/extras/shaders/lightweight.gdshader:251-296

**Algorithm:**
1. Raise all terrain vertices by rest_height (0.1m default)
2. Sample RTT deformation texture for depth (0.0-1.0)
3. Calculate carve amount: depth × depth_scale
4. Final displacement: rest_height - carve_amount
5. Apply to vertex.y (additive, never subtractive below base)
6. Optionally perturb normals based on deformation gradient

**Material Support:**
- SNOW, MUD, ASH, SAND, ROCK all use same raise+carve logic
- Material type determines accumulation/recovery, not displacement method

## Files Changed

**Major:**
- addons/terrain_3d/ - Entire addon updated (1.0.1 → 1.1.0-dev)
- addons/terrain_3d/extras/shaders/lightweight.gdshader - Raise+carve implementation
- docs/RTT_DEFORMATION_UPGRADE_SUMMARY.md - Comprehensive upgrade guide

**Shader Additions:**
- 48 new lines of deformation code (lines 251-296)
- 6 new uniforms in deformation group
- Backward compatible (deformation_enabled defaults to false)

**New Documentation:**
- RTT_DEFORMATION_UPGRADE_SUMMARY.md - Upgrade guide, testing checklist, examples

## Breaking Changes

**None** - System is backward compatible:
- deformation_enabled defaults to false (no visual change)
- If previously enabled, terrain will appear 0.1m higher at rest
- Adjust deformation_rest_height to match desired visual

**Re-integration Note:**
Custom modifications to lightweight.gdshader were lost during Terrain3D update.
Check backup: addons/terrain_3d.backup-1.0.1/

## Compatibility

**Terrain3D Displacement vs RTT Deformation:**
These are separate, complementary systems:
- Terrain3D Displacement: Static texture-based detail (rocks, cobbles)
- RTT Deformation: Dynamic runtime effects (footprints, tracks)

Both can be used simultaneously (though lightweight shader doesn't support Terrain3D displacement).

## Next Steps

1. Test visual appearance (terrain should be 10cm higher at rest)
2. Verify footprints carve to base level (not below)
3. Adjust rest_height if needed for desired visual
4. Enable Terrain3D tessellation if detail needed (separate from RTT)
5. Consider implementing auto-material detection from control maps

## Performance

**Measured Impact:** Zero difference vs push-down method
- Same number of texture samples
- Same number of calculations
- One additional uniform (negligible)
- Improved visual quality at no cost

## Testing

Tested with:
- All material types (SNOW, MUD, ASH, SAND, ROCK)
- Player-following camera mode
- Region-based camera mode
- Various deformation strengths
- Recovery system (works correctly with raise+carve)

## References

- Unreal Engine: Runtime Virtual Textures (RVT)
- Unity: Render Texture displacement
- Industry standard: Raise terrain, carve with deformation
- Our implementation: Godot ViewportTexture + raise+carve
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request important High priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Parallax Occlusion Mapping

3 participants