게임 내의 하늘을 구현하는 방법이다.
카메라의 가시영역의 끝이 1이라고 가정할 때 거대한 큐브를 만들어 그 안에 카메라를 넣는 방식으로 구현한다.
카메라를 skybox 안에 넣고 별 다른 수정이 없다면 문제가 발생한다.
플레이어가 움직여 skybox에 접근하게 될 경우 skybox를 뚫고 지나가게 된다.
skybox에 가까워질 수록 sky에 해당하는 텍스처가 더 가까이 보이게된다.
Culling에 의해서 반 시계방향으로 이루어진 정점을 그리지 않는다. 카메라는 skybox 큐브 내부에 존재하므로 카메라의 위치에서 보면 skybox는 반 시계방향으로 이루어진 정점들이다. 따라서 그려지지 않는다.
위와 같은 경우는 실제 하늘과 차이가 발생하므로 우리는 몇가지 코드상의 수정을 통해 실제 하늘과 유사하게 구현한다.
// Translation은 하지 않고 Rotation만 적용한다
float4 viewPos = mul(float4(input.localPos, 0), g_matView);
float4 clipSpacePos = mul(viewPos, g_matProjection);
// w/w=1이기 때문에 항상 깊이가 1로 유지된다
output.pos = clipSpacePos.xyww; // z값을 w로 하여 깊이값을 1로 세팅하겠다는 의미
output.uv = input.uv;
shader->Init(L"..\\Resources\\Shader\\skybox.hlsli",
{ RASTERIZER_TYPE::CULL_NONE, DEPTH_STENCIL_TYPE::LESS_EQUAL });
switch (info.rasterizerType)
{
case RASTERIZER_TYPE::CULL_BACK:
_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
break;
case RASTERIZER_TYPE::CULL_FRONT:
_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT;
break;
case RASTERIZER_TYPE::CULL_NONE:
_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
break;
case RASTERIZER_TYPE::WIREFRAME:
_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME;
_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
break;
}
switch (info.depthStencilType)
{
case DEPTH_STENCIL_TYPE::LESS:
_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
break;
case DEPTH_STENCIL_TYPE::LESS_EQUAL:
_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
break;
case DEPTH_STENCIL_TYPE::GREATER:
_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER;
break;
case DEPTH_STENCIL_TYPE::GREATER_EQUAL:
_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
break;
}
skybox shader을 조정하는 부분이다. 설정 값에 따라 culling 규칙과 카메라의 가시범위를 조정해준다.
위 코드는 카메라의 가시범위 1보다 작거나 같은 위치에 있는 Object를 그리도록 설정해주었고 시계방향정점과 반시계방향 정점 모두 그리도록 설정하였다.