VK_EXT_opacity_micromap açıklaması: anyhit olmadan alfa-testli ışın izleme

Alfa-testli geometri — yapraklık, tel örgü çitler, saç kartları — ışın izlemenin klasik patolojik vakasıdır: her üçgen alfa dokusunu değerlendirmek için bir anyhit shader’ı çalıştırır ve anyhit yolu pipeline’ın en yavaş, en diverjan kısmıdır. VK_EXT_opacity_micromap (OMM) bu doku aramasını BLAS’a pişirilmiş mikro-üçgen başına bir opasite ızgarasıyla değiştirir: donanım “opaque / transparent / unknown"u kendisi yanıtlar — anyhit çağrısı yok.

Fikir

omm.txt
üçgen ──► 4^N mikro-üçgene böl (barycentric grid)
      ──► mikro-üçgen başına durum: OPAQUE | TRANSPARENT |
                                    UNKNOWN_OPAQUE/UNKNOWN_TRANSPARENT
      ──► VkOpacityMicromapEXT'e pişir, BLAS üçgenlerine ekle

ışın isabeti: OPAQUE      → commit et, shader yok
              TRANSPARENT → atla, shader yok
              UNKNOWN_*   → anyhit'e düş (sınır pikselleri)

Alfa testi mikro-üçgen başına build zamanında bir kez çalışır, çalışma zamanında ışın başına isabet başına bir kez değil.

API’nin şekli

omm.cpp
// micromap, üçgen geometrisine bağlı bir buffer'dır:
vk::AccelerationStructureTrianglesOpacityMicromapEXT omm{};
omm.indexType    = vk::IndexType::eUint32; // veya none
omm.indexBuffer  = indexDevAddr;
omm.indexStride  = 4;
omm.baseTriangle = 0;
omm.micromap     = micromapBufAddr;   // VkOpacityMicromapEXT verisi
// VkAccelerationStructureGeometryTrianglesDataKHR::pNext'e zincirle

// micromap'in kendisini build et:
vk::MicromapBuildInfoEXT mb{};
mb.type   = vk::MicromapTypeEXT::eOpacityMicromap;
mb.usageCounts = usage;   // üçgen başına bölüntü seviyeleri
// … vkCmdBuildMicromapsEXT — acceleration structure'larla aynı
//   "scratch + cihazda build" kalıbı

// pipeline opt-in'i:
pci.flags |= vk::PipelineCreateFlagBitsKHR
              ::eRayTracingOpacityMicromapEXT;

Format ve bölüntü

formats.txt
VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT   — 1 bit/mikro-üçgen (opaque/clear)
VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT   — 2 bit (sınır pikselleri için
                                           iki unknown durumunu ekler)
bölüntü seviyesi N → üçgen başına 4^N mikro-üçgen (seviye 0 = yok,
                      seviye 4 = 256, seviye 7 = 16384)

256×256 alfa dokusunda 4-state, seviye-4 harita ~4 KB ister — buna karşılık her ışın isabetinde anyhit çalıştırmak.

Kazancın olduğu yer

wins.txt
yapraklık/bitki       — yoğun yaprak kartları: anyhit fırtınası → OMM
                        çoğu mikro-üçgeni shader çağrısı olmadan çözer
alfa-testli UI/çitler — aynı kalıp
gölge ışınları        — en büyük tek kazanç: gölge ışınları sadece
                        "bir şeye değdi mi" ister, alfa anyhit en kötü
                        vakaydı

Gerçek içerikteki sayılar (NVIDIA’nın yayınladığı veri): yaprak-ağırlıklı sahneler RT pass’inde 1,5–2 kat alır; saf opaque mesh ~hiçbir şey kazanmaz.

Pratik kurallar

  • OMM, VK_EXT_opacity_micromap + micromap özelliği + eRayTracingOpacityMicromapEXT pipeline flag’i ister — üç yer, üçüncüsünü unutmak kolay.
  • 4-state format, sınır vakasını (alfa sınırına basan mikro-üçgenler) ele alır — bunlar hâlâ anyhit çalıştırır, bu yüzden sınır pikselleri için fallback anyhit shader’ı tutun.
  • VK_EXT_opacity_micromap, micromap’leri acceleration structure’lar gibi build eder: scratch bellekli vkCmdBuildMicromapsEXT — aynı “cihazda build, scratch’i canlı tut” yaşam döngüsü.
  • Kalan diverjans için VK_NV_shader_execution_reordering ile birleştirin — OMM anyhit işinin çoğunu kaldırır, SER kalanı yeniden tutarlı hale getirir.
  • Bedava doku yerine koyma değil — alfa haritası UNKNOWN pikselleri (kenarlar, antialias’lı kesikler) için hâlâ gerekli; OMM bir filtre, ikame değil.

Check out similar posts by category: Vulkan C++