1. EX App Program
1.1 Mirror
1.1.1 Mirror System
- 물체의 반사상을 그리려면 거울 평면에 대해 그 물체를 반사시켜 렌더링
- 위의 방식만 할 경우 장면의 또 다른 물체일 뿐 다른 물체가 가리지 않는 이상 전체가 눈에 보임
- 거울 바깥의 영역이 물체를 가릴 수 있어야 함
- 후면 버퍼의 특정 영역에 픽셀들이 그려지지 않게 하는 스텐실 버퍼를 사용하여 해결
- 반사된 두개골의 픽셀들 중 거울 표면 영역 바깥에 있는 픽셀들은 스텐실 버퍼를 통해 폐기
/* Mirror System */ /* 벽, 거울, 두개골 */
- 바닥과 벽, 두개골을 보통의 방법으로 렌더링, 거울은 아직 그리지 않음
- 스텐실 버퍼를 0으로 지우고 거울을 스텐실 버퍼에만 렌더링
- 후면 버퍼에 색상 성분들이 기록되지 않게 하는 경우 Depth & Stencil 상태 변경
D3D11_DEPTH_STENCIL_DESC::DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
D3D11_RENDER_TARGET_BLEND_DESC::RenderTargetWriteMask = 0;
- 거울을 스텐실 버퍼에 렌더링할 때 스텐실 판정이 항상 성공하도록 설정
- 판정 성공 시 스텐실 버퍼 항목이 1로 대체, 실패하는 경우 행동방식은 유지
- 거울만 스텐실 버퍼에 렌더링하는 것
- 스텐실의 항목 중 거울의 가시적인 부분의 픽셀에 해당하는 항목들은 모두 1, 그외 항목들은 모두 0
- 반사된 두개골을 후면 버퍼와 스텐실 버퍼에 렌더링, 픽셀이 스텐실 판정을 통과한 경우에만 후면 버퍼에 기록
- 거울 자체를 후면 버퍼에 통상적인 방식으로 렌더링하되, 반사된 두개골이 가려지지 않도록 투명도 혼합 적용
- 거울을 투명하게 렌더링하지 않는다면 거울의 깊이가 반사된 두개골의 깊이보다 작으므로 거울이 반사상을 가림
mMirrorMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mMirrorMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 0.5f);
mMirrorMat.Specular = XMFLOAT4(0.4f, 0.4f, 0.4f, 16.0f);
1.1.2 C++ 응용 프로그램 구조체
- 거울 픽셀들을 스텐실 버퍼에 기록하기 위해 거울을 렌더링할 때 사용하는 구조체
/* 중요한 부분만 기록, 나머지 제외 */
D3D11_DEPTH_STENCIL_DESC mirrorDesc;
mirrorDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
mirrorDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
mirrorDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
mirrorDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
mirrorDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
HR(device->CreateDepthStencilState(&mirrorDesc, &MarkMirrorDSS));
- 반사된 두개골을 거울의 가시적 부분에만 그릴 때 사용하는 구조체
/* 중요한 부분만 기록, 나머지 제외 */
D3D11_DEPTH_STENCIL_DESC drawReflectionDesc;
drawReflectionDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
drawReflectionDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
drawReflectionDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
drawReflectionDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
drawReflectionDesc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;
HR(device->CreateDepthStencilState(&drawReflectionDesc, &DrawReflectionDSS));
1.1.3 C++ 응용프로그램 Draw Scene
- 거울을 생성할 때 스텐실 버퍼 항목이 1과 같은 픽셀만 렌더링하고 기본 상태들은 복원
activeTech->GetDesc(&techDesc);
for (uint32 p = 0; p < techDesc.Passes; ++p)
{
/* ... */
_deviceContext->OMSetDepthStencilState(RenderStates::MarkMirrorDSS.Get(), 1);
/* ... */
_deviceContext->OMSetDepthStencilState(0, 0);
_deviceContext->OMSetBlendState(0, blendFactor, 0xffffffff);
}
- 반사된 두개골을 그리기 위해 기존 좌표와 xy 평면 축을 이용하여 위치를 반대방향으로 이동
XMVECTOR mirrorPlane = ::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
XMMATRIX R = ::XMMatrixReflect(mirrorPlane);
XMMATRIX world = ::XMLoadFloat4x4(&_skullWorld) * R;
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
XMMATRIX worldViewProj = world * view * proj;
- 광원 또한 방향을 반사시켜야 하므로 이전에 사용한 광원을 사용하여 계산
- 거울에만 비추게 설정하기 위해 스텐실 버퍼 항목이 1과 같은 픽셀만 렌더링하고 광원과 스텐실 버퍼 복원
_deviceContext->OMSetDepthStencilState(RenderStates::DrawReflectionDSS.Get(), 1);
- 마지막으로 거울을 통상적인 방식으로 후면 버퍼에 렌더링하되, 반사상이 통과해 보이도록 투명도 혼합 적용
_mirrorMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
_mirrorMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 0.5f);
_mirrorMat.Specular = XMFLOAT4(0.4f, 0.4f, 0.4f, 16.0f);
Effects::BasicFX->SetMaterial(_mirrorMat);
- 모든 사항을 적용시킨 거울을 생성
_deviceContext->OMSetBlendState(RenderStates::TransparentBS.Get(), blendFactor, 0xffffffff);
pass->Apply(0, _deviceContext.Get()); _deviceContext->Draw(6, 24);
1.1.4 정점 감김 순서와 반사
- 삼각형을 한 평면에 반사시켜도 정점들이 감기는 순서가 뒤집히지는 않으며, 면 법선도 뒤집히지 않음
- 반시계방향으로 감긴 삼각형을 전면 삼각형으로 간주하고 시계방향으로 감긴 삼각형을 후면 삼각형으로 간주
D3D11_RASTERIZER_DESC cullClockwiseDesc;
ID3D11RasterizerState* CullClockwiseRS;
HR(device->CreateRasterizerState( ScullClockwiseDesc, &CullClockwiseRS));
- 나머지 부분은 처음 생성한 예제 프로그램을 수정
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 25. EX App Program - Billboard (0) | 2023.06.20 |
---|---|
[Direct11] 24. Direct3D Geometry Shader (0) | 2023.06.20 |
[Direct11] 22. Direct3D Stencil (0) | 2023.06.19 |
[Direct11] 21. EX App Program - Fog System (1) | 2023.06.17 |
[Direct11] 20. Direct3D Blending - Blending System (0) | 2023.06.17 |