Terrain pass now ports the SAGE water model (Ocean.fx / OpenSAGE Water.frag): a de-gridded procedural wave normal combined with the retail ra3_deepocean flow and ra3_deepocean_nrm bump maps (appended as the last two terrain-atlas layers, no new backend binding), Schlick fresnel, sky reflection + depth-graded refraction, SAGE diffuse/specular lighting, depth-based transparency, and an underwater tint (UnderwaterDeferred.fx). Mirrored across terrain.frag / dx_terrain.hlsl / webgl_terrain_frag.glsl / webgpu_terrain.wgsl.
Also: logs move to the per-user state dir (%LOCALAPPDATA%\\OpenRA3\\logs, else XDG) and archive as openra3.<stamp>.log; the FPS label shows the active backend; middle-drag camera reset; objects and roads below the water plane are culled.
- ra3.map: capture the object RoadType; ra3.models pairs the map's
Start/End road objects and drapes a flat textured ribbon along each
segment (tessellated to the relief).
- Ground decals (roads/sidewalks) get a per-vertex screen-space depth
offset (scene::vertex.bias) applied in the object shader and the
software rasteriser, so they no longer z-fight or clip into the
terrain at top-down angles.
- Tactical view aligned with retail (SAGE LookAtTranslator): middle-drag
orbits yaw/pitch, a middle click resets angle/pitch/zoom, arrow keys
pan, wheel zooms within the retail zoom range; WASD pan removed and
left-drag no longer rotates.
- ui_event gains middle/right/released buttons; Vulkan + SDL map them.
- docs: roads, depth bias and camera controls.
Read the buildings and props a map places from its compiled art (the
uncompressed worldbuilder stream + embedded DDS textures):
- ra3.models: BAB asset-stream parser (lazy slices), W3DMesh + D3DHierarchy
decode, DDS (DXT1/3/5 + uncompressed) decode, per-mesh bone remap and
bind-pose single-joint skinning, flattened to one world-space triangle soup.
- ra3.map: parse the ObjectsList chunk into (type, x, y, z, angle).
- ra3.terrain: render3d rasterises the scene over the raymarched terrain with
a z-buffer; gpu_terrain carries the scene for the GPU backends.
- ra3.vulkan: second pipeline + depth attachment, terrain.frag writes
gl_FragDepth, and a small depth bias keeps ground decals from z-fighting.
- objects.fx shaders (compiled to SPIR-V), embedded like scene/terrain.
Only opaque parts are drawn: FX-light billboards (DefaultW3D.fx / BasicW3D.fx)
and damage-fill shells (BuildingsGenericDamageFill.fx) are skipped, since the
latter paint the wrecked interior (e.g. orange CBBuilding_Wood) over the shell.
Ground-decal meshes with no diffuse role and the Road templates themselves are
still not drawn.