본문 바로가기

DX

텍스처링

텍스처링은 이미지를 레벨의 오브젝트에 맵핑 하는 기법.

 

사용하고 싶은 이미지를 GPU 메모리에서 Texture2D 형식으로 받아올 수 있다.

텍스처 이미지 안의 원하는 위치로부터 색을 가져오는 것을 샘플링이라고 한다. 쉐이더에서는 그 역할이 샘플러라는 문법으로 존재.

HLSL 에서 샘플링 할 때는 텍스처에 샘플러와 UV 좌표를 넣어 색을 가져 올 수 있다.

 

register 에서 t0 는 텍스처 s0 는 샘플러 b0 는 버퍼의 레지스터 주소 사용 순서를 의미한다.

Texture2D g_texture0 : register(t0);
SamplerState g_sampler : register(s0);

cbuffer PixelShaderConstantBuffer : register(b0) { float xSplit; };

struct PixelShaderInput {
    float4 pos : SV_POSITION;
    float3 color : COLOR;
    float2 texcoord : TEXCOORD;
};

float4 main(PixelShaderInput input) : SV_TARGET {

    return input.texcoord.x > xSplit
               ? g_texture0.Sample(g_sampler, input.texcoord)
               : float4(1.0, 0.0, 0.0, 1.0);
}

 

CPP 에서 텍스처링에 필요한 리소스들을 정의한다.

TextureResourceView : 쉐이더가 텍스처를 리소스로 사용할 수 있는 형식으로 View 만 잠깐 바꿔주는 역할을 한다.

이런 역할이 필요한 이유는 텍스처를 쉐이더에서 렌더타겟으로 사용할 수 있는데 다른 쉐이더에서 렌더 타겟을 리소스로 사용할 수 있다. 리소스로 사용 할 때는 리소스 뷰로 텍스처를 넣어주도록 해서 용도에 맞게 사용 하도록 만들어졌다.

 

cpp 에서 원하는 png 파일로 텍스처와 리소스 뷰를 만들어준다. *Dx에서는 DDS 파일이 텍스처 형식으로 좋음

Address 는 WRAP 을 사용하는 것이 일반적이다. (다음 강의에서 차이 확인)

 

텍스처 생성 함수 안쪽을 보면 경로로 부터 filename에 맞는 이미지 파일을 가져온다.

그래서 immutable, 쉐이더에 사용될 리소스로 설정하여 텍스처를 생성한다.

void AppBase::CreateTexture(
    const std::string filename, ComPtr<ID3D11Texture2D> &texture,
    ComPtr<ID3D11ShaderResourceView> &textureResourceView) {

    int width, height, channels;

    unsigned char *img =
        stbi_load(filename.c_str(), &width, &height, &channels, 0);

    //assert(channels == 4);

    std::vector<uint8_t> image;

    image.resize(width * height * channels);
    memcpy(image.data(), img, image.size() * sizeof(uint8_t));

    // Create texture.
    D3D11_TEXTURE2D_DESC txtDesc = {};
    txtDesc.Width = width;
    txtDesc.Height = height;
    txtDesc.MipLevels = txtDesc.ArraySize = 1;
    txtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    txtDesc.SampleDesc.Count = 1;
    txtDesc.Usage = D3D11_USAGE_IMMUTABLE;
    txtDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

    // Fill in the subresource data.
    D3D11_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = image.data();
    InitData.SysMemPitch = txtDesc.Width * sizeof(uint8_t) * channels;
    // InitData.SysMemSlicePitch = 0;

    // ID3D11Device* pd3dDevice; // Don't forget to initialize this
    // TODO: You should really consider using a COM smart-pointer like
    // Microsoft::WRL::ComPtr instead

    m_device->CreateTexture2D(&txtDesc, &InitData, texture.GetAddressOf());
    m_device->CreateShaderResourceView(texture.Get(), nullptr,
                                       textureResourceView.GetAddressOf());
}

}

 

 

다음으로 Render 함수에서 리소스뷰와 샘플러를 설정해서 넘겨주는데 배열로 넘긴다. 여러 리소스 뷰 (텍스처)를 사용할 수 있기 때문이다. 샘플러 또 한 배열 형식으로 넘길 수 있다.

 

 

실행하면 ps 에 의해서 아래와 같이 렌더링 되어진다.

 

 

 

다음은 AddressUVW 를 바꾸어보면 아래와 같은 차이가 나온다.

Wrap

Clamp

 

 

Mirror

 

 

 

 

 

 

 

 

'DX' 카테고리의 다른 글

퐁 vs 블린 퐁  (0) 2025.06.16
조명  (0) 2025.06.16
HLSL 코드 예제  (0) 2025.06.15
HLSL 디버거  (0) 2025.06.15
HLSL 기본 문법  (0) 2025.06.15