-
[DirectX11] CubeMap 적용DirectX11 2023. 12. 20. 11:35
큐브맵으로 배경에 이미지를 씌우는 과정이다.
여기에 사용될 이미지는 HDRI 이미지를 큐브맵으로 변환해서 사용했다.
HDRI 이미지는 이곳에서 구했다.
HDRIs • Poly Haven
Previously known as HDRI Haven. Hundreds of free HDRI environments, ready to use for any purpose. No login required.
polyhaven.com
HDRI 이미지를 큐브맵으로 변환해주는곳
https://matheowis.github.io/HDRI-to-CubeMap/
HDRI to CubeMap
matheowis.github.io
변환한 뒤에 6면을 따로 받으면 된다.
큐브맵 이미지는 DirectX Texture Tool로 제작했다.
2010년 버전 DirectX SDK를 설치하면 포함되는 툴이다.
https://www.microsoft.com/en-us/download/details.aspx?id=6812
Download DirectX SDK - (June 2010) from Official Microsoft Download Center
This download is the legacy DirectX SDK. It is now end-of-life and should only be used for maintaining older software. For targeting DirectX for Windows 7 or later, use the modern Windows SDK instead.
www.microsoft.com
HDRI 이미지는 이것을 사용했다.
https://polyhaven.com/a/kloofendal_overcast
Kloofendal Overcast HDRI • Poly Haven
Download this free HDRI from Poly Haven
polyhaven.com
다운로드 옆에 메뉴를 열어서 8K jpg 파일로 다운받았다.
그 다음에 큐브맵으로 변환해서 다운받으면 아래처럼 된다.
해상도는 2048px로 했다.
DirectX Texture Tool에서 새로운 텍스쳐를 만들고 큐브맵을 선택하고 해상도도 2048으로 지정한다.
면을 변경하면서 텍스쳐를 지정하면 큐브맵 텍스쳐가 만들어진다.
면 선택 해당하는 면에 텍스쳐 지정 이렇게 해서 큐브맵에 사용할 DDS 텍스쳐 파일을 생성했다.
다음으로 큐브맵에 사용될 정육면체 모델을 만든다.
블렌더를 켜면 기본으로 생성되는 2m 크기의 정육면체 큐브를 사용했다.
이 큐브를 Edit 모드에서 면의 노멀을 뒤집고 export 했다.
블렌더에서 노멀 뒤집는 방법
다음으로 다이렉트x에서 큐브맵을 적용한다.
기본적으로 필요한것을 모델을 그릴때 필요한 버텍스 버퍼와 인덱스 버퍼, 텍스쳐를 사용하기위해 필요한 쉐이더 리소스 뷰다.
큐브맵을 위해서 필요한 것은 다음과 같다.
- 버텍스 쉐이더
- 픽셀 쉐이더
- 뎁스 스텐실 스테이트 (
ID3D11DepthStencilState
)
내가 사용한 방식은 다음과 같다.
뎁스 스텐실 스테이트를 설정해서 깊이를 계산하지 않게하고, 그 상태에서 큐브맵을 그린다.
이때 큐브맵 모델은 카메라의 위치를 따라다니게 해서 카메라가 항상 큐브맵 내부 중앙에 있는것처럼 보이게 했다.
그 다음에 기존의 뎁스 스텐실 스테이트를 다시 적용하고, 월드 공간의 오브젝트를 렌더해서 큐브맵 위에 덮어씌우는 방식을 사용했다.
블렌더에서 따라해보면 이런 느낌이다.
조작하는 오브젝트가 카메라고, 정육면체가 큐브맵이다.
뎁스 스텐실 스테이트 설정
D3D11_DEPTH_STENCIL_DESC dsDesc; ZeroMemory(&dsDesc, sizeof(dsDesc)); dsDesc.DepthEnable = false; dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDesc.DepthFunc = D3D11_COMPARISON_NEVER; dsDesc.StencilEnable = false; dsDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; dsDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER; dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; hr = g_pd3dDevice->CreateDepthStencilState(&dsDesc, &g_pSkyDepthStencilState); if (FAILED(hr)) return hr;
깊이 비교를 하지 않게 설정했다.
TextureCube
TextureCube txSkyBox : register(t0);
큐브맵에 사용되는 텍스쳐를 큐브맵 텍스쳐이므로 쉐이더에서 해당 텍스쳐를 받을때
Texture2D
가 아니라TextureCube
타입으로 받아야한다.이 타입은 2d 텍스쳐의 배열로 되어있으며, 텍스쳐를 샘플할때 float2가 아니라 float3를 받는다.
버텍스 쉐이더
struct VS_OUTPUT_Sky { float4 Pos : SV_POSITION; float3 TexCoord : TEXCOORD0; }; // ... VS_OUTPUT_Sky VS_Sky(VS_INPUT input) { VS_OUTPUT_Sky output = (VS_OUTPUT_Sky) 0; matrix ViewPosMat = { 1.f, 0.f, 0.f, 0.f, // column 0 0.f, 1.f, 0.f, 0.f, // column 1 0.f, 0.f, 1.f, 0.f, // column 2 vViewPosWorld.x, vViewPosWorld.y, vViewPosWorld.z, 1.f // column 3 }; output.Pos = mul(input.Pos, ViewPosMat); output.Pos = mul(output.Pos, mView); output.Pos = mul(output.Pos, mViewProjection); output.TexCoord = normalize((float3) input.Pos); // or output.TexCoord = (float3) input.Pos; return output; }
카메라 위치 벡터인
vViewPosWorld
는 버퍼를 통해 받은 값이다.이 값은 이전에 Specular BRDF를 계산할때 사용되고있었고, 이미 버퍼를 통해 매 프레임마다 갱신해주고있는 상황이어서 그대로 사용했다.
큐브맵에 사용되는 정육면체 모델을 카메라 위치로 translation 해주는 행렬을 생성해서 그 값을 곱했다.
HLSL은 열 우선이므로 행렬을 생성할때 열을 기준으로 작성해준다.
TexCoord
는 픽셀 쉐이더에서 텍스쳐를 샘플할때 사용되는데 위와 같이 정점의 좌표를 지정해준다.normalize한 결과와 하지 않은 결과의 차이는 없는듯 하다.
픽셀 쉐이더
float4 PS_Sky(VS_OUTPUT_Sky input) : SV_Target { return txSkyBox.Sample(samLinear, input.TexCoord); }
결과
'DirectX11' 카테고리의 다른 글
[DirectX11] chrono로 정확한 DeltaTime 구하기 (1) 2023.12.18 [DirectX11] 1인칭 카메라 조작 (0) 2023.12.18 [DirectX11] 쉐도우 맵과 PCF(Percentage Closer Filtering) (3) 2023.12.15 [DirectX11] 텍스쳐와 노멀매핑 (1) 2023.12.13 [DirectX11] Disney Diffuse (0) 2023.12.12