헤더파일
셰이더공부 - 텍스쳐 매핑 본문
텍스쳐 좌표는 위치를 표현하는 x,y와 구별하기 위해 u,v로 나타냅니다.
3D물체를 이루는 구성요소는 삼각형이므로 2번 삼각형의 왼쪽꼭지점에 이미지의 오른쪽 귀퉁이 픽셀을 출력할 것과 같은 지시를 내릴 수 있습니다. 텍스처위의 픽셀을 정수로 나타내면 이미지 파일 크기에 따라 유동적이게 되므로 색깔과 같이 백분율(0~1사이 값)로 나타냅니다.
uv 좌표의 범위에 따라 다양한 효과를 줄 수 있습니다. (1,0) ~ (0,1)로 하면 텍스처의 좌우를 뒤집을 수 있고 (0,0) ~ (1,2)로 하면 텍스처가 위아래로 두번 반복할 수 있습니다.
1. 정점셰이더
텍스처 매핑을 하려면 텍스처로 사용할 이미지 하나가 필요합니다. 텍스처를 입히는 작업은 어디에서 해야 할까요? 텍스처는 정점에 입히는 게 아니라 표면을 구성하는 모든 픽셀에 입혀야 합니다. 정점셰이더는 각 정점마다 실행되므로 이 작업은 각 픽셀마다 호출이 되는 픽셀셰이더에서 해야합니다. 따라서 저번 셰이더에서 변한 부분은 입력받은 텍스쳐 좌표를 픽셀셰이더로 전달하는 것 밖에 없습니다.
어떻게 보면 불필요한 작업으로 볼 수 있는데 픽셀셰이더는 정점버퍼데이터에 직접적으로 접근을 못하기 때문에 이런 작업을 해야합니다. 그렇다면 이런 제약은 왜 뒀을까요? 정점셰이더에서 전달한 위치정보를 래스터라이저가 알아서 처리해줬듯이 정점 이외의 기타 정보는 보간기라는 장치가 알아서 혼합해주기 때문입니다. uv의 좌표는 정점별로 정의 되어있기 때문에 이를 픽셀단위로 계산하려면 세 정점의 거리를 구한 뒤 그 거리의 비율에 따라 세 uv값을 혼합해야 합니다. 이 작업을 보간기가 해주기 때문에 uv좌표는 정점셰이더에서 반환되어야 합니다.
struct VS_INPUT
{
float4 mPosition : POSITION;
float2 mTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 mPosition : POSITION;
float2 mTexCoord : TEXCOORD0;
};
float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;
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;
}
2. 픽셀셰이더
픽셀셰이더에서 할 일은 텍스처 이미지에서 텍셀(텍스처의 최소 구성 단위)을 구해와 그 색을 화면에 출력하는 것입니다. Sampler2D 자료형은 HLSL에서 지원하는 텍스처 개체 자료형으로 DirectX상에서 ID3D11ShaderResourceView* 변수를 만들어서 전달받습니다.
PS_INPUT으로 보간기를 거쳐서 나온 uv를 좌표를 받습니다. 이는 정점셰이더와 픽셀셰이더의 입력데이터 시멘틱으로 연결됩니다. 즉 같은 이름의 시멘틱을 써서 연결하는 것입니다.
이렇게 얻은 두가지 정보로 텍스처 파일에 텍셀을 구해야 하는데 이는 HLSL의 내장 함수 tex2D를 사용하면 매우 쉽게 할 수 있습니다. tex2D함수에 샘플러와 uv좌표를 전달해서 얻은 텍셀을 return하면 텍스처가 입혀져 출력하게 됩니다.
sampler2D DiffuseSampler;
struct PS_INPUT
{
float2 mTexCoord : TEXCOORD0;
};
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 albedo = tex2D(DiffuseSampler, Input.mTexCoord);
return albedo.rgba;
}
albedo.rgba 에 rgba는 색깔 벡터의 기본 성분인 red, green, blue, alpha 에 접근한 것입니다. 이렇게 순서 대로 접근하는 것 뿐만 아니라 rrra, bgra 등 벡터의 성분을 마음대로 순서를 바꿔서 반환하는 것도 가능합니다.
'DirectX' 카테고리의 다른 글
셰이더공부 - 정반사광 (0) | 2018.02.25 |
---|---|
셰이더 공부 - 난반사광 (0) | 2018.02.24 |
셰이더 공부 - Color Shader (0) | 2018.02.23 |
DirectX11 - 정점버퍼, 셰이더 생성 (0) | 2018.01.24 |
DirectX 프레임워크 만들기 - FBX에서 노말, UV, 정점 얻어오기 (0) | 2018.01.18 |