Shader) Unity HLSL 행렬 변환
Shader를 작성하다 보면 꼭 마주치는 개념이 있다.
바로 행렬(Matrix) 변환이다.
오브젝트를 화면에 그리기까지는 다양한 공간 좌표계를 거치게 되는데, 이때 행렬 변환이 핵심적인 역할을 한다.
다행히도 Unity에서는 자주 사용하는 변환 행렬을 미리 선언해두고, Shader 코드에서 바로 사용할 수 있게 지원하고 있다.
공간 좌표계 요약
Shader에서 다루는 주요 공간은 아래와 같다.
- Object Space (모델 공간): 오브젝트 자체의 로컬 좌표계
- World Space (월드 공간): 씬 전체에서의 위치
- View Space (카메라 공간): 카메라를 기준으로 본 공간
- Clip Space (클립 공간): 최종적으로 GPU가 클리핑할 좌표계
주요 행렬 매크로
이름 | 설명 |
---|---|
UNITY_MATRIX_M unity_ObjectToWorld |
Object → World 변환. 모델 매트릭스 |
UNITY_MATRIX_I_M unity_WorldToObject |
World → Object 변환. 모델 행렬의 역행렬 |
UNITY_MATRIX_V |
World → View 변환. 뷰 매트릭스 |
UNITY_MATRIX_P |
View → Clip 변환. 투영 매트릭스 |
UNITY_MATRIX_MV |
Object → View 변환. 모델-뷰 매트릭스 |
UNITY_MATRIX_VP |
View → Clip 변환. 뷰-프로젝션 매트릭스 |
UNITY_MATRIX_MVP |
Object → Clip 변환. 가장 많이 쓰이는 MVP 매트릭스 |
UNITY_MATRIX_MVP
는 버텍스 쉐이더에서 거의 필수적으로 사용된다.
예제 코드
아래는 버텍스 쉐이더에서 UNITY_MATRIX_MVP
를 이용해 로컬 좌표를 클립 공간으로 변환하는 코드다.
float4 vert(appdata v) : SV_POSITION
{
return mul(UNITY_MATRIX_MVP, v.vertex);
}
만약 월드 좌표가 필요하다면, 다음과 같이 모델 행렬만 따로 사용할 수도 있다.
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
주의할 점
UNITY_MATRIX_I_M
과unity_WorldToObject
는 같은 의미지만, 내장 렌더 파이프라인에서는 후자만 제공된다.- URP에서는 둘 다 사용 가능하다.
mul(A, B)
는A * B
와 같지만, HLSL에서는 행 벡터 기준으로 작동하기 때문에 곱셈 순서에 주의해야 한다.
댓글남기기