Geometry
GeometryHelper클래스에 자주 쓰는 도형들을 사각형 Quad 외에도 큐브, 스피어, 그리드를 추가해보고자 한다.
먼저 큐브. 사각형에 텍스쳐를 붙이려면
(0,0) (1,0)
(0,1) (1,1)
이렇게 정점을 붙여줬었다. 그런데 그럼 오른쪽 면은
(1,0) ?
(1,1) ?
이렇게 이상하게 되니깐 정점은 총 8개 더라도 한 면에 텍스쳐를 맵핑하려면 각각의 사각형이 필요하다.
그래서 6면체니 정점이 24개가 된다.

그리고 스피어.
스피어를 만드는 전략은 북극과 남극 두 꼭짓점 사이에서 가로로 몇개로 나눌지, 세로로 몇개로 나눌지를 정해서 만드는 것이다.
그럼 북극과 남극을 잇는 선이 중점이 되는 두꺼운 피자?케이크? 처럼 생긴 조각이 생긴다.

그런데맨 위랑 맨 밑만 삼각형으로 만들 수 있고 그 가운데는 사각형을 또 삼각형으로 나눠서 가야한다.
그리고 이 식은 보통 프랭크 루나 저의 DirectX책에있는걸 그대로 쓴다.
기본적으로 지름이 1이고 가로 세로 20개씩 나눈다고 생각한다. 크기는 스케일을 늘려서 사용하면 된다.
그리드는 땅(터레인)깔 때 괄호이다.
그리드의 정점을 높낮이를 다르게 하면 땅에 높낮이가 달라지는것같다.
만약에 10*10의 그리드를 그릴거면 정점은 11*11로 해야한다.

실습을 해본다.


이전시간에 했던 05.TextureDemo에서 오브젝트를 Quad가 아닌 Cube, Sphere에 넣어봤다.
그리드도 넣어봤다. 그리드는 크기를 정해야하므로 인수로 넘긴다.


그런데 오른쪽 그림처럼 사진 한장이 첫번째 그리드칸에만 있고 나머지칸에는 이상하게 들어갔다.ㅠㅠ
Uv맵핑시 0~1사이가 공식적인 범위이나 이 범위를 벗어나면 어떻게 될지 샘플러스테이트에서 처리하지 않고 기본만 사용했기때문에 이렇게 보인것이다. 다음시간엔 이걸 어떻게 처리하는지 샘플링 기법에 따라 그리드가 어떻게 채워지는지 알아보자.
Sampling
지난시간에 그리드에 텍스쳐를 맵핑할 때 Uv맵핑시 0~1 사이 값의 범위를 벗어나면 이상하게 보였던 문제가 잇었다.
쉐이더에서샘플링을 할때 여러가지 옵션을 줄수있는데 본격적으로 테스트해보자.
Uv맵핑이란 정점마다 uv좌표를 지정해주면 그거에 맞게 붙이는 느낌이다. 이게 샘플링의 기본개념인데
샘플링의 옵션은 대표적으로
Filter와 Adress를 수정할 수있다. Filter는 linear나 pointer중에 고를 수있다.
Address는 특히 그리드에서 터레인? 만들때 유용히 쓰인다. uint 타입으로 Address변수 만들고 바꿔서 테스트해보자.
샘플러 스테이트도 4개를 만들고 u,v값을 따로 설정하게 했다.
그리고 새로운 픽셀쉐이더를 만든다.
우선 Shaders에 05.Sampler.fx를 아래와 같이 만들어서 Client프로젝트에 추가했다.
matrix World;
matrix View;
matrix Projection;
Texture2D Texture0;
uint Address;
struct VertexInput
{
float4 position : POSITION;
float2 uv : TEXCOORD;
};
struct VertexOutput
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};
VertexOutput VS(VertexInput input)
{
VertexOutput output;
output.position = mul(input.position, World);
output.position = mul(output.position, View);
output.position = mul(output.position, Projection);
output.uv = input.uv;
return output;
}
// Filter = 확대/축소 일어났을 때 중간값을 처리하는 방식
// Address = UV가 1보다 컸을 때, 나머지 부분을 어떻게 처리
SamplerState Sampler0;
SamplerState SamplerAddressWrap
{
AddressU = Wrap;
AddressV = Wrap;
};
SamplerState SamplerAddressMirror
{
AddressU = Mirror;
AddressV = Mirror;
};
SamplerState SamplerAddressClamp
{
AddressU = Clamp;
AddressV = Clamp;
};
SamplerState SamplerAddressBorder
{
AddressU = Border;
AddressV = Border;
BorderColor = float4(1, 0, 0, 1);
};
float4 PS(VertexOutput input) : SV_TARGET
{
if (Address == 0)
return Texture0.Sample(SamplerAddressWrap, input.uv);
if (Address == 1)
return Texture0.Sample(SamplerAddressMirror, input.uv);
if (Address == 2)
return Texture0.Sample(SamplerAddressWrap, input.uv);
if (Address == 3)
return Texture0.Sample(SamplerAddressBorder, input.uv);
return Texture0.Sample(Sampler0, input.uv);
}
technique11 T0
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
};
기존 원본 텍스쳐에서 샘플링해서 바로 가져다쓰는 Sampler0, 그리고 Wrap,Mirror,Clamp,Border.
그리고 이들을 테스트할 06.SamplerDemo파일 SamplerDemo클래스도 만들었다.
// 06. SamplerDemo.cpp
void SamplerDemo::Render()
{
_shader->GetMatrix("World")->SetMatrix((float*)&_world);
_shader->GetMatrix("View")->SetMatrix((float*)&Camera::S_MatView);
_shader->GetMatrix("Projection")->SetMatrix((float*)&Camera::S_MatProjection);
_shader->GetSRV("Texture0")->SetResource(_texture->GetComPtr().Get());
enum ADDRESS_VALUE
{
ADDRESS_WRAP = 0,
ADDRESS_MIRROR = 1,
ADDRESS_CLAMP = 2,
ADDRESS_BORDER = 3,
};
_shader->GetScalar("Address")->SetInt(ADDRESS_WRAP);
uint32 stride = _vertexBuffer->GetStride();
uint32 offset = _vertexBuffer->GetOffset();
DC->IASetVertexBuffers(0, 1, _vertexBuffer->GetComPtr().GetAddressOf(), &stride, &offset);
DC->IASetIndexBuffer(_indexBuffer->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);
_shader->DrawIndexed(0, 0, _indexBuffer->GetCount(), 0, 0);
}
WRAP

MIRROR

BORDER

유브이 비율에 따라서 정점에 맞게 발라주는게 샘플러의 역할인데
필터와 어드레스 값으로 변화를 줄 수있고 특히 어드레스값이 유브이가 1보다 클때 나머지 부분을 어떻게 채울지와 관련이 있는것 이었다.
'[DirectX11]' 카테고리의 다른 글
| Light #2 - Diffuse (0) | 2024.08.30 |
|---|---|
| Light #1 - Ambient (0) | 2024.08.27 |
| 3D - 프로젝트 설정 (0) | 2024.08.03 |
| Constant Buffer (0) | 2024.01.15 |
| 기본 프레임워크 만들기, 외부 라이브러리 추가 방법( feat. DirectXTex) (0) | 2023.11.05 |