fix(render3d): Vulkan exposure, foliage depth and meadow alpha

Three things the first Vulkan frames on the RTX 3070 Ti showed against OpenGL on the same PC:

- Exposure: the adaptation pass reads the HDR scene's smallest mip, and a render target made
  without pixels had one level, so exposure came from a single texel. A target asked for mipmaps
  now grows a full chain (level 0 kept), and passes draw through level-0 views keyed by the
  image's generation.
- Foliage: the depth prepass and the lit pass (depth EQUAL) are different variants. Vulkan vertex
  stages now declare an invariant gl_Position so both land on the same depth.
- Alpha to coverage is enabled only on a multisampled pass. OpenGL ignores it without MSAA; Vulkan
  with one sample dropped every fragment under half alpha.

vk_resources also checks a big-endian 16-bit RGB upload (a normal map). VKRES OK; ludic-dev test
140 passed; the PC's Vulkan frame is validation-clean; OpenGL frames byte-identical at the five
viewpoints with 59 self-tests passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-15 12:29:24 +03:00
parent 072f9a848e
commit a674c9b372
33 changed files with 70 additions and 7 deletions

View file

@ -173,7 +173,9 @@ function cmd_shaders() -> int {
# is untouched. No y flip: a Vulkan target's row 0 is where OpenGL's is (NDC y = -1), so render
# to texture, sampling and gl_FragCoord agree; only the present and the screenshot flip.
let depth_remap = "\n#undef main\nvoid main() {\n ludic_gl_main();\n gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n}\n"
let vsrc = "#version 460\n" + defines + "#define main ludic_gl_main\n" + shd_file(parts[0]) + depth_remap
# invariant: the foliage's depth prepass and its lit pass (depth EQUAL) are different variants,
# and without it the compiler may compute their positions a hair apart and fail the test
let vsrc = "#version 460\n" + defines + "invariant gl_Position;\n#define main ludic_gl_main\n" + shd_file(parts[0]) + depth_remap
let fsrc = "#version 460\n" + defines + shd_noise + shd_lighting + shd_file(parts[1])
# one binding table for both stages
shd_names = new []pointer