-
DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 9Graphics/DX11 물방울책 연습문제 풀이 2021. 4. 28. 21:27
우선.. 말투 좀 고치겠습니다. ~이다는 저랑 너무 안 어울리도 어색해서..
9장은 혼합을 주제로 다루고 있습니다. 원본픽셀과 대상 픽셀을 factor와 지정된 연산자를 이용해 적절히 계산하여 혼합 결과를 출력합니다. 여기서 원본 픽셀은 래스터화 된 ij번째 픽셀 색상을 가리키며 대상 픽셀은 후면 버퍼에 그려진 ij번째 픽셀 색상입니다.
잠시 저의 생각을 옮겨 적자면.. 저는 이 주제를 공부할때 한 가지 오해 때문에 많이 힘들어했습니다. 왜냐하면..
당연히 alpha값이 0이면 아무것도 안보이고 1이면 잘 보이겠죠? 그리고 0과 1 사이면 반투명으로 보이겠죠? 근데 그게 아녔습니다. 알아서 반투명되는 건 줄 알았습니다.. 이때 필요한 게 혼합이고요.
문제 1
수면을 렌더링하기 전에 SampleMask를 0 xfffffffe로 수정하라.
해결
이 문제는 매우 간단합니다. 심지어 문제 자체에 답과 해설이 적혀있고요.
OMSetBlendState의 samplemask를 0xfffffffe로 바꿔주면 됩니다. 이렇게 하면 물 픽셀이 그려지지 않습니다.
왜냐하면 지금 이 예제 프로젝트는 다중표본화를 사용하지 않고 있으며(다른 말로 표본이 단 하나인 다중 표본화를 사용하므로), 이렇게 하면 물 픽셀이 그려지지 않는다고 합니다.
사실 이 부분은 좀 더 공부하고 해설을 적어보려고 시도했습니다만.. 아직까지 다중표본화가 아 이런 거구나~ 하고 제 몸으로 느낀 적이 없기 때문에 나중에 진도 더 나가서 알게 된다면 그때 와서 해설을 수정하도록 하겠습니다.
문제 2
혼합 연산과 혼합 계수들의 다양한 조합을 시험해 보라.
위에서 블렌드상태를 적용할 때 사용했던 블랜드 상태 구조체입니다. 하나씩 따져보도록 하죠.
AlphaToCoverageEnable은 식물의 풀 따위나 창살문 같은 텍스처의 렌더링에 유용한 다중 표본화 기법인 알파 포괄도 변환이 활성화된다. 이 문제를 풀 때 다루는 부분이 아니기 때문에 아래 영상 링크를 통해 어떤 변화가 일어나는지 눈으로 알아보자. www.youtube.com/results?search_query=alpha+to+coverage
IndependentBlendEnable은 모든 렌더링 타겟에 대해 최대 8개까지 각자 다른 혼합방식을 적용할 수 있습니다. false로 하면 모든 혼합방식은 RenderTarget [0] 번째의 혼합방식을 사용합니다.
BlendEnable은 혼합을 활성화할지 안할지를 결정합니다.
혼합 공식은( Src * SrcBlend ) BlendOp ( Dest * DestBlend )입니다.
여기서 Src가 원본 픽셀 색상, Dest가 후면 버퍼 픽셀 색상(대상 픽셀 색상)입니다. RenderTarget의 SrcBlend, DestBlend, BlendOp가 이 공식에 대입된다고 보면 됩니다.
그리고 알파 값 또한 공식이 따로 존재합니다.
(SrcAlpha * SrcBlendAlpha) BlendOpAlpha (DestAlpha * DestBlendAlpha)
위 공식들을 통해서 픽셀 색상과 알파 값의 혼합 연산이 이루어지고 그 최종 결과가 픽셀 셰이더를 통해 출력이 됩니다.
마지막으로 RenderTargetWirteMask는 어떤 색상 채널들을 보여줄 것인지 결정합니다.
기본적으로 알파 값을 변하게 하지 않으려면 SrcBlendAlpha를 D3 D11 D3 D11_BLEND_ONE으로
DestBlendAlpha를 D3 D11_BLEND_ZERO으로 하면 된다. 이렇게 지정하면 원본 픽셀 알파 값만 온전히 살아있고 대상 알파 값은 죽게 된다.
위 열거형 값들을 이용하여 적절히 사용하면 된다.
문제 3
지형보다 물을 먼저 그리도록 혼합 예제를 수정해서 결과를 살펴보고, 왜 그런 결과가 나오는지 설명해라.
해결
혼합 색상은 원본 픽셀 색상과 대상 픽셀 색상(후면 버퍼)을 연산해서 나온 색상입니다. DrawIndex메서드를 사용하여 오브젝트를 순서대로 그리는 게 DirectX가 화면에 무언가를 그리는 방식인데 만약 산 그러고 나서 물을 그리면
원본 픽셀(물)과 대상 픽셀(산)의 색상을 조합하게 됩니다. 하지만 물을 먼저 그리고 나면 산을 그리면 원본 픽셀(산)과 대상 픽셀(물) 이렇게 조합하게 됩니다. 하지만 산은 alpha값이 1이기 때문에 반투명으로 보이지 않게 됩니다. 구체적으로 어떻게 변하는지 그래픽 디버깅을 통해 관찰해봅시다.
산의 alpha는 1이고 물은 0.5입니다. 산을 그리고 물을 나중에 그렸으니 src=물이고 dst=산입니다.
혼합 공식은 ( Src * SrcBlend ) BlendOp ( Dest * DestBlend )입니다. SrcBlend를 알파 값으로 지정하였으니 원래 색상에 0.5를 곱하고 dst도 1-0.5=0.5이므로 0.5를 곱해줍니다. 그리고 그 두 색상을 더한 게 혼합 색상입니다.
알파 혼합 공식은 (SrcAlpha * SrcBlendAlpha) BlendOpAlpha (DestAlpha * DestBlendAlpha)입니다. 여기서 srcalpha=0.5이며 destalpha=1.0입니다. 여기서 destblend=0이므로 온전히 srcAlpha값만이 남게 됩니다. 고로 최종적으로 알파 값은 0.5가 됩니다.
색상은 건너뛰고 알파만 짚어보겠습니다.
지금 배경색이 회색입니다. 배경이니까 당연히 알파가 1이고 destAlpha가 이에 해당합니다.
현재 물은 배경을 반투명으로 비춰주고 있는 상태입니다. 그래서 물이 살짝 탁하게 보이는 겁니다. 이는 원본 텍스처(3번째 사진)와 비교하면 더욱 확실해집니다. 그리고 이상태로 산을 그려봅니다. 산은 alpha가 1이고 물은 0.5입니다. 하지만 destBlendAlpha는 0이기 때문에 최종적으로 1입니다. 그래서 산도 멀쩡하게 그려지는 것이고요. 근데 물 알파 값이 0.5이기 때문에 물속에 산이 보여야 되지 않을까 하는 의문이 생깁니다만 이미 물은 다 그린 상태에서 산을 그리는 거기 때문에 물속에서 보여야 할 부분은 깊이 버퍼에 의해 픽셀이 폐기됩니다.
즉 반투명한 물 효과를 내고 싶다면 나중에 그려야 합니다.
혼합 효과를 나타내기 위해서 나중에 렌더링을 해야 한다니 꽤 치명적인 단점입니다.
문제 4
fogStart=10이고 fogRange=200일 때 여러 카메라-표면 점 거리들에 대해 foggedColor를 각각 계산하라.
dist(p, E)=160
dist(p, E)=110
dist(p, E)=60
dist(p, E)=30
foggedColor = (1-s)*LitColor + s*fogColor입니다.
여기서 s는 saturate의 첫 자이며 s = (dist(p, E) - fogStart)/fogRange입니다.
그리고 dist는 Distance의 약자이며 dist(p, E)는 p(표면 점)와 E(카메라 위치)의 거리입니다.
litColor는 픽셀마다 값이 다르고 fogColor도 프로그래머가 설정하는 값이기 때문에 s만 구하도록 하겠습니다.
dist(p, E)=160
s = (160-10)/200 = 150/200 = 0.75f
dist(p, E)=110
s = (110-10)/200 = 100/200 = 0.5f;
dist(p, E)=60
s = (60-10)/200 = 50/200 = 0.25f;
dist(p, E)=30
s = (30-10)/200 = 20/200 = 0.1f;
문제 5
기본 효과에서 gAlphaClip = false인 기법으로부터 생성된 어셈블리 코드와 gAlphaClip = true인 기법의 어셈블리 코드를 비교해보고 전자의 경우 discard함수가 존재하지 않음을 확인해 보라. discard는 HLSL의 clip에 대응되는 어셈블리 명령어이다.
해결
문제가 뭘 의도한 건지 잘 모르겠다.(-_-);;
문제 6
적색 채널과 녹색 채널로의 색상 쓰기를 비활성화하는 혼합 상태를 생성해서 적용하도록 혼합 예제를 수정하라.
해결
RenderTargetWriteMask를 통해 채널을 자유자재로 on 할 수 있다. 켜고 싶은 채널끼리 or로 연산해주면 된다.
'Graphics > DX11 물방울책 연습문제 풀이' 카테고리의 다른 글
DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 10 (1) 2021.05.26 DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 8 (0) 2021.04.24 DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 7 (0) 2021.04.03 DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 6 - 12 (0) 2021.03.24 DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 6 - 10 (0) 2021.03.23