HLSL은 부울, 정수, 부동소수점, 벡터, 행렬, 구조체 등의 데이터 타입을 지원한다.

분류를 나누면, 크게 스칼라 타입과 벡터타입, 그리고 구조체타입이 있다.


스칼라 타입
 타입  값
 bool  true 또는 false 를 갖으며, C의 bool 과 같다.
 int  32비트 부호있는 정수, C의 int 와 같다.
 half  16비트 부동소수점, float 의 반토막
 float  32비트 부동소수점, C의 float 과 같다.
 double  64비트 부동소수점, C의 double과 같다.

변수 선언 및 배열 선언은 C언어와 동일하다.


타입 수식어
  • const
  • row_major 또는 col_major

const 키워드
1. 상수성을 부여한다.
2. C와 동일하다.
3. 선언과 함께 초기화 해야 한다.


row_major 또는 col_major 키워드
1. 행렬 데이터에 쓰인다.
2. row_major는 행 우선순위로 행렬을 배치하며 col_major는 그 반대이다.
3. 이 키워드는 행렬의 데이터를 읽는 순서에 영향을 준다.
4. row_major는 행렬의 ↓ 순으로 읽고, col_major는 행렬의 → 순으로 읽는다.


기억 부류 수식어
1. 수식어의 변수 범위와 수명을 결정짖는다. C언어의 static, extern 등을 생각하면 될 것이다.
2. 기억부류 수식어는 static, extern, uniform, shared 가 있다.


static
1. 전역 변수에 쓰이면, 응용프로그램에서 접근할 수 없다.
2. 지역 변수에 쓰이면, C언어의 특성을 따른다.

extern
1. 전역변수에 쓰이며, 응용프로그램에서 접근할 수 있다.
2. 전역변수에 기본적으로 수식어가 없다면 extern 이 묵시적으로 선언된다.

uniform
1. HLSL 외부 즉, 쉐이더 외부에서 값이 변경된다는 의미만을 갖는다.

shared
1. 전역 변수에만 쓰일수 있다.
2. 이펙트 프레임웍에게 다수의 효과에 공유될 것만을 의미한다.(전역 변수 자체가 공유해서 씀)


벡터 타입
벡터는 1~4개의 성분을 갖는 특별한 데이터 구조이다.

int1 iVector;
half2 hVector;

등으로 쓸수 있으며, 데이터 타입 뒤에 붙은 정수가 Vector의 성분 갯수를 의미한다.
선언시 초기화도 가능하다.

예) int3 iVector = {1, 2, 3};

벡터타입은 아래와 같은 형태로 선언해도 된다.
vector<bool, 2> bVector = { true, false };

가독성은 템플릿 선언같은 vector<타입, 성분> 식으로 하는게 제일 보기가 좋다.


행렬 타입
행렬은 데이터의 행과 열을 포함하는 데이터 구조이며, 행렬의 데이터는 모든 스칼라 데이터 타입이 가능하다. 단, 모든 요소는 같은 데이터 타입이여야만 한다.

int1x1 iMatrix; // 1 By 1 행렬
또는
float4x4 fMatrix; // 4 By 4 행렬

주로 이런식으로 선언을 쓰며, 다른 방법으로
matrix<float 2, 2> fMatrix;
이런식으로 선언 가능하다.


생성자
생성자는 객체를 생성하고 초기화하는데 사용되며, C++ 형태와 유사하다.

즉 float3 upVector = float3(0.0f, 1.0f, 0.0f);
식으로 사용 가능하다.


캐스트
식의 형태가 일정하지 않을 때, 캐스트가 일어나며, HLSL 에서는 스칼라가 벡터나 행렬로 확장변환이 일으키는 것과, 벡터/행렬에서 더 복잡하지 않은 타입으로 축소 변환이 일어난다.

float4 v;
v = 1;
식에서 v는 float4 고 1은 int타입일 뿐이다. 이때 int 1 은 float4(1, 1, 1, 1) 로 확장변환된다.

