GS Volumetric Lighting (SH Density)
Volumetric
Lighting
SH Density 기반 라이팅 모델
Gaussian splat 기반 반투명 볼륨 렌더링에서 정렬 기반 ODT 누적을 유지하면서 방향성 라이팅, 환경 반사, 직접광 하이라이트를 안정적으로 계산한다. 표면 노멀 재구성 없이 density 분포 자체를 방향 함수로 취급하여 라이팅을 수행한다.
기본 파이프라인
픽셀 단위로 depth 정렬된 splat 리스트를 사용하여 ODT 누적을 수행한다. 동시에 픽셀의 방향 밀도 분포를 SH로 누적한다.
w = T × alpha 가중치로 albedo · density 누적, T 감쇠w로 splat 방향을 SH basis에 투영하여 누적dot(SH_density, SH_light) 로 최종 라이팅 계산T = 1
for splat in sorted:
w = T * alpha
accum_albedo += w * albedo
accum_density += w * density
// 방향 밀도를 SH로 동시 누적
dir = splat_direction // view→splat 또는 splat orientation
SH_density += w * SH_basis(dir)
T *= (1 - alpha) transmittance 가중치 w = T × alpha를 그대로 사용한다. 모든 레이어가 투과율에 비례해 기여한다.
w = T * alpha
accum_albedo += w * albedo 처음 N개의 splat에 강한 bias를 적용한다. 표면에 가장 가까운 레이어의 smoothness가 지배적으로 반영된다.
bias = FrontBias(splat_index, N)
w_s = T * alpha * bias
accum_smooth += w_s * smooth SH Density 정의
픽셀 내부의 splat 분포를 방향 함수로 근사한다. SH order는 L2 또는 L3 사용.
라이팅 모델
라이팅도 SH로 표현한다. 픽셀 라이팅은 SH 내적 형태로 계산한다.
L(ω) ≈ SH_light
lighting = dot(SH_density, SH_light) 라이팅 소스 — IBL
라이팅 소스는 IBL(SH)이다. 직접광도 별도로 처리하지 않고 SH 방향 분포로 인코딩한다.
density를 SH로 누적했기 때문에, 광원 종류에 관계없이 dot(SH_density, SH_light) 하나로 계산이 통일된다.
직접광도 SH 방향 분포로 인코딩하여 IBL처럼 취급한다. 단일 방향이면 델타 함수에 가까운 sharp SH, cone lobe로 확장하면 highlight 폭을 조절할 수 있다.
// 단일 방향 → sharp SH lobe
SH_light = SH(dirLightDir)
// cone lobe 확장 (highlight 폭 제어)
SH_light = SH_cone(dirLightDir, width) direct = dot(SH_density, SH_light) 환경맵 전체를 SH로 변환한다. SH_density와 내적하면 방향 밀도 분포에 따른 환경광 응답을 얻는다. 반사·간접광·IBL 모두 동일한 방식으로 처리된다.
// 환경맵 → SH 변환
SH_env = ConvertEnvmapToSH(cubemap) env = dot(SH_density, SH_env) Roughness 처리
roughness는 SH blur로 처리한다. light side를 blur하는 방법 A와 density side를 blur하는 방법 B 중 선택한다.
SH_light_rough = BlurSH(SH_light, rough)
lighting = dot(SH_density, SH_light_rough) SH_density_rough = BlurSH(SH_density, rough)
lighting = dot(SH_density_rough, SH_light) 최종 셰이딩
직접광과 환경광 기여를 합산하고 accum_albedo를 곱해 최종 색상을 구한다. accum_density로 Beer, Powder, AO 효과를 추가할 수 있다.
float3 light =
dot(SH_density, SH_direct) // 직접광
+ dot(SH_density, SH_env); // 환경광
float3 color =
accum_albedo * light;