UI

ㅋㅋ·2022년 7월 26일
0

DirectX12강의

목록 보기
28/39

직교 투영

투영 시 깊이 값에 따라 물체의 비율이 정해지지 않고,

고정된 비율을 가지고 투영시키는 것

2d 게임이나, 3d 게임의 2d UI로 사용 시 필요

window
height: h
width: w

z
far: f
near: n
=>

x: 2x / w
y: 2y / h
z: (z - n) / (f - n)

M=[2/w00002/h00001/(fn)000n/(fn)0]M = \left[ \begin{matrix} 2/w & 0 & 0 & 0 \\ 0 & 2/h & 0 & 0 \\ 0 & 0 & 1/(f-n) & 0 \\ 0 & 0 & -n/(f-n) & 0\end{matrix} \right]


hlsl 컴파일러

비주얼 스튜디오 프로젝트에 fx나 hlsl 파일이 있을 경우

hlsl 컴파일러를 사용하여 쉐이더 문법 오류를 알 수 있음


기본적으로 UI를 찍는 직교 투영 카메라와

유저가 바라보는 게임 화면을 찍는 원근 투영 카메라 두 대를 이용하여

두 장면을 합성한다.

유니티에서는 UI 레이어를 가진 객체만 직교 투영 카메라가 찍게 된다.

임시적으로 Scene manager에서 layer들을 관리

gameObject 클래스에는 자신이 가질 layer를 구현

void Camera::FinalUpdate()
{
	...

	if (_type == PROJECTION_TYPE::PERSPECTIVE)
		_matProjection = ::XMMatrixPerspectiveFovLH(_fov, width / height, _near, _far);
	else
		_matProjection = ::XMMatrixOrthographicLH(width * _scale, height * _scale, _near, _far);

	...
}

void Camera::Render()
{
	...
	for (auto& gameObject : gameObjects)
	{
		...

		if (IsCulled(gameObject->GetLayerIndex()))
			continue;

		...

		gameObject->GetMeshRenderer()->Render();
	}
}

camera 클래스에는 자신의 투영 타입을 설정하고 자신이 찍을 layer를 검사하도록 구현


shared_ptr<Scene> SceneManager::LoadTestScene()
{
	...
    
    {// UI camera
		shared_ptr<GameObject> camera = make_shared<GameObject>();
        
		...
        
		camera->GetCamera()->SetProjectionType(PROJECTION_TYPE::ORTHOGRAPHIC);
		uint8 layerIndex = GET_SINGLE(SceneManager)->LayerNameToIndex(L"UI");
		camera->GetCamera()->SetCullingMaskAll();
		camera->GetCamera()->SetCullingMaskLayerOnOff(layerIndex, false);
		scene->AddGameObject(camera);
	}
    
    {// UI retangle
		shared_ptr<GameObject> sphere = make_shared<GameObject>();
		sphere->SetLayerIndex(GET_SINGLE(SceneManager)->LayerNameToIndex(L"UI"));
		
        ...
        
		{
			shared_ptr<Mesh> mesh = GET_SINGLE(Resources)->LoadRectangleMesh();
			meshRenderer->SetMesh(mesh);
		}
        
		...
	}
    ...
}

UI용 카메라는 UI 레이어를 가진 물체만을 투영하도록 설정하고

UI로 사용할 객체는 레이어를 UI로 설정


Swap Chain에서 사용하는 render target view buffer는 하나이기 때문에

카메라마다 렌더한 정보가 버퍼를 계속 덮어쓰게 됨

0개의 댓글