본문 바로가기
셰이더 (Shader)/셰이더 프로그래밍 입문 - Pope Kim (완)

[HLSL] 챕터3 - 텍스쳐매핑

by Minkyu Lee 2023. 3. 18.

 

// 텍스쳐 매핑이란?

텍스쳐를 입히는 것을 텍스쳐매핑이라고 부른다. (texture mapping)

 

// UV란?

3D 물체 구성요소는 삼각형이다.

삼각형 위 이미지를 입히려면 어떻게 해야하는가?

 

정점을 픽셀에 대응시켜준다.

값을 0~1 사이의 백분율로 표현한다.

이를 UV라고 부른다.

 

이렇게 다른 두 점을 대응 시키는 것을 매핑이라고 한다.

 

정점셰이더

float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;

struct VS_INPUT
{
   float4 mPosition : POSITION;
   float2 mTexCoord : TEXCOORD0;
};

struct VS_OUTPUT
{
   float4 mPosition : POSITION;
   float2 mTexCoord : TEXCOORD0;
};

VS_OUTPUT vs_main(VS_INPUT Input)
{
   VS_OUTPUT Output;
   Output.mPosition = mul(Input.mPosition, gWorldMatrix);
   Output.mPosition = mul(Output.mPosition, gViewMatrix);
   Output.mPosition = mul(Output.mPosition, gProjectionMatrix);
   Output.mTexCoord = Input.mTexCoord;
   return Output;
}

텍스쳐 매핑을 하려면 새로운 데이터가 필요하다.

텍스쳐로 사용할 이미지가 그것이다.

 

텍스쳐는 픽셀에 입힌다.

따라서 픽셀셰이더에서 텍스쳐매핑 해야한다.

이미지는 텍스쳐로 사용하기 때문에 정점셰이더에서 선언할 필요가 없다.

 

// UV좌표가 필요하다.

UV 좌표는 각 정점마다 지정하기 때문이다.

각 정점마다 이므로 전역변수가 아니다. 정점데이터의 일부로 지정된다.

 

// UV 좌표는 float2이다.

어떤 시맨틱을 사용하는가 TEXCOORD이다.

0을 붙인 이유는 HLSL에서 지원하는 수가 여러개이기 때문이다.

여러개 동시 사용시 0 1 등으로 뒤에 숫자를 붙인다.

 

// 정점셰이더는 위치 정보 외에 다른 것도 반환할 수 있다.

이는 래스터라이저가 아니라 픽셀셰이더를 위해서 반환한다.

그 예로 UV 좌표가 있다.

 

// 보간기 (UV 전달과 관련)

픽셀셰이더는 정점버퍼 데이터에 직접 접근하지 못한다.

따라서 정점셰이더를 거쳐 전달되어야한다.

그 이유는 무엇인가?

 

세 정점까지의 거리를 구한 뒤 비율에 따라 UV 값을 혼합해야 하기 때문이다.

이는 자동으로 처리된다.

정점 이외의 기타 정보를, 보간기(interpolator)라는 장치가 혼합해준다.

 

// 수정된 3D 파이프라인

정점셰이더 -> 래스터라이저 / 보간기 -> 픽셀셰이더 -> 화면

 

여전히 간략화한 버전이다.

 

// UV 좌표는 공간변환을 적용하지 않는다.

3차원 공간에 존재하지 않기 때문이다.

삼각형 표면상에 존재한다.

따라서 변환이 필요치 않다.

 

픽셀셰이더

sampler2D DiffuseSampler;

struct PS_INPUT
{
   float2 mTexCoord : TEXCOORD0;
};

float4 ps_main(PS_INPUT Input) : COLOR
{
   float4 albedo = tex2D(DiffuseSampler, Input.mTexCoord);
   return albedo.rgba;
}

텍셀을 구해와 그 색을 화면에 출력하는 코드이다.

 

// 텍셀이란

텍스쳐의 최소 구성단위를 말한다.

 

// 텍스쳐로 사용할 이미지와 UV 좌표가 필요하다.

이미지는 전역변수로,

UV 좌표는 정점셰이더를 거친 입력데이터로 받는다.

 

// 픽셀셰이더의 입력데이터

정점셰이더의 출력데이터와 일치할 수 밖에 없다.

반환 값을 그대로 가져오는 것이기 때문이다.

 

// 텍스쳐 샘플러

텍셀을 구할 때 사용하는 것이 텍스쳐 샘플러이다.

 

- sampler2D

HLSL에서 지원하는 데이터형중 하나이다.

2D 텍스쳐에서 텍셀 하나를 구해오는데 사용한다.

 

// 샘플링

UV값과 텍스쳐 샘플러가 있다.

이제 이 둘을 이용해 텍셀 값을 구해야한다.

( 의문 : 텍스쳐 샘플러는 단순히 텍셀 그 자체를 구해오고 거기서 값을 추출하는 것은 별개인 것인가?)

 

텍셀 값을 구하는데는 내장함수인 tex2D를 사용한다.

사용법은 tex2D(텍스처 샘플러, UV좌표) 이다.

이를 샘플링한다고 말한다.

댓글