개요
DirectX에서 스텐실은 픽셀단편을 후면버퍼에 그릴지말지 판정할 수 있는 깊이 판정외의 판정 수단이다. 스텐실 판정을 먼저 수행한 후 추가적으로 깊이 판정을 수행하며, 둘다 통과할시에만 후면버퍼에 픽셀단편이 그려지게 된다.
이러한 스텐실 판정은 스텐실을 설정할 때 다양한 기준으로 설정할 수 있다.
또한 스텐실 버퍼의 갱신은 스텐실 판정이 실패했을때, 깊이 판정이 실패했을때, 후면버퍼에 그려졌을때 각각에 대해 갱신 방법을 지정할 수 있다.
대표적인 사용예시는 평면 그림자, 거울 기능이다.
스텐실 설정
PSO에 포함되는 D3D12_DEPTH_STENCIL_DESC구조체를 설정하여 스텐실을 활성화하고 여러 설정들을 할 수 있다. 다음은 핵심적인 스텐실 설정들이다.
스텐실 판정
스텐실 판정은 렌더링전 그래픽 커맨드로 설정할 수 있는 스텐실 기준값과 기존에 스텐실 버퍼의 해당 픽셀에 적힌 값을 PSO에서 설정한 연산자로 처리하여 true가 나오면 판정에 성공하는 방식이다.
이때 스텐실 기준값과 기존 버퍼 픽셀 값을 처리할 때 특정 비트에 대해서만 처리하도록 PSO에서 비트 마스크를 설정해줄 수도 있다.
대표적인 방식은 단순 숫자 비교 연산자를 사용하는 방식이다.
ex) if (스텐실 기준값 > 기존 픽셀 값) -> 스텐실 판정 성공
스텐실 갱신
스텐실 갱신은 스텐실 판정이 실패했을때, 깊이 판정이 실패했을때, 후면버퍼에 그려졌을때 각각에 대해 갱신 방법을 지정할 수 있다.
각각의 상황에 대해 유지, 0으로 갱신, 기준값 덮어쓰기, 1더하기, 1줄이기 등등의 방식을 지정할 수 있다.
평면 거울 구현
평면 거울 구현 예시는 반사 자체에 스텐실이 쓰이는 것이 아닌 반사된 물체를 계산후 그 물체를 그릴 때 거울 밖의 부분은 그리지 않도록 하는데 스텐실이 사용된다. 특정 평면 거울에 대해 반사된 물체의 정점을 계산하는 방법은 해석 기하학의 방식을 사용한다. 여기서는 주요 주제가 아니기에 생략한다.
거울을 그릴 때 핵심 스텐실 원리는 다음과 같다. 현재 화면상에서 거울이 채우고 있는 픽셀을 스텐실버퍼에 그리고 그 부분에만 반사된 물체의 스텐실 판정을 통과시키도록 하면 거울에만 반사된 물체가 그려진다.
평면 거울을 그리는 방법은 다음 과정을 따른다.
1. 일반 물체들을 그린다.
2. 스텐실 버퍼를 0으로 지운다.
3. 거울을 후면버퍼, 깊이버퍼 갱신을 해제하고 스텐실 판정을 무조건 성공으로 설정하고 깊이 판정까지 성공 시 스텐실을 1로 갱신하도록 만든 후 거울을 그린다. 그러면 화면상에서 거울이 눈에 보이게 되는 픽셀들이 스텐실 버퍼에서 1의 값을 가지게 된다.
4. 반사된 물체들을 스텐실 기준값을 1로하고 스텐실 기준값과 기존 픽셀 값이 같을 때만 스텐실 판정을 성공하게 한뒤 정상적으로 그리면 거울안에만 물체들이 그려진다.
5. 추가적으로 거울 위치에 반투명한 유리를 두면 좀 더 자연스러운 거울 효과가 추가된다.
평면 그림자 구현
평면 그림자는 그림자에 대한 빛을 내는 광원, 빛을 가릴 물체, 그림자를 받을 평면 3개가 주어지면 만들 수 있다.
특정 광원에 대해 해당 물체의 삼각형이 가려져 평면에 투영됬을때의 반투명한 검은 삼각형 물체를 기하학으로 계산하여 만들면 물체의 삼각형 부분에 대한 그림자가 만들어진다. 그리고 그러한 삼각형을 물체의 모든 삼각형에 적용시키면 물체에 대한 삼각형이 만들어진다. 문제는 투영된 삼각형들이 서로 겹쳐 불규칙적인 어둡기의 그림자가 나오게 된다. 이를 방지하기 위해 스텐실을 사용한다.
그림자 삼각형들을 그릴 때 다음과 같이 스텐실을 사용한다.
스텐실 판정은 기준값과 기존 픽셀값이 같을때로 하고 갱신은 깊이 판정까지 성공하여 그려질때 스텐실 픽셀을 1증가 시키는 방식으로 하여 그림자를 그린다. 그러면 한번 그려진적 있는 픽셀은 스텐실 값이 1이되고 더이상 추가적인 그림자 픽셀이 그려지지않아 균등한 어둡기의 그림자가 그려지게된다.
참고서적
DirectX 12를 이용한 3D 게임 프로그래밍 입문
'그래픽스 > DirectX12' 카테고리의 다른 글
[Directx12][13장]계산셰이더 (0) | 2023.03.21 |
---|---|
[Directx12][12장]기하셰이더 (0) | 2023.03.21 |
[Directx12][10장]혼합 (0) | 2023.03.21 |
[Directx12][~9장][실습]Block Game (0) | 2023.03.21 |
[Directx12][9장]텍스처 (0) | 2023.03.21 |