개요
Sampler(샘플러)와 Texture Coordinate(UV 좌표)는 3D 그래픽에서 텍스처를 오브젝트 표면에 매핑하는 핵심 개념입니다. Sampler는 텍스처에서 픽셀 값을 읽어오는 방법을 정의하고, UV 좌표는 3D 메시의 어느 부분에 텍스처의 어느 부분을 매핑할지 결정합니다.
Part 1: 텍스처 샘플링의 개념
텍스처 샘플링이란?
텍스처 샘플링은 3D 그래픽에서 텍스처를 프리미티브(다각형 등의 기본 형태)에 매핑할 때 사용되는 작업입니다. 이 작업은 텍스처의 크기와 프리미티브의 크기가 다를 때 발생하며, 픽셀에 맞게 텍스처의 텍셀 값을 정해주고 처리해야 합니다.
왜 샘플링이 필요한가?
문제 상황
•
텍스처 이미지: 512×512 픽셀
•
화면에 그려지는 크기: 256×256 픽셀 또는 1024×1024 픽셀
•
픽셀과 텍셀(텍스처의 픽셀)이 1:1로 대응하지 않음
해결책: 샘플링
•
확대(Magnification): 텍스처보다 크게 그릴 때
◦
하나의 텍셀을 여러 픽셀에 적용
◦
어떻게 보간할지 결정 필요
•
축소(Minification): 텍스처보다 작게 그릴 때
◦
여러 텍셀을 하나의 픽셀로 압축
◦
어떤 텍셀을 선택할지 결정 필요
텍스처 좌표 (UV Coordinate)
UV 좌표계
•
U축: 텍스처의 가로 방향 (0.0 ~ 1.0)
•
V축: 텍스처의 세로 방향 (0.0 ~ 1.0)
•
정규화된 좌표계로 텍스처 크기와 무관
좌표 매핑
정점과 UV 좌표
struct Vertex
{
Vector3 position; // 3D 공간의 위치
Vector2 uv; // 텍스처 좌표 (0~1 범위)
};
// 예시: 사각형 메시
Vertex vertices[4] = {
{ Vector3(-1, -1, 0), Vector2(0, 1) }, // 좌하단
{ Vector3( 1, -1, 0), Vector2(1, 1) }, // 우하단
{ Vector3( 1, 1, 0), Vector2(1, 0) }, // 우상단
{ Vector3(-1, 1, 0), Vector2(0, 0) } // 좌상단
};
C++
복사
Part 2: 텍스처 필터링 방식
대표적으로 사용되는 샘플링 방법은 3가지 방법으로 나눌 수 있습니다.
1. 포인트 필터링 (Point Filtering)
포인트 필터링은 축소되거나 확대된 픽셀을 샘플링할 때 가까운 이웃 픽셀을 보간해서 픽셀을 가져옵니다. 영어로는 Nearest Neighbor Interpolation이라고 하는데, 일단은 보간이 뭔지부터 알아봐야 합니다.
보간(Interpolation)이란?
보간은 한자로 "간격을 돕는다"라는 의미가 됩니다. 좀 더 보충해서 해석하면 보간이란 '두 개의 위치가 존재하였을 때 두 위치를 기반으로 사이에 있는 위치(점)들을 계산하는 것'입니다.
포인트 필터링의 동작 원리
•
UV 좌표에 가장 가까운 텍셀 하나를 선택
•
보간 없이 그대로 사용
•
가장 빠르지만 품질이 낮음
특징
•
장점: 매우 빠른 성능, 메모리 접근 최소
•
단점: 픽셀화된 외관(계단 현상), 확대 시 블록 형태 보임
•
용도: 픽셀 아트, 레트로 스타일, UI 요소
2. 선형 필터링 (Linear Filtering)
선형 필터링은 포인트 필터링에서 보간을 사용합니다. 해당 픽셀 근처의 픽셀을 조사해서 여러 픽셀 사이의 값들을 보간 연산을 통해서 얻은 값으로 채워줍니다.
선형 필터링의 종류
선형 보간 (Linear Interpolation)
•
1D: 2개의 텍셀 사이 보간
•
수평 또는 수직 방향 한 축만 고려
쌍선형 보간 (Bilinear Interpolation)
•
2D: 4개의 인접 텍셀 보간
•
U축과 V축 모두 고려
•
가장 일반적으로 사용
삼선형 보간 (Trilinear Interpolation)
•
3D: 8개의 텍셀 보간
•
U, V축 + Mipmap 레벨 간 보간
•
밉맵 전환 시 부드러운 효과
보간 계산 예시
특징
•
장점: 부드러운 외관, 적절한 성능
•
단점: 멀리서 보면 깜빡임(앨리어싱) 발생 가능
•
용도: 대부분의 일반적인 텍스처 렌더링
3. 비등방성 필터링 (Anisotropic Filtering)
비등방성이란 물체의 물리적 성질이 방향에 따라 다른 성질을 가지는 것입니다. 기존의 Point, Linear 필터링은 회전으로 인한 왜곡을 따지지 않는 필터링입니다. 따라서 결과가 제대로 나오지 않을 수 있습니다. 하지만 비등방성 필터링은 이런 부분까지도 깔끔하게 렌더링됩니다.
비등방성 필터링의 필요성
예를 들어 원 텍스처의 크기가 1024×1024라고 하면, 보통의 밉맵은 512×512, 256×256, 128×128, ... 이런 식으로 만들어진다. 따라서 가로축과 세로축이 1/2배로 축소된 경우에는 512×512 밉맵을 쓸 것이고 아무 문제가 없다. 그러나 가로축은 그대로인데 세로축만 1/4로 축소된 경우(멀리 있는 바닥 텍스처 등)에는 512×512 밉맵이나 256×256 밉맵을 써야만 하며, 어느 경우든 가로축의 해상도는 떨어져 보일 것이다.
따라서 가로축은 그대로이고 세로축만 1/4로 축소된, 1024×256 밉맵을 미리 만들어두는 생각을 해볼 수 있다. 이렇게 하면 세로축의 에일리어싱은 없으면서도 가로축의 해상도는 1024 그대로를 유지할 수 있다.
이렇게 1024×512, 1024×256, 1024×128, ... 식으로 세로축이 축소되는 밉맵과, 512×1024, 256×1024, 128×1024, ... 식으로 가로축이 축소되는 밉맵, 그리고 또 512×512, 512×256, 512×128, ... 처럼 가로축이 1/2인 경우, ... 등등을 모두 만들어 놓으면, 가로축과 세로축이 축소된 정도 각각에 따라 적절한 밉맵을 사용할 수 있다. 이것이 비등방성 필터링이다.
특징
•
장점: 최고 품질, 비스듬한 각도에서도 선명
•
단점: 성능 비용 높음, 메모리 사용량 증가
•
용도: 바닥, 벽, 먼 거리 텍스처
필터링 방식 비교
전체 비교
정리
Part 3: Sampler State 구현
샘플러의 역할
샘플러를 사용한다는 것은 셰이더 스테이지에 세팅되어 있는 샘플러 스테이지를 경유해서 텍스처(셰이더 리소스 뷰)에 액세스함으로써 필터링 처리나 샘플링 처리를 수행한 값을 얻을 수 있다는 것입니다.
셰이더에서 샘플러 선언
SamplerState pointSampler : register(s0); // point sampler
SamplerState linearSampler : register(s1); // linear sampler
SamplerState anisotropicSampler : register(s2); // anisotropic sampler
SamplerState postProcessingSampler : register(s3); // postProcess sampler
C++
복사
샘플러 슬롯
•
DirectX 11에서는 최대 16개의 샘플러 슬롯 제공 (s0 ~ s15)
•
각 슬롯에 다른 샘플러 바인딩 가능
•
용도에 따라 적절한 샘플러 선택
D3D11_SAMPLER_DESC 구조체
아래는 샘플러 스테이트를 생성하는 예시입니다.
D3D11_SAMPLER_DESC samplerDesc = {};
samplerDesc.Filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_FUNC::D3D11_COMPARISON_NEVER;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
GetDevice()->CreateSamplerState(&samplerDesc, samplerStates[(UINT)eSamplerType::Anisotropic].GetAddressOf());
C++
복사
하나하나 옵션을 설명해보자면:
typedef struct D3D11_SAMPLER_DESC
{
D3D11_FILTER Filter;
D3D11_TEXTURE_ADDRESS_MODE AddressU;
D3D11_TEXTURE_ADDRESS_MODE AddressV;
D3D11_TEXTURE_ADDRESS_MODE AddressW;
FLOAT MipLODBias;
UINT MaxAnisotropy;
D3D11_COMPARISON_FUNC ComparisonFunc;
FLOAT BorderColor[ 4 ];
FLOAT MinLOD;
FLOAT MaxLOD;
} D3D11_SAMPLER_DESC;
C++
복사
각 옵션 상세 설명
Filter (필터링 방식)
•
D3D11_FILTER_MIN_MAG_MIP_POINT: 모든 단계에서 포인트 필터링
•
D3D11_FILTER_MIN_MAG_MIP_LINEAR: 모든 단계에서 선형 필터링
•
D3D11_FILTER_ANISOTROPIC: 비등방성 필터링
•
더 많은 필터 옵션은 MSDN 참조
AddressU, AddressV, AddressW (텍스처 어드레싱 모드)
•
U축, V축, W축(3D 텍스처)의 텍스처 래핑 방식
•
0~1 범위를 벗어난 UV 좌표 처리 방법
MipLODBias (밉맵 LOD 바이어스)
•
밉맵 레벨 선택에 오프셋 추가
•
양수: 더 흐릿한 밉맵 사용 (성능 향상)
•
음수: 더 선명한 밉맵 사용 (품질 향상)
•
일반적으로 0.0
MaxAnisotropy (비등방성 차수)
•
비등방성 필터링의 샘플 수
•
1: 비등방성 비활성화
•
2~16: 품질 증가 (일반적으로 4, 8, 16 사용)
•
높을수록 품질 좋지만 느림
ComparisonFunc (비교 함수)
•
깊이 비교 샘플링에 사용
•
그림자 매핑 등에 활용
•
D3D11_COMPARISON_NEVER: 비교 안 함 (일반적)
BorderColor (경계 색상)
•
D3D11_TEXTURE_ADDRESS_BORDER 모드 사용 시 적용
•
RGBA 색상 배열 [R, G, B, A]
•
텍스처 범위 밖의 색상
MinLOD, MaxLOD (밉맵 레벨 범위)
•
사용할 밉맵 레벨의 최소/최대 제한
•
MinLOD: 0 (가장 선명한 레벨)
•
MaxLOD: D3D11_FLOAT32_MAX (모든 레벨 허용)
Part 4: 텍스처 어드레싱 모드
텍스처 좌표 범위
텍스처 좌표 값은 0.0 ~ 1.0이 표준 범위입니다. 예를 들어 2D 텍스처의 경우 (0.0, 0.0) ~ (1.0, 1.0)일 것입니다.
그러나 0.0 이하 1.0 이상이 안 쓰이란 법은 없으며, 오히려 이러한 값을 사용함으로 특수한 효과를 줄 수도 있습니다.
어드레싱 모드 종류
텍스처 어드레싱 모드에는 총 5개의 모드가 있습니다.
enum D3D11_TEXTURE_ADDRESS_MODE
{
D3D11_TEXTURE_ADDRESS_WRAP = 1, // 텍스처 좌표를 반복한다
D3D11_TEXTURE_ADDRESS_MIRROR = 2, // 인접한 이미지를 반복한다
D3D11_TEXTURE_ADDRESS_CLAMP = 3, // 텍스처 끝 부분의 픽셀이 늘어진다
D3D11_TEXTURE_ADDRESS_BORDER = 4, // 경계 색을 설정한다
D3D11_TEXTURE_ADDRESS_MIRROR_ONCE = 5 // CLAMP + MIRROR 모드
} D3D11_TEXTURE_ADDRESS_MODE;
C++
복사
각 모드 상세 설명
WRAP (랩/타일링)
•
UV 좌표를 1.0으로 나눈 나머지 사용
•
텍스처가 무한히 반복되는 효과
•
벽돌, 바닥 타일 등에 사용
MIRROR (미러/대칭 반복)
•
텍스처를 좌우 대칭으로 반복
•
이음새가 자연스러움
•
대칭 패턴이 있는 텍스처에 적합
CLAMP (클램프/고정)
•
0~1 범위로 제한
•
범위 밖은 가장자리 픽셀로 늘어남
•
단일 이미지, UI 요소에 사용
BORDER (경계 색)
•
0~1 범위 밖은 BorderColor로 채움
•
데칼, 스티커 효과
•
투명 경계가 필요한 경우
MIRROR_ONCE (한 번만 미러)
•
0~1: 정상
•
1~2: 미러 (한 번만)
•
2 이상: CLAMP
•
대칭 효과 + 경계 고정
Part 5: 텍스처 필터링 모드
텍스처를 그냥 렌더링하면 텍스처 이미지가 확대되거나 축소될 때 원래 이미지처럼 깔끔하게 보이지 않습니다. 이 부분을 보간 처리하여 보다 깔끔하게 보일 수 있도록 하는 것이 필터링 모드입니다.
필터 설정 가이드
성능 우선 (모바일, 저사양)
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerDesc.MaxAnisotropy = 1;
C++
복사
균형 (PC, 콘솔)
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.MaxAnisotropy = 4;
C++
복사
품질 우선 (고사양 PC)
samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
samplerDesc.MaxAnisotropy = 16;
C++
복사
비등방성 필터링 설정
비등방성 필터링을 사용하려면 비등방성의 차수를 설정해야 합니다. 비등방성 차수를 1로 설정하면 비등방성 필터링이 무효가 되며, 1보다 큰 값을 설정하면 비등방성 필터링이 유효가 됩니다. 가장 깔끔하게 보이지만 성능은 가장 떨어집니다.
// 비등방성 필터링 설정
samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
samplerDesc.MaxAnisotropy = 16; // 2, 4, 8, 16 중 선택
C++
복사
차수에 따른 효과
•
1: 비활성화 (선형 필터링과 동일)
•
2-4: 저품질, 성능 영향 적음
•
8: 중간 품질, 권장 설정
•
16: 최고 품질, 성능 비용 높음
비교 함수
또 텍셀의 값을 비교 함수로 비교할 수도 있습니다. 다양한 필터링이 존재하니 자세한 것은 아래 주소에서 확인해보자.
비교 샘플링 사용 예시 (그림자 매핑)
// 그림자 맵용 샘플러
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
// HLSL에서 사용
SamplerComparisonState shadowSampler : register(s4);
float shadow = shadowMap.SampleCmpLevelZero(shadowSampler, uv, depth);
C++
복사
Part 6: 텍스처 샘플링 함수
HLSL 샘플링 함수
셰이더 함수 내에서 샘플러를 사용하여 필터링 처리나 샘플링 처리를 수행하고 텍스처로부터 값을 읽어들이려면 다음 함수를 사용합니다.
제약 사항
•
<T>.Sample()와 <T>.SampleCmp()는 픽셀 셰이더에서만 사용할 수 있음
•
나머지 함수들은 모든 셰이더에서 사용 가능
샘플링 함수 예시
기본 샘플링
color = triangleTexture.Sample(g_sam_0, _in.vUV);
C++
복사
밉맵 레벨 지정 샘플링
실전 사용 패턴
여러 텍스처와 샘플러 조합
UV 애니메이션
Part 7: 샘플러 최적화
샘플러 재사용
좋은 예: 샘플러 공유
// 초기화 시 한 번만 생성
SamplerState globalLinearSampler : register(s0);
SamplerState globalAnisotropicSampler : register(s1);
// 여러 텍스처에서 재사용
float4 color1 = texture1.Sample(globalLinearSampler, uv);
float4 color2 = texture2.Sample(globalLinearSampler, uv);
float4 color3 = texture3.Sample(globalLinearSampler, uv);
C++
복사
나쁜 예: 불필요한 중복
// 같은 설정의 샘플러를 여러 개 생성 (비효율적)
SamplerState sampler1 : register(s0);
SamplerState sampler2 : register(s1);
SamplerState sampler3 : register(s2);
// 모두 같은 설정이면 하나만 있으면 됨
C++
복사
밉맵 최적화
밉맵 생성
// 텍스처 로드 시 밉맵 자동 생성
D3D11_TEXTURE2D_DESC texDesc = {};
texDesc.MipLevels = 0; // 0 = 자동 생성 (전체 레벨)
texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
// 수동 밉맵 생성
context->GenerateMips(shaderResourceView);
C++
복사
LOD 바이어스 활용
// 먼 거리 오브젝트: 낮은 밉맵 레벨 강제
samplerDesc.MipLODBias = 1.0f; // 한 단계 낮은 해상도
samplerDesc.MaxLOD = 3.0f; // 최대 4번째 밉맵까지만
// 중요 오브젝트: 높은 품질 유지
samplerDesc.MipLODBias = -0.5f; // 더 선명하게
samplerDesc.MinLOD = 0.0f; // 최고 해상도 허용
C++
복사
성능 프로파일링
샘플러 비용 비교
최적화 팁
•
UI, HUD: Point 또는 Linear (CLAMP 모드)
•
캐릭터 텍스처: Trilinear 또는 Anisotropic 4x
•
바닥, 벽: Anisotropic 8x~16x
•
파티클: Linear (성능 중요)
•
먼 거리 오브젝트: LOD 바이어스 적용
결론
핵심 요약
Sampler (샘플러)
•
텍스처에서 픽셀 값을 읽어오는 방법 정의
•
Filter, Address Mode, LOD 등 다양한 옵션 제어
•
품질과 성능의 균형 조절 가능
Texture Coordinate (UV 좌표)
•
3D 메시와 2D 텍스처를 연결하는 매개체
•
0~1 정규화된 좌표계
•
정점마다 UV 좌표 할당
필터링 방식
•
Point: 빠르지만 픽셀화
•
Linear: 부드럽고 균형적
•
Anisotropic: 최고 품질, 비스듬한 각도 대응
어드레싱 모드
•
WRAP: 타일링, 반복 패턴
•
MIRROR: 대칭 반복
•
CLAMP: 경계 고정
•
BORDER: 경계 색상
실전 적용 가이드
샘플러 설계
1.
용도별로 샘플러 타입 분류
2.
전역 샘플러 재사용으로 효율화
3.
품질/성능 프로필에 따라 동적 전환
텍스처 준비
1.
적절한 해상도 선택 (2의 거듭제곱 권장)
2.
밉맵 생성으로 품질과 성능 확보
3.
UV 매핑 최적화 (왜곡 최소화)
성능 최적화
1.
필요한 만큼만 비등방성 차수 사용
2.
LOD 바이어스로 먼 거리 품질 조절
3.
샘플러 변경 최소화 (배칭 고려)
Sampler와 UV 좌표의 깊은 이해는 고품질 텍스처 렌더링의 핵심이며, 게임의 시각적 품질을 결정하는 중요한 요소입니다. 적절한 샘플러 설정과 최적화를 통해 성능과 품질의 최적 균형점을 찾을 수 있습니다.











