ludic/packages/ludic.render3d/shaders/grass_reset.comp
Orkuncakilkaya cc384efee0 feat(render3d): the meadow's blades are culled on the GPU - under 1.5 ms of a MoltenVK frame for all the grass
- grass_cull.comp decides each candidate blade once a frame (place, ground, density, water,
  slope, frustum, colour field) and writes survivors into three bands by distance, one indirect
  draw each; grass_inst.vert only bends and places the vertices. OpenGL keeps grass.vert's
  per-vertex path; R3D_GRASS_GPU=0 compares
- compute programs take sampled textures after their buffers (gpu_compute_tex / gpu_dispatch_tex),
  and every dispatch now records a compute-to-draw memory barrier
- the blades as a sward: 4 m cells, bands with five, three and one-quad blades, spacing doubling
  every 18 m to 70 m, never narrower than a pixel; lit facing the sun and leaning to the sky,
  shadow looked up above the ground (it read the terrain as its caster), a colour ramp that
  leaves only the sheath dark, clumps, dry patches and a tussock shade worked out per blade
- scatter layers flagged grass are skipped while the blades draw (and under R3D_NOGRASS);
  R3D_BLADES, R3D_NOBLADES win over the game's setting; R3D_GRASS_S0/D0 for measuring

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 15:47:36 +03:00

8 lines
417 B
Text

// grass_reset.comp - zero each band's instance count before grass_cull.comp counts into it. On the
// GPU, in order, because the frame before may still be drawing from the same records.
layout(local_size_x = 1) in;
layout(set = 0, binding = 0) uniform Params { uvec4 n; } pr;
layout(set = 0, binding = 1) buffer Cmds { uint cmds[]; };
void main() {
for (uint b = 0u; b < pr.n.x; b++) { cmds[b * 5u + 1u] = 0u; }
}