항상 카메라를 향하는 객체를 GPU로 구현
3D 공간에서 카메라 앵글이 바뀌어도 항상 이쪽을 향하고 싶은 객체를 만들고 싶은 경우가 있습니다.
예를 들어, 2D 판에 텍스처를 붙이고, 그것을 항상 정면을 향하게 하는 것으로, 한 장 그림을 3D내에서 보이는, 라고 하는 테크닉(?)이 있습니다. 이런 평면을 판 다각형이나 빌보드 등이라고 부르기도 합니다.
before:
after:
이, 빌보드를 항상 카메라쪽으로 향하는 행위입니다만, 쉐이더로 간단하게 실장하는 방법을 알았으므로 소개해 보려고 생각합니다.
하는 방법은 매우 간단하고, 정점 쉐이더로, 클리핑 좌표를 계산하는 부분을 이하의 바꾸는 것 뿐입니다.
-OUT.vertex = UnityObjectToClipPos(IN.vertex); // 通常
+OUT.vertex = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0)); // 常にカメラを向く
왜 이것으로 항상 방향이 일정해지는지 조금 해설해 보려고 합니다.
우선, 변경 전의, 언제나 하고 있는 좌표 변환의
UnityObjectToClipPos
입니다만,최적화의 분기를 무시하면 대체로 이하와 같은 구현이 되어 있습니다.
mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));
음. 모델 변환, 뷰 변환, 프로젝션 변환의 행렬을 각각 곱하고 있을 뿐이지요.
(입력의 마지막 요소에
1.0
를 넣고 있는 것은, 3차원 벡터를 행렬로 좌표 변환할 때에, 이동(translate)도 허락하도록(듯이) 할 수 없다)위에서 등장하는 좌표변환을 위한 행렬의 상수에 대해 조금만 되돌아보자.
상수
의미
UNITY_MATRIX_P
프로젝션 변환. 카메라가 비추는 영역을 화면에 투영하는 변환
UNITY_MATRIX_V
뷰 변환. 월드 좌표에서 카메라를 원점에 놓았을 때의 좌표계로의 변환
unity_ObjectToWorld
소위 모델 변환. 로컬 좌표를 월드 좌표로 변환.
UNITY_MATRIX_M
라는 이름이 아닌 것이 이상하다(?)이것을 근거로, 얼마 안되는, 카메라를 향하면서 클리핑 좌표로 변환하는 코드를 다시 한번 보겠습니다.
mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0))
UNITY_MATRIX_MV
는 V와 M의 행렬을 미리 CPU측에서 곱한 것입니다. 한 번 그리기의 변화 행렬은 불확실하기 때문입니다. 그래서, 실질, 이하의 코드와 동등합니다.mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0)))
즉,
float(0,0,0.1)
에 대해서 M과 V의 변환을 하는 것으로, 오브젝트의 어느 정점의 계산도 모두 뷰 좌표계(카메라를 원점으로 한 좌표계)에 있어서의 원점이라고 하는 것에 일단 해 버립니다. (모든 정점이 원점에 있으면, 회전도 거짓이 없습니다) 그 후, 뷰 좌표계에 있어서의 2D상에서 x와 y를 더하는 것으로, 뷰 좌표계내에서 정점의 위치를 맞춥니다. 마지막으로 P 변환을 씌워 완성.셰이더로 구현하는 이점
마지막으로, 이와 같이 방향을 바꾸는 처리를 셰이더로 구현하는 메리트에 대해입니다.
Reference
이 문제에 관하여(항상 카메라를 향하는 객체를 GPU로 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/hadashiA/items/2c9271f47eb70eb9eb31텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)