베개발

[엔진심화] 09. 구조체, 벡터 연산, 변환 행렬 본문

대학교 공부

[엔진심화] 09. 구조체, 벡터 연산, 변환 행렬

rusal0204 2021. 6. 2. 23:55

목차

  • (지난시간 보충) 오브젝트 중심 거리에 의한 소팅의 한계
  • Lexical scope
  • 구조체
  • 벡터의 뺄셈
  • 공간 방향에서 수평 방향 얻기
  • 벡터의 내적 (dot)
  • lambert (맛보기)
  • 벡터의 MVP 변환
    - 변환 행렬의 이해

* 공부 과정에서 작성한 글이기 때문에 틀린 내용이 있을 수 있습니다.


오브젝트 중심 거리에 의한 소팅의 한계


왼쪽의 토끼는 반투명 오브젝트인데, 렌더링될 때 소팅 문제로 이상하게 보인다. (원래대로라면 오른쪽 토끼처럼 나와야 한다.

*텍스쳐는 다른걸 사용한게 맞다.)

빌보드 플랜이 아닌 복잡한 형태의 반투명 폴리곤은, 오브젝트 거리에 의한 소팅으로도 해결 불가능하다.

예를 들자면 옷의 소매가 반투명한다던지 등의 예시가 있을 것이다.

빌보드 평면도 오브젝트의 중심에 의한 거리 순서와 버텍스의 거리 순서에 오차가 발생하기도 한다.

 

 

Lexical Scope

지난 번 과제에서 변수의 Scope에 대해 알아보았다. 일반적으로 변수가 최초로 사용된 곳을 기준으로 스코프가 결정된다. 변수에 별다른 값을 입력하지 않고 단순히 변수를 적어주기만 하더라도 그 변수의 스코프가 결정되는 것이다.

그런데 Lecical Scopping에 의해서 이 개념이 조금 달라진다. Lexical Scopping은 하위 레벨의 스코프에서 local을 명확하게 명시함으로써 동일한 이름의 변수를 하위 레벨전용으로 사용될 수 있게 해 주는 기능이다.

간단히 말해서, 만약 a라는 이름의 변수를 상위 레벨에서 사용했었는데, 하위 레벨에서 a라는 똑같은 이름의 변수를 만들었을 시 하위 레벨에서 별도의 a라는 이름의 변수를 사용할 수 있는 것이다.

 

구조체 (Structure)

struct Attributes
{
	float4 positionOS	: POSITION;
    float2 uv			: TEXCOORD0;
 };

위 코드에서 struct가 구조체인데, 교수님께서는 구조체를 3첩쟁반이나 7첩반상같은 밥상으로 설명하셨다.

3첩쟁반이라는 struct를 정의하고, 그 안에는 float 대접, half 종지1, half 종지2 이렇게 3가지 그릇이 있다고 만들어준 다음에, 이렇게 만들어진 3첩쟁반 구조체를 사용할 때에는 3첩쟁반 철수네; 혹은 3첩쟁반 영희네; 이런 식으로 선언을 해준다.

그런 다음 각각의 대접과 종지1, 종지2에 무엇을 담을지 정해주면 된다.

쉽게 봤을때 일종의 템플릿(흔히 볼수있는 ppt템플릿 등)이라고 보면 될 것 같다.

 

 벡터의 뺄셈

★벡터의 뺄셈은 오브젝트가 바라보는 방향이 된다.

만약 아래와 같은 벡터들이 있다고 치면

A-B를 하면 C가 된다.

저번에 했던 벡터의 덧셈과 마찬가지로 (1-3,3-1)과 같이 계산해서 나온 결과가 C,즉 (-2,2)이다.

저 C는 B가 A를 바라보는 방향이다.

다만 그렇기 때문에, 덧셈과 달리 뺄셈은 서로 순서가 달라지면 안된다. A-B와 B-A는 결과값이 다르다는 말이다. 실제로 계산해봐도 A-B는 (-2,2)인 반면 B-A는 (2,-2)로 B가 A를 바라보는 방향과, A가 B를 바라보는 방향은 다르다.

이렇듯 벡터의 덧셈과는 달리 뺄셈은 순서가 중요하다.

 

공간 방향에서 수평 방향 얻기

(유니티 기준) 임의의 공간 벡터에서 수평 방향을 얻으려면, y축을 0으로 한 벡터를 정규화(normalize)하면 된다.

*위 설명에서 유니티 기준이라는 것은 유니티가 y-up 좌표계를 사용하고 있기 때문이다. 3d max 등의 z-up 좌표에서는 z축을 0으로 한 벡터를 정규화하면 된다.

쉽게 입체로 이해하자면, 위에서 바로 아래 방향으로 디렉셔널 라이트가 쬐어지고, 바닥에 그림자가 생기는 모습을 상상하면 되는데 이때 그림자가 z축(유니티는 y축)이 0으로 된 상황을 의미한다.

 

벡터의 내적 (dot)

폴리곤 표면의 빛을 계산하는 가장 기본적인 계산 방식이다.

dot 연산은 반드시 정규화 된 단위벡터를 사용해야 한다.

교수님이 주신 이미지

이 연산은 삼각함수와 관련이 있다. 특정 벡터의 각도에 대해 삼각함수를 계산해서 결과값을 내는 방식인데,

각도가 높아지면 높아질수록 값이 작아진다. 이 값을 빛의 양으로 계산하는 것이다.

위 사진처럼 위에서 빛을 쐈을 때, 각도가 커질수록 받는 빛의 양이 적어진다.

 

 벡터의 MVP 변환

- 변환 행렬의 이해

우리가 맥스에서 오브젝트를 이동하거나, 회전시키거나, 스케일을 조절하는 등 공간상의 변화를 주는 것은 행렬 연산이었다. 특정 변화값을 곱해주는 연산이었던 것이다. (매트릭스 연산이라고도 한다.)

출처: http://www.c-jump.com/bcc/common/Talk3/Math/Matrices/W01_0100_3d_transformations.htm

 위와 같은 연산들이 있다고 한다. 사진에서 볼 수 있듯 3D 변환은 4x4 행렬로 표현된다.

 

 

 

- 벡터의 MVP 변환

MVP변환의 MVP는 각각 Model, View, Projection을 나타낸다.

렌더링 파이프라인에서는 로컬 스페이스에서 월드 스페이스, 카메라 스페이스, 클립 스페이스, 스크린 스페이스까지 총 4번의 공간 변환을 거친다.

엔진 내에서는 위와 같은 변환 과정들이 행렬을 곱하는 식으로 진행된다.

유니티 렌더 파이프라인에서 공간 변환시 사용되는 내장변수를 미리 만들어 두었다고 한다.