※ 아래의 내용들은 DirectX 11을 이용한 3D 게임 프로그래밍 입문 책의 내용을 바탕으로 작성된 것입니다.
1. 수면을 렌더링하기 전에 첫 번째 표본의 추출을 비활성화 하는 코드를 수행하도록 예제를 수정하라.
- 아래의 기존 예제 코드에서 마지막 0xffffffff 값만 0xfffffffe 로 변경하면 문제없이 실행된다.
md3dImmediateContext->OMSetBlendState(RenderStates::TransparentBS, blendFactor, 0xffffffff);
=> 다만 저의 경우, 주석에도 적혀있듯이 코드에 익숙해질겸 혼합 상태를 직접 설정하고 만드는 방식으로 변경했습니다.
- 이번 예제는 다중표본화를 사용하지 않으므로, 이렇게 하면 물 픽셀이 그려지지 않는다.
2. 혼합 연산과 혼합 계수들의 다양한 조합을 시험해 보라.
- 예제의 RenderStates.cpp 코드에서 아래에 해당되는 내용들을 변경하며 실행해보면 된다.
=> 혼합 연산과 혼합 계수들은 transparentDesc.RenderTarget[0] 으로 시작하는 코드들의 값을 변경하면 됨.
=> 주석에도 적혀있듯이 해당 값들은 특정 열거형의 한 멤버를 지정해야 함을 유의.
- 결과물을 확인하며 테스트할 때, 안개가 아니라 물의 투명도를 중심으로 봐야한다.
- D3D11_BLEND_SRC_ALPHA 값은 원본 픽셀의 알파값을 가져온다는 의미이다.
- 알파값이 0 ~ 1 일때 이미지의 불투명도를 나타낼 수 있는 것은 모두 혼합 연산을 통해서이다.
=> 즉, 덧씌울 픽셀의 rgb 값에 해당 픽셀의 알파값을 곱하고 나온 결과 A와, 덧씌워질 대상 픽셀의 rgb값에 "(1 - 덧씌울 픽셀의 알파값)" 다음을 계산한 값을 곱하여서 나온 결과 B에 대해서 A와 B의 값을 더하기 혼합하면 투명도 혼합이 이루어진다.
=> 혼합 연산 없이, 색상의 알파값만 변경한다고 해서 투명도가 조절되는 것이 아님을 기억하자.
ex) rgba 채널의 값을 (1.0f, 1.0f, 1.0f, 0.5f) 로 설정한다고 해서 해당 픽셀이 반투명해지는 것이 아님. 혼합 연산이 이루어져야함.
3. 지형보다 물을 먼저 그리도록 혼합 예제를 수정해서 결과를 살펴보고, 왜 그런 결과가 나오는지 설명하라.
- 물을 먼저 그린 후, 지형을 그리면서 혼합 상태를 적용하면 지형에 투명도 혼합이 적용되어 지형이 반투명해지는 것을 알 수 있다.
- 물은 투명도 혼합이 적용되지 않으므로 물에 가려지는 박스나 지형은 전혀 보이지 않는다.
※ 단, 예제에서 지형의 분산광 알파값이 1.0으로 설정되어 있는데 이 경우 투명도 혼합을 하게되면 아무런 변화가 없다.
따라서 지형의 알파값을 변경해주어야 한다.(ex: 0.5f)
※ 투명도 혼합은 덧씌울 픽셀의 알파값을 이용해서 구하는 것이기 때문에, 덧씌워질 지형의 알파값이 1.0이 되면, 지형은 완전히 불투명한 상태가 되므로 투명도 혼합을 해도 아무런 변화가 없는 것이다.
- 지형을 그리기 전, 물을 먼저 그리면서 혼합상태를 적용한다면 똑같이 물에 가려져있더라도 물보다 먼저 그려진 박스는 보여지고, 물보다 나중에 그려지는 지형은 보이지 않는다.
- 물을 그린 후, 혼합 상태를 다시 디폴트값으로 변경해주지 않고 지형을 그린다면 위와 같이 지형도 투명도 혼합이 적용되는 것을 알 수 있다.
- 지형을 그린 후, 혼합 상태를 다시 디폴트값으로 변경해주지 않는다면 계속해서 투명도 혼합이 적용되므로 박스 또한 반투명해진다.
=> 박스보다 먼저 그려진 물체가 없으므로 박스가 반투명해지더라도 뒤의 물체가 비쳐 보이지는 않는다.
4. gAlphaClip이 false, true 인 각각의 경우에 대해 어셈블리 코드를 비교해보라.
- gAlphaClip = false 인 경우 discard 함수가 존재하지 않는다.
=> discard는 HLSL의 clip에 대응되는 어셈블리 명령이다.
5. 적색 채널과 녹색 채널로의 색상 쓰기를 비활성화하는 혼합 상태를 생성해 적용하라.
- D3D11_RENDER_TARGET_BLEND_DESC 내의 RenderTargetWriteMask는 렌더 대상 쓰기 마스크로, 몇몇 플래그들을 하나 이상 조합해서 지정할 수 있다.
=> 조합에 사용되는 플래그들은 혼합의 결과를 후면 버퍼의 어떤 색상 채널들에 기록할 것인지를 결정한다.
==> 만약 D3D11_COLOR_WRITE_ENABLE_RED; 플래그만 설정할 경우 혼합의 결과가 Red 채널에만 적용된다.
- 색상 채널에 기록된다는 것은 덧씌울 픽셀의 해당 색상 채널에 혼합 연산의 결과가 적용된다는 의미이며, 적용되지 않은 채널의 경우 원래 본인의 채널 값이 적용된다고 생각할 수 있지만 그렇지 않다.
=> D3D11_COLOR_WRITE_ENABLE_ALPHA 플래그는 혼합의 결과가 RGB 채널들에는 기록되지 않고 알파 채널에만 기록된다. 알파 플래그만 적용해서 확인해본 결과, 덧씌울 픽셀의 원래 채널 값이 적용된게 아니라, 기존에 이미 그려져있던 대상 픽셀의 채널 값들이 적용된다. (뒤의 배경이 흰색이라면 덧씌울 픽셀의 rgb 채널 값은(1, 1, 1)이 된다.)
=> 예제의 경우 조명만 가해서 장면을 렌더링 하도록 하는 설정도 있는데, 해당 설정으로 확인해봐도 혼합을 알파 채널에만 쓸 경우 덧씌울 이미지가 보이지 않았다.
==> 뒤의 배경과 완전히 같은 색이 되므로 없는 것처럼 보인다.
- 결과물에서 물 뒤쪽에 지형이 아닌 배경이 있을 때는 물의 색깔이 노란색으로 보이는데 이것은 뒤쪽 배경의 Silver (0.75f, 0.75f, 0.75f, 1.0f) 여서 그렇다. r, g 채널이 0.75로 비교적 높은 값을 갖게 되고 b 채널의 값은 혼합의 결과 비교적 낮은 값을 갖게 되어 노란색으로 보이게 된다.
- 참고로 해당 부분의 물과 배경의 r, g, b 값은 위와 같다.(그래픽 디버깅 사진 첨부)
※ Yellow는 (1.0f, 1.0f, 0.0f, 1.0f) 값을 가진다.
개인적으로 이해한 내용을 바탕으로 작성하였기 때문에 틀린 내용이 있을 수 있습니다. 참고하실 때 주의 해주세요.
틀린 부분이나 이상한 부분이 있으면 댓글로 편하게 지적해주세요.
감사합니다!
'DirectX11 > 코드정리' 카테고리의 다른 글
[DirectX11] 10장 스텐실 적용 연습문제 (1) | 2023.01.18 |
---|---|
[DirectX11] 8장 텍스처 연습문제 (0) | 2022.12.02 |
[DirectX11] 텍스처 예제 (0) | 2022.11.29 |
[DirectX11] 7장 연습문제 (0) | 2022.11.25 |
[DirectX11] 조명 예제 (0) | 2022.11.25 |
댓글