저번에 이어서 오늘은 3번 렌더 타겟에 기록되는 마스킹 데이터를 렌더링하는 SunLightShader 를 볼 계획이다.
내가 사용하는 방식에서는 현재 픽셀 위치에서 광원의 방향으로 이동하며 샘플링을 하되, 이 샘플링이 원본 텍스쳐에서 이루어지면 안 된다. 그렇게 하게 되면 라이트 섀프트라기 보다는 블러 효과에 가까운 모양새가 된다. 이것도 결국 주변 텍셀을 샘플링하여 적절한 가중치를 더해 픽셀을 바꾸는 것이기에 블러와 그 궤가 같다.
그래서 렌더 타겟을 따로 만들어 해당 렌더 타겟에 어느 부분이 광원인지나 어느 부분은 차폐가 되는 지 등의 여부를 기록하고 이렇게 만든 텍스쳐에서 샘플링을 진행한다. 이를 위한 첫번째 단계가 SunLigthShader가 되겠다.
선언부는 위와 같은데, 다른 쉐이더 클래스랑 크게 다를바 없다. 그나마 중요한 부분은 Render겠으나 마찬가지로 여기도 별 건 없다.
그나마 중요한 렌더도 이걸로 끝이다.
단순하게 프리미티브 토플로지를 삼각형 리스트로 설정하고 6개의 정점을 가진 인스턴스 하나를 드로우 콜하고 있다. 이 다음에는 정점 셰이더에서 화면 전체를 뒤덮는 크기의 삼각형 2개를 만들어 픽셀 셰이더로 넘겨준다.
당연하게도 입력조립기로 넘겨줄 버퍼도 만들 필요없다.
그 다음에는 바로 픽셀 셰이더로 넘어가서 광원의 위치와 카메라의 위치를 고려하여 현재 화면에서 광원이 어디에 위치하고 있는지를 계산한다.
이 부분이 화면 상에서 광원의 위치를 계산하는 코드인데, 이건 이전 포스트에서 거의 유사한 코드를 사용한 바가 있으므로 넘어가자.
그 다음으로는 계산한 광원의 위치를 기준으로 정해진 크기 만큼의 원을 렌더링한다.
위 코드를 설명하자면, 먼저 해당 픽셀의 UV를 이용하여 원의 방정식을 계산한다. 이 때, 원의 중심은 광원의 위치이고 반지름은 미리 설정한 임의의 상수가 되겠다.
그 다음에는 해당 광원의 방향과 카메라의 방향을 내적하여 카메라가 광원을 바라보고 있는지를 검사한다. 만일 바라보고 있지 않다면 화면 상에 광원이 존재하지 않으므로 검은색으로 칠해지도록 리턴한다.
만일 광원이 화면 내에 존재한다면 앞서 계산한 원의 방정식 반지름보다 작다면 해당 픽셀은 광원으로 판단하여 하얀색으로 색상을 결정하고 아니라면 아주아주 짙은 회색으로 색상을 결정한다.
이렇게하면 광원을 제외한 위치에는 아주 어두운 회색이 칠해지고 나머지 광원에 해당하는 부분은 흰색이 칠해지게 되는데 이렇게 만들어진 텍스쳐를 샘플링하여 라이트 섀프트 계산에 사용하면 우리가 원하는 라이트 섀프트 결과를 얻을 수 있다. 다만 여기서 광원을 제외한 배경은 완전히 검은색이 아닌 그보다 약간 밝은 색을 하고 있는 이유는 이렇게 해야 화면 전체에 대하여 좀 더 넓고 자연스럽게 라이트 섀프트가 생성되기 때문이다.
하지만 이대로 끝내면 안되고 한 가지 처리를 더 해야한다. 이 과정으로는 광원의 위치에 대한 정보를 표현할 순 있어도 씬에 존재하는 오브젝트 간의 차폐에 대해서는 표현할 수 없다. 그래서 이 차폐에 대한 처리까지 이루어져야 제대로된 라이트 새프트를 만들 수 있다.
이 부분은 정교하게 차폐를 계산하고자 한다면 여러 방법을 생각해볼 수는 있겠으나 나같은 경우 단순히 오브젝트가 렌더링될 때 해당 위치의 마스킹 텍스쳐의 픽셀을 완전한 검은색으로 렌더링하게 처리했다.
그래서 만들어지는 최종 렌더링 결과가 저번 포스트에서도 봤던 아래 이미지다.
해당 이미지에서 마스킹 텍스쳐의 내용은 광원 부분은 흰색으로 존재하고, 나무가 그려져있는 부분은 검은색일 것이며 그외 하늘 부분은 아주 어두운 회색으로 구성될 것이다.
그리하여 여기까지 구현하면 라이트 섀프트는 대충 완성이다. 다만, 잘 만든 라이트 섀프트라고 부르기엔 하자가 좀 많다. 빛줄기의 색상도 잘 보면 검은색이라 빛줄기 같지 않은데다 내 코드 기준으로는 광원을 바라보고 있을 때와 아닐 때의 하늘의 색상이 다르다.
광원을 보고 있지 않을 때는 마스킹 텍스쳐를 모두 검은색으로 하다보니 샘플링을 하여 값을 더해서 누적하는 방식 특성상 원본 색상이 그대로 출력이 되고, 광원을 보고 있는 상태에서는 여백이 완전한 검은색이 아니라 하늘 부분을 렌더링할 때 색상이 조금씩 누적되어 기존보다 약간 더 밝은 색상이 만들어진다.
그렇다보니 화면을 회전하다보면 어색하게 하늘의 색상이 점멸하는 구간이 생기는 문제가 있어서 이부분을 해결할 필요가 있다. 여러모로 제대로된 라이트 섀프트를 위해선 좀 더 발전된 방식을 쓰는 게 마음 편하지 않나 생각한다.
아무튼 여기까지 해서 라이트 섀프트도 끝.
'Rampage' 카테고리의 다른 글
Screen Space Light Shaft - 화면 공간 라이트 섀프트 (1) (0) | 2023.08.10 |
---|---|
Detail Object Map - 지형 위에 풀숲 (2) (0) | 2023.07.29 |
Detail Object Map - 지형 위에 풀숲 (1) (0) | 2023.07.24 |
Terrain - 지형 (2) (1) | 2023.07.07 |
Terrain - 지형 (1) (0) | 2023.01.28 |