float4 c;
float3 a, b;
a = b*c;
식에서 a = b * float3(c.x, c.y, c.z); 로 축소변환 된다.

정수의 산술연산
HLSL에서는 부동소수점 타입이 가장 효율적이다. HLSL 역시 int 데이터 타입을 지원하지만, 원시적인 int 데이터 타입과는 다르다.  하드웨어가 부동소수점 연산만 처리 하기 때문에, 정수 연산은 부동소수점 연산에 의하여, 정수 연산을 하므로 오차가 발생할수 있다.

int x = 3;
x = x / 3; 이라고 했을 경우, C에서는 1이겠지만 HLSL 에선 0이 나온다. ...
왜냐하면 HLSL은 보수와 곱셈을 지원하므로 x / 3 식은 x * 0.33333 = 0.99999로 되고 정수 타입으로 만들때 이 소수점을 날려버려 0이 되어 버린다;



복잡 데이터 타입
샘플러
샘플러는 일종의 구조체로 이미 몇가지가 정의되어 있다. 샘플러는 샘플러 스테이트가 정의되어 있으며 이것으로 텍슽쳐를 샘플링한다. 샘플링하기 위하여 필요한 3가지 요소가 있다.
1. 텍스쳐
2. 샘플러(그리고 샘플러 스테이트)
3. 샘플링 명령

texture tex0;
sampler2D s_2D = sampler_state
{
     textrue = (tex0);
     minfilter = LINEAR;
};

float2 PS( float2 tex : TEXCOORD0 ) : COLOR
{
     return tex2D(s_2D, tex);
}

이렇게 되어 있다고 친다면, tex2D 함수에서 샘플러 s_2D를 사용하여 tex좌표의 색을 읽어와 float2 를 반환한다고 볼수 있다.


구조체
struct 키워드를 사용해 구조체 타입을 정의할수 있다.
struct VS_OUT
{
    float4 a;
    float4 b;
    float4 c;
};

이런식으로 사용 가능하다.

버텍스 쉐이더 객체
vertexshader 선언으로 객체 생성을 할수 있다.
vertexshader vs = asm {
vs_2_0
dcl_position v0
mov oPos, v0
};

이런식으로 선언 가능하다.

픽셀 쉐이더 객체
pixelshader ps = asm { ...... } 버텍스와 형식은 똑같다.

이렇게 해도 가능하고, 함수를 컴파일하여 픽셀 쉐이더나 버텍스 쉐이더객체에 할당할수 있따.
vertexshader vs = compile vs_2_0 vsmain();
pixelshader ps = compile ps_2_0 psmain();

compile 은 컴파일하여 컴파일된 객체를 반환한다.
vs_2_0 은 이 버전으로 컴파일 하라는 옵션이다.
vsmain() 은 .. 컴파일 대상이다.
이렇게 나온 객체는 vs 에 들어간다.


텍스쳐
texture 데이터 타입은 텍스처 객체를 나타내며, 이 데이터 타입은 각종 이펙트에 쓰일 텍스처 장치에 설정된다.
sampler 1D_samper = sampler
{
     texture = (tex0);
};
이 식은 픽셀쉐이더에서 무시되며, 오로지 이펙트에서만 사용 가능하다.










posted by 농사를 짓는 게임 프로그래머 최익필
TAG ,

댓글을 달아 주세요

  1. Favicon of http://blog.naver.com/cor2738 그라파 2009.08.24 12:02  Addr  Edit/Del  Reply

    좋은 정보 감사합니다. 담아갈께요

  2. 매커 2010.10.18 14:37  Addr  Edit/Del  Reply

    좋은 정보 잘 보고 갑니다. ^^;

  3. 크래이 2011.04.20 11:35  Addr  Edit/Del  Reply

    저... 정수 산술 연산 부분에요.
    x/3 하면 소수점이 날아가면서 0이 되는 것 맞죠?
    뉘앙스는 그런데 1이라고 적혀있어서요 ^^

  4. redball 2012.05.07 12:15  Addr  Edit/Del  Reply

    잘보고 갑니다!!!