구형을 사용해서 SkyBox만들기
- 회전할때 같이 회전되지 않도록 신경써야 한다.
SkyBox 너머에 있는 물체도 보이게끔 처리해줘야한다.
- 플레이어가 구체의 뒷면을 보고 있기 때문에 뒤를 보고 있어도 앞면이 보이게끔 해줘야 한다.
- 쉐이더에서
SkyBox을 그릴 때 Z값을 1에 가깝게 세팅
Global.fx
RasterizerState FrontCounterClockwiseTrue
{
FrontCounterClockwiseTrue = true;
};
Sky.fx
- 원래는
Local -> World -> View -> Proj 순서로 진행했지만, SkyBox를 바라볼때의 주체가 카메라 이기때문에 원점이 카메라이므로 World가 빠지면서 Local -> View -> Proj으로 진행하면 된다.
View로 갈 때, 회전값은 고정으로 가져가기 위해 w값을 0으로 정해두기
float4 viewPos = mul(float4(input.position.xyz, 0), V);이 부분이 빠지게 된다면, 물체와 카메라가 같이 돌아가기 때문에 같은 곳만 보게된다.
Rasterizer단계에서 position의 xyzw값이 w로 나눠지는데, 이때 z값에 w값을 넣어서 z값을 1로 만드는 방식
output.position.z = output.position.w * 0.9999999f; 이부분에서 곱해주는 값이 1일 경우에 깊이버퍼에서 같은 값이면 그리지 않게 설정해두었기 때문에 0.999999f를 곱해줘서 1은 아니지만 1과 근사한 값을 가지도록 해줘야한다. (여기서 0.99999999f까지 가게되면 1과 비슷하다고 판단해서 그려지지 않는다.)
#include "00.Global.fx"
#include "00.Light.fx"
struct VS_OUT
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};
VS_OUT VS(VertexTetrueNormalTangent input)
{
VS_OUT output;
float4 viewPos = mul(float4(input.position.xyz, 0), V);
float4 clipSpacePos = mul(viewPos, P);
output.position = clipSpacePos.xyzw;
output.position.z = output.position.w * 0.9999999f;
output.uv = input.uv;
return output;
}
float4 PS(VS_OUT input) : SV_TARGET
{
float4 color = DiffuseMap.Sample(LinearSampler, input.uv);
return color;
}
technique11 T0
{
pass P0
{
SetRasterizerState(FrontCounterClockwiseTrue);
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
};
SkyDemo
- Sky Texture를 Material로 Load, Mesh는 Sphere로 설정
void SkyDemo::Init()
{
RESOURCES->Init();
_shader = make_shared<Shader>(L"18.Sky.fx");
{
shared_ptr<Material> material = make_shared<Material>();
material->SetShader(_shader);
auto texture = RESOURCES->Load<Texture>(L"Sky", L"..\\Resources\\Textures\\Sky01.jpg");
material->SetDiffuseMap(texture);
MaterialDesc& desc = material->GetMaterialDesc();
desc.ambient = Vec4(1.f);
desc.diffuse = Vec4(1.f);
desc.specular = Vec4(1.f);
RESOURCES->Add(L"Sky", material);
}
{
_obj = make_shared<GameObject>();
_obj->GetOrAddTransform();
_obj->AddComponent(make_shared<MeshRenderer>());
{
auto mesh = RESOURCES->Get<Mesh>(L"Sphere");
_obj->GetMeshRenderer()->SetMesh(mesh);
}
{
auto material = RESOURCES->Get<Material>(L"Sky");
_obj->GetMeshRenderer()->SetMaterial(material);
}
}
_camera = make_shared<GameObject>();
_camera->GetOrAddTransform()->SetPosition(Vec3{ 0.f, 0.f, -10.f });
_camera->AddComponent(make_shared<Camera>());
_camera->AddComponent(make_shared<CameraScript>());
RENDER->Init(_shader);
}
결과

참고 강의
https://www.inflearn.com/courses/lecture?courseId=329791&type=LECTURE&unitId=161152&tab=script&category=questionDetail&q=1674815&subtitleLanguage=ko