오늘은 텍스처 관련 데모앱을 분석해보자.
우선 데모앱을 실행해보면 텍스처가 적용된 큐브가 보이는데 잘보면 밑부분은 어둡게 되어있어 빛까지 적용된 것을 볼 수 있다.
이 텍스처와 빛이 코드로 어떻게 구현되어있는지 살펴보자. 기존에는 uv좌표를 통해 텍스처를 매핑해줬었다.
이때 uv좌표는 텍스처의 비율이라고 보면 된다. 만약 텍스처를 매핑했을 때 잘 떨어지지 않는 부분이 있다면 보간이 이루어지게 된다.
이번 코드에도 보면 SRV를 기반으로 텍스처를 묘사하고 이를 shader쪽에 넘겨줘서 uv좌표를 통해 맵핑을 해주는 것이다.
ComPtr<ID3D11ShaderResourceView> _diffuseMapSRV;
HRESULT hr = ::LoadFromWICFile(L"../Resources/Textures/WoodCrate01.dds", WIC_FLAGS_NONE, &md, img);
CHECK(hr);
// 여러 버전이 있음. (~CreateShaderResourceViewEx)
hr = ::CreateShaderResourceView(_device.Get(), img.GetImages(), img.GetImageCount(), md, _diffuseMapSRV.GetAddressOf());
CHECK(hr);
shader 코드에서 TEXCOORD부분이 uv좌표를 나타내는 부분이다. 이 uv좌표와 샘플러 함수를 통해 텍스처를 입혀주는 것이다.
struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
};
float4 texColor = float4(1, 1, 1, 1);
if (gUseTexure)
{
// Sample texture.
texColor = gDiffuseMap.Sample(samAnisotropic, pin.Tex);
}
좀 더 자세히 알아보자
우선 큐브를 만드는 부분에서 uv좌표를 설정해줘야한다.
geoGen.CreateBox(1.0f, 1.0f, 1.0f, box);
이 CreateBox함수가 선언된 클래스의 헤더파일 코드를 보면 정점을 정의하는 구조체에서 UV좌표부분이 추가되어 있다.
struct Vertex
{
Vertex() : position(0, 0, 0), normal(0, 0, 0), tangentU(0, 0, 0), texC(0, 0) {}
Vertex(const XMFLOAT3& p, const XMFLOAT3& n, const XMFLOAT3& t, const XMFLOAT2& uv)
: position(p), normal(n), tangentU(t), texC(uv){}
Vertex(
float px, float py, float pz,
float nx, float ny, float nz,
float tx, float ty, float tz,
float u, float v)
: position(px,py,pz), normal(nx,ny,nz),
tangentU(tx, ty, tz), texC(u,v){}
XMFLOAT3 position;
XMFLOAT3 normal;
XMFLOAT3 tangentU;
XMFLOAT2 texC; //UV
};
그리고 텍스처를 SRV로 받아서 샘플링할 때도 여러가지 방법이 있는데 이것은 쉐이더 코드의 SamplerState를 통해 정의해줄 수 있다.
SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4;
AddressU = WRAP; //넘어가면 반복
AddressV = WRAP;
};
이때 조명은 여러 가지 계산을 해보면서 제일 자연스러운 것을 채택하는 것이 좋다. 여기서는 텍스처컬러에 Ambient와 Diffuse값을 더한 부분을 곱해주고 Specular는 이 값에 더해주어서 반짝이는 효과가 텍스처자체 색상에는 영향을 주지 않도록 했다.
// Modulate with late add.
litColor = texColor * (ambient + diffuse) + spec;
여기서 만약 파도와 같이 텍스처가 움직이는 모션에 맞춰주려면 uv좌표가 고정된 것이 아닌 변화해야한다.
v[i].tex.x = 0.5f + _waves[i].x / _waves.Width();
v[i].tex.y = 0.5f - _waves[i].z / _waves.Depth();
'게임공부 > Directx11(물방울책)' 카테고리의 다른 글
[Directx11][C++][물방울]6. Stencil (1) | 2024.10.21 |
---|---|
[Directx11][C++][물방울]5. 블렌딩 (1) | 2024.10.19 |
[Directx11][C++][물방울]3. 조명 (3) | 2024.10.16 |
[Directx11][C++][물방울]2.Direct3D의 그리기 연산 (1) | 2024.10.15 |
[Directx11][C++][물방울]1.렌더링 파이프라인 (2) | 2024.10.14 |