Skip to content

feat: add water surface rendering with mesh generation and shaders#95

Merged
ViTeXFTW merged 2 commits intofeat/terrain-renderingfrom
claude/implement-water-rendering-hYFD0
Feb 23, 2026
Merged

feat: add water surface rendering with mesh generation and shaders#95
ViTeXFTW merged 2 commits intofeat/terrain-renderingfrom
claude/implement-water-rendering-hYFD0

Conversation

@ViTeXFTW
Copy link
Copy Markdown
Owner

Summary

This PR adds complete water surface rendering support to the engine, including mesh generation from map polygon triggers, GPU buffer management, and animated water shaders with scrolling UV effects.

Key Changes

Water Mesh Generation (src/render/water/water_mesh.hpp/cpp)

  • Coordinate transformation: triggerPointToWorld() converts map trigger coordinates to world space with proper scaling (MAP_XY_FACTOR for XZ, MAP_HEIGHT_SCALE for height)
  • Ear-clipping triangulation: earClipTriangulate() implements polygon triangulation supporting both convex and concave polygons, with automatic CCW winding correction
  • Polygon generation: generateWaterPolygon() converts PolygonTrigger data into flat water meshes with averaged height, computed bounds, and normalized texture coordinates
  • Batch processing: generateWaterMeshes() processes all water triggers from a map and computes total bounds

Water Renderable (src/render/water/water_renderable.hpp/cpp)

  • GPU buffer management for water polygons with staged uploads
  • Pipeline initialization with proper descriptor layout for UBO and texture sampling
  • INI-based water appearance settings (color, opacity, scroll rates, tiling)
  • Per-frame animation updates and descriptor management
  • Implements IRenderable interface for integration with the rendering system

Shaders

  • water.vert: Generates two layers of scrolling UV coordinates with perpendicular offset (70% speed) for cross-ripple effect
  • water.frag: Blends two texture samples and applies water color tinting with configurable opacity

Pipeline Configuration (src/lib/gfx/pipeline.hpp)

  • Added WaterPushConstant struct for time, scroll rates, color, and UV scale
  • Added PipelineCreateInfo::water() factory with proper vertex layout (position + texCoord), descriptor bindings, and alpha blending configuration

Testing (tests/water/test_water_mesh.cpp)

  • Comprehensive test suite (30+ tests) covering:
    • Coordinate transformation correctness
    • Triangulation for various polygon types (triangle, square, pentagon, hexagon)
    • Polygon generation with bounds, height, and texture coordinate validation
    • Batch mesh generation with filtering and bounds aggregation

Notable Implementation Details

  • Water surfaces are flattened to an averaged height for perfectly flat water
  • Texture coordinates are normalized by MAP_XY_FACTOR so one texel equals one map cell
  • Ear-clipping includes safety limits to prevent infinite loops on degenerate input
  • Alpha blending is enabled with depth writes disabled for proper water rendering over terrain
  • Secondary UV layer scrolls perpendicular at 70% speed to match original C&C Generals water appearance

https://claude.ai/code/session_015VJkdyPaCy7vByfWHZ17Zz

claude and others added 2 commits February 23, 2026 11:05
…peline, renderable)

Adds the full water surface rendering pipeline for map-based PolygonTrigger
water areas:

- src/render/water/water_mesh.hpp/.cpp: Polygon-to-GPU-mesh conversion using
  ear-clipping triangulation. Converts PolygonTrigger points (map cell coords)
  to world-space flat water surfaces. Generates UV coordinates for texture
  scrolling.

- src/render/water/water_renderable.hpp/.cpp: IRenderable implementation for
  water surfaces. Manages GPU buffers for all water polygons from a map file.
  Supports INI-driven water appearance (WaterSettings), per-frame time-based
  UV animation, and alpha-transparent rendering after terrain.

- shaders/water.vert/.frag: Two-layer scrolling UV water shader. Vertex shader
  outputs two UV sets at different scroll rates/directions for a cross-ripple
  effect. Fragment shader blends both samples and applies configurable opacity.

- src/lib/gfx/pipeline.hpp: Added WaterPushConstant (waterColor, time,
  uScrollRate, vScrollRate, uvScale) and PipelineCreateInfo::water() factory
  (alpha blend on, depth write off, two-sided, WaterVertex format).

- tests/water/test_water_mesh.cpp: 31 unit tests covering coordinate
  conversion, ear-clip triangulation (convex/concave, CW/CCW), polygon
  generation, bounding box correctness, and terrain-scale consistency.

https://claude.ai/code/session_015VJkdyPaCy7vByfWHZ17Zz
@ViTeXFTW
Copy link
Copy Markdown
Owner Author

@greptileai

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Feb 23, 2026

Greptile Summary

This PR implements complete water surface rendering for the Vulkan W3D viewer, converting map polygon triggers into triangulated meshes with animated dual-layer UV scrolling shaders.

Key accomplishments:

  • Robust ear-clipping triangulation supporting both convex and concave water polygons with automatic CCW winding correction
  • Proper coordinate transformation from map trigger space to world space using MAP_XY_FACTOR and MAP_HEIGHT_SCALE constants
  • GPU buffer management following project RAII patterns with proper resource cleanup
  • Dual-layer water shader achieving the classic C&C Generals cross-ripple appearance (perpendicular scrolling at 70% speed)
  • Alpha blending pipeline configuration with depth writes disabled for correct render order
  • Comprehensive test coverage (30+ tests) validating coordinate transforms, triangulation, and polygon generation
  • INI-based water appearance settings integration for color, opacity, and scroll rates

The implementation is production-ready with excellent code quality, following all project style guidelines from AGENTS.md and CLAUDE.md. No issues found.

Confidence Score: 5/5

  • This PR is safe to merge with no issues found
  • The implementation demonstrates excellent engineering: comprehensive test coverage validates all core functionality, proper RAII patterns prevent resource leaks, safety limits protect against degenerate input, coordinate transforms are mathematically correct and tested, and the code follows all project style guidelines. The PR is focused, well-documented, and production-ready.
  • No files require special attention

Important Files Changed

Filename Overview
src/render/water/water_mesh.cpp Solid implementation of ear-clipping triangulation and coordinate transforms with safety limits for degenerate polygons
src/render/water/water_renderable.cpp Clean GPU buffer management and descriptor updates, follows project patterns for Vulkan resource handling
shaders/water.vert Implements dual-layer UV scrolling for cross-ripple water effect matching C&C Generals appearance
shaders/water.frag Simple fragment shader blending two texture samples with configurable water color tint and opacity
src/lib/gfx/pipeline.hpp Added WaterPushConstant struct with proper alignment and water() factory with correct vertex layout and alpha blending
tests/water/test_water_mesh.cpp Comprehensive test suite (30+ tests) covering coordinate transforms, triangulation, polygon generation, and edge cases

Last reviewed commit: 806161d

@ViTeXFTW ViTeXFTW marked this pull request as ready for review February 23, 2026 12:47
@ViTeXFTW ViTeXFTW changed the base branch from claude/terrain-rendering-phase-3-dTd3F to feat/terrain-rendering February 23, 2026 12:50
@ViTeXFTW ViTeXFTW changed the title Add water surface rendering with mesh generation and shaders feat: add water surface rendering with mesh generation and shaders Feb 23, 2026
@ViTeXFTW ViTeXFTW merged commit 6d91e7a into feat/terrain-rendering Feb 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants