TV10: Terrain Subsurface Materials
Epic TV10 from docs/plans/2026-03-16-terrain-viz-epics.md is implemented as a terrain-specific subsurface response for snow, ice, wet soil, and similar broad natural layers. The shipped path is a bounded in-shader approximation built around per-layer scatter strength/tint controls, wrap lighting, and a curvature-weighted diffusion estimate. It is intentionally terrain-first, not a full screen-space diffusion pipeline.
Shipped in forge3d 1.17.0.
What shipped
Public terrain controls:
MaterialLayerSettings.snow_subsurface_strengthMaterialLayerSettings.snow_subsurface_colorMaterialLayerSettings.rock_subsurface_strengthMaterialLayerSettings.rock_subsurface_colorMaterialLayerSettings.wetness_subsurface_strengthMaterialLayerSettings.wetness_subsurface_color
Native terrain config plumbing:
src/terrain/render_params/decode_materials.rssrc/terrain/render_params/native_material.rs
GPU uniform wiring:
src/terrain/renderer/uniforms.rssrc/terrain/renderer/bind_groups/terrain_pass.rs
Terrain shader integration:
src/shaders/terrain_pbr_pom.wgslper-layer weight evaluation now feeds a terrain subsurface state
the beauty path adds a bounded subsurface contribution based on wrap lighting, view/light alignment, and derivative-based diffusion
Real-DEM example coverage:
examples/terrain_tv10_subsurface_demo.pyrenders Mount Rainier and Gore Range from repo DEM assets
Regression coverage:
tests/test_terrain_materials.pytests/test_terrain_tv10_subsurface.pytests/test_terrain_tv10_goldens.pytests/test_terrain_tv10_demo.py
Public API
import forge3d as f3d
from forge3d.terrain_params import MaterialLayerSettings, make_terrain_params_config
config = make_terrain_params_config(
size_px=(1280, 720),
terrain_span=2400.0,
z_scale=1.4,
cam_radius=3200.0,
cam_phi_deg=144.0,
cam_theta_deg=48.0,
materials=MaterialLayerSettings(
snow_enabled=True,
snow_altitude_min=1800.0,
snow_altitude_blend=650.0,
snow_slope_max=58.0,
snow_slope_blend=18.0,
rock_enabled=True,
rock_slope_min=36.0,
rock_slope_blend=10.0,
wetness_enabled=True,
wetness_strength=0.18,
wetness_slope_influence=0.45,
snow_subsurface_strength=0.58,
snow_subsurface_color=(0.72, 0.85, 0.98),
rock_subsurface_strength=0.04,
rock_subsurface_color=(0.45, 0.38, 0.30),
wetness_subsurface_strength=0.16,
wetness_subsurface_color=(0.38, 0.27, 0.18),
),
)
params = f3d.TerrainRenderParams(config)
Workflow notes
Defaults stay backward-compatible at the scene level because all terrain material layers remain disabled by default.
Snow defaults now carry a non-zero terrain subsurface response:
snow_subsurface_strength = 0.35snow_subsurface_color = (0.78, 0.88, 0.98)
Rock defaults stay neutral:
rock_subsurface_strength = 0.0
Wetness defaults carry a mild warm fill:
wetness_subsurface_strength = 0.12wetness_subsurface_color = (0.40, 0.28, 0.18)
Setting all
*_subsurface_strengthvalues to0.0restores the pre-TV10 terrain response.*_subsurface_coloris a scatter tint, not an albedo override.The terrain SSS path is additive and bounded. It does not add a new full-screen post-process or a generic character-material pipeline.
The approximation is most visible on low-angle lighting over snow/ice or damp terrain where the layer weights already dominate.
Example output
examples/terrain_tv10_subsurface_demo.py writes:
mount_rainier_baseline.pngmount_rainier_subsurface.pngmount_rainier_comparison.pnggore_range_baseline.pnggore_range_subsurface.pnggore_range_comparison.pngterrain_tv10_summary.png
The bundled demo uses two real repo DEM assets so the effect is validated on representative terrain rather than only synthetic fixtures.
Regression contract
Explicit zero-strength SSS matches the pre-TV10 baseline image contract.
Two dedicated SSS scenes are locked with goldens:
tests/golden/terrain/terrain_tv10_scene_a_sss.pngtests/golden/terrain/terrain_tv10_scene_b_sss.png
The zero-strength baseline is locked separately:
tests/golden/terrain/terrain_tv10_zero_sss.png
Example and tests
Example:
examples/terrain_tv10_subsurface_demo.pyConfig/API tests:
tests/test_terrain_materials.pyRuntime render tests:
tests/test_terrain_tv10_subsurface.pyGolden-image tests:
tests/test_terrain_tv10_goldens.pyReal-DEM example test:
tests/test_terrain_tv10_demo.py