DirectX11

Voxel GI - Cone Tracing

RuNaPi 2023. 5. 25. 16:10

이전 글에서 3D텍스처에 복셀들의 정보를 기록하는것까지 하였다.

이제 Voxel들로부터 전역 조명을 계산하기 위하여 다음과 같은 순서를 거친다.

1. 픽셀의 세계공간 위치에서 복셀 그리드 좌표로 계산

2. 법선 위의 반구에서 주위로 광선추적을 실행

3. 광선 행진을 할때마다 밉레벨을 증가시키며 복셀을 샘플링

4. 광선을 따라 복셀에 닿으면 샘플링된 값을 축적(알파값이 1에 도달할때까지)

5. 각 원뿔에 대해 이 작업을 수행후 누적된 결과를 광선 수로 나눔

원뿔 추적를 하기 위해서는 일단 세계 공간에서의 좌표를 구하고 주어진 Cone의 방향으로ConeTracing를 실행해주면된다. 계산할 Cone의 수가 많으면 많을 수록 좀더 좋은 품질이 나온다.

Cone마다 계산된 값을 모두 더한 후에 평균 값을 구해준다.

반구에서 랜덤한 방향으로 콘의 방향은 상수로 방향을 정해주었다.

미리 설정한 콘의 랜덤한 방향

ConeTracing의 각 픽셀 위에 원뿔을 그리면 된다. 레이 마칭과 유사하지만 샘플링 할 볼륨의 크기가

광선이 전진 할 수록 증가한다. 이는 원뿔의 밑면의 지름에 따라 샘플링 할 밉 단계를 다르게 취해준다.

Vl=log2(d/Vs)

d는 원뿔의 밑면의 지름이로 V_s는 복셀의 크기이다.

d=2tdottan(theta/2)

d의 크기는 위와 같이 구 할 수 있다. t는 원뿔의 높이, 광선이 이동한 거리이고 θ는 원뿔의 각도이다.

샘플링 된 값을 계속해서 누적하면서 a가 1이상이 되거나 광선이 미리 지정해둔 최대 거리에 도달하면 멈춘다. 여기서 샘플링 값을 누적을 할때는 front-to-back 블렌딩을 해준다.

$$color = color + ( 1 - alpha) * sampleColor$$

$$alpha = alpha + (1 - alpha) * sampleAlpha$$

이를 사전에 정한 최대 값 혹은 alpha값이 1이상 누적이 될 때 까지 반복을 해줍니다.

이걸 Diffuse Trace와 Specular Trace로 나누어 구해주면 된다.

Specular Trace를 할때는 콘의 방향을 View 벡터와 노말의 Reflect 값을 사용하고 조리개 값을 더 작게 설정 해주었다.

Voxel Gi를 사용하지 않을때는 빛이 비추는 영역에만 Direct Light가 들어간다.

Voxel GI를 사용 할때 빛이 안비추는 주변 부분도 간접광이 들어갔다.

이방성 복셀 표현은 원뿔 추적 중에 더 높은 시각적 품질과 정확성을 제공한다. 각 추적된 원뿔은 방향을 가지고 있는데, 이 방향을 사용하여 어떤 방향 볼륨을 보간해야 할지 결정해준다.

임의의 방향은 간소화된 복셀의 이 방향에 따라 앞면을 나타내는 세 개의 볼륨으로 표현해준다. 원뿔의 방향은 각 방향 축에 가중치를 가지고 있기 때문에, 각 방향 볼륨의 값은 샘플링할 때 가중치를 고려해 계산한다. 등방성 표현은 원뿔의 방향성 개념을 갖고 있지 않기 때문에, 일부 경우에 시각적 문제를 일으킬 수 있다 (하나의 판때기를 기준으로 양쪽으로 샘플링이 되기때문에 원치않는 값이 된다.) 이 구현의 단점은 원뿔 추적이 더 느리고, 원뿔의 각 단계마다 세 개의 샘플링을 수행해야 하며, 더 많은 메모리를 사용한다.

일단 방향성 복셀을 만들기위해 2차원 복셀을 예를 들어 설명하겠다.

위와 같이 5^2 해상도와 3^2 해상도의 밉이 있을때

복셀 E를 필터링 하기 위해서는 인접해있는 8개의 복셀들을 고려하게된다.

이를 4개의 그룹으로 나누어서 생각한다.

좌상단의 그룹을 +X 방향에 대하여 필터링 해보면 우선 q→r과 l→m이 +X방향에 속한다.

위의 수식에 따라 +x방향으로 알파 블렌딩 혹은 선형 보간을 해주고 구한 값들의 평균을 구해준다.

이것을 각 그룹 4개에 대해 반복을 해준다.

복셀 텍스처의 해상도의 반에 해당하는 Mip을 생성해주는 컴퓨트 쉐이더

이방성 복셀을 사용하게 되면 어떤 방향의 볼륨 값을 사용할지 정해야한다,

이는 Cone의 방향 벡터의 각 축의 부호를 사용 하여 결정을 한다.

이제 ConeTrace를 이방성 복셀을 샘플링하도록 수정해준다. 추가로 불투명도를 누적하여 나중에 차폐값으로 사용한다.

r은 원뿔의 반경을 나타내고, λ는 거리에 따른 감쇠의 강도를 나타내는 주변 차폐 항의 거리에 따른 감쇠 강도, 기본적으로 차폐 반경의 범위 값이다.

방향 벡터의 각 축의 가중치를 이용하여, 각 축에 가중된 결과 값을 얻을 수 있다.

이방성 복셀을 이용한 AO
Direct + Indirect
Direct + Indirect + AO

 

'DirectX11' 카테고리의 다른 글

Texture Compression(Block Compression)  (0) 2023.06.27
GPU Instancing  (0) 2023.06.22
Voxel GI - Voxelize  (0) 2023.05.25
Cascade Shadow  (0) 2023.02.16
Shadow Mapping  (0) 2022.09.27