새소식

개발/Shader

[Snow Footprint] 02.Tessellator - 02 (Tessellator and Domain Stage)

  • -

이번 포스팅은 저번 포스팅에 이어 Tessellator Stage에 대한 이야기를 해볼까 합니다.

이전에 Hull Shader Stage에서 폴리곤을 어떤 기준으로 그리고 얼마나 분할 할 것인가를 정했습니다.

Tessellator Stage에서는 이 결과를 Input으로 받아 Domain Shader에서 사용할 '무게중심'을 계산합니다.

하지만 이 스테이지는 프로그래머가 제어 할 수 없는 영역이기 때문에, 이 계산과정에 대한 설명만을 설명 한 뒤 이번 포스팅은 넘어가도록 하겠습니다.


1. 무게중심좌표

무게중심좌표를 구하는 방법은 다양합니다. Vertex Averaging을 통해 나온 결과도 무게 중심좌표이지만 지금 설명하려는 방법으로도 구할 수 있습니다.

설명에 앞서 다음과 같은 외적의 기하학적 의미를 알고 있어야 합니다.

- A X B 의 결과는 두 벡터에 수직인 벡터 C 다.
- C 의 길이는 A와 B로 이루어진 평행사변형의 넓이다.

이 성질은 다음과 같은 중심좌표 표현법에서 유용하게 사용됩니다.

위 그림에선 중심좌표 P를 각 꼭지점의 비율로 구성합니다. 

다만 w (가중치)는 어떻게 구할 수 있을까요?

방법은 각 꼭지점의 맞은편에 있는 삼각형의 넓이를 전체 삼각형의 넓이로 나누는 것 입니다.

      • w1 = 삼각형 BCP의 넓이 / 삼각형 ABC의 넓이
      • w2 = 삼각형 ACP의 넓이 / 삼각형 ABC의 넓이
      • w3 = 삼각형 ABP의 넓이 / 삼각형 ABC의 넓이
      • w1 + w2 + w3 = 1 만족

이 방법은 비율을 따져서 중심좌표를 구하기 때문에, Triangle에서도 Quad에서도 사용가능하며 도형의 면적을 이용한 좌표라해서
'면적좌표'라고도 불립니다.

이 과정을 CG 언어로 작성하면 다음과 같이 작성 할 수 있습니다.

float3 CalculateBC(float3 vecP, 
				  float3 vecA, 
				  float3 vecB, 
				  float3 vecC)
			{
				float3 vecResult;
				float3 vecCross;
				float3 a2b = vecB - vecA;
				float3 a2c = vecC - vecA;
				float3 a2p = vecP - vecA;

				vecCross = cross(a2b, a2c);
				float totalArea = length (vecCross);

				vecCross = cross(a2b, a2p);
				float subArea = length(vecCross);
				vecResult.z = subArea/totalArea;

				vecCross = cross(a2c, a2p);
				subArea = length(vecCross);
				vecResult.y = subArea/totalArea;

				vecResult.x =  1 - (vecResult.z + vecResult.y);
				return vecResult;
			}

 테셀레이터 내부에선 위와 비슷한 방법으로 무게중심의 가중치를 구합니다. 이 과정은 앞서 설명드렸듯 프로그래머가 관여 할 수 없는 고정 기능입니다.

이후 이 가중치들은 Domain-Shader로 전달되어 사용됩니다.

(MSDN에서 정의한 Domain-Shader의 가장 기초적인 형태)

[domain("tri")]
DS_OUTPUT DS( HS_CONSTANT_DATA_OUTPUT input, 
                    float3 UVW : SV_DomainLocation,
                    const OutputPatch patches
{
   DS_OUTPUT Output;
    ...
    return Output;    
}

이제 기본적인 Hull Shader와 Tessellator, Domain Shader의 흐름과 개념을 익히는것이 끝났습니다.

다음 포스팅에서는 기존 Wave Deformer을 개량하는 예제와 풀이를 올리도록 하겠습니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.