DirectX11 Screen Space Reflection ( 시도 )

호야·2024년 5월 2일

Screen Space Reflection


기존 Lake 에서 반사되는 장면을 그릴때 반사되는 시점에서 물체들을 한번씩 더 그렸다.

SSR 은 SSAO 와 같이 화면공간에서 반사되는 장면을 그리는 기법이다.


구현 방법


SSR 맵을 만들기 위해 Deferred Rendering 으로 저장한 색상 값 , 위치 값 , 법선 값 , 깊이 값 을 이용해야 한다.


ComputeShader 에서 현재 픽셀에 해당하는 View 시점에서의 좌표에서 reflect 함수를 이용하여 법선을 기준으로 반사 벡터를 구한다.

구한 반사벡터를 이용하여 View 시점 좌표에서 Ray Marching 을 통해 검사를 하고 Ray Marching 을 통해 이동한 좌표에서의 깊이 값을 구해서 이동한 깊이값이 현재 픽셀의 원래 깊이값보다 크다면 충돌한 것으로 판정한다.


Ray Marching 2가지 방법


1. View 공간에서 반사 방향으로 조금씩 좌표 이동하여 검사


구해진 반사벡터는 View 공간에서의 반사 벡터이고 이것을 정규화하여 기준이 되는 View 좌표에서 조금씩 이동시켜서 검사하는 방법이다.

단점

원근 문제로 인해서 원래 위치보다 높거나 낮은 곳을 샘플링 할 수 있어 정확한 값이 안나올수도 있다.

Ray 가 진행하는 거리가 길다.

첫번째 방법으로 구현하면 반사 장면이 이상하게 그려지고 여러 장면이 여러겹 덧붙여서 그려진다.

그리고 특정 시점에서만 잘 나온다.


2. DDA 알고리듬을 이용하여 화면공간에서 Ray를 이동하여 검사


View 시점에서의 좌표를 화면 공간으로 변환하여 시작과 끝의 기울기를 이용하여 이동시킨다.

x 값 변화량과 y 값 변화량을 비교하여

x 값 변화량이 더 크면 x 좌표가 화면상으로 1 픽셀 이동할때 y 좌표는 y변화량 / x 변화량 값만큼 이동하게 되고

y 값 변화량이 더 크면 y 좌표가 화면상으로 1 픽셀 이동할때 x 좌표는 x 변화량 / y 변화량 값만큼 이동하게 된다.

이 값은 실수 값이 나올수가 있는데 픽셀은 실수 단위가 없으므로 실수 값이 나오면 실수 값보다 큰 정수 값으로 변환하여 계산해준다.

이렇게 이동한 픽셀 값을 해상도 값으로 나눠주고 깊이텍스처에서 샘플링해와서 깊이 비교를 해주면 된다.


하지만 그래도 반사 장면이 이상하게 그려지고 여러번 덧씌워져 그려진다.
반사 벡터가 닿지 않아야 하는 곳에도 닿는 현상도 발생한다.



개선해야할 점

법선 값을 View 시점으로 변환하고 계산하니 이상하게 나와 임시로 World 시점에서 계산

DDA 알고리듬 개선

Position 렌더타겟에 저장된 좌표의 값과 Depth 렌더타겟에 저장된 깊이값을 이용하여 구한 좌표의 값이 서로 다르다.
-> 각각의 방법으로 구한 View 좌표를 이용한 결과값이 다름

0개의 댓글