Sphere Mapping
Sphere Mapping
부드럽게 잘 텍스쳐링 된 줄 알았으나
이음새 부분에서 갑자기 이상하게 보인다
-
텍스쳐는 ‘정사각형’ 모습으로 존재하며
그것을 각 정점의 uv좌표에 맞게 그리는 방식 -
현재의 subDivision은 모든 Vertex 하나 밖에 없는 Mesh에 적용 중
(텍스쳐 좌표를 vertex 좌표 기준으로 역산정하여 구하는 중이다) -
atan2f 를 통해 텍스쳐 좌표를 역산중이기에
원본 텍스쳐의 0,1 이 겹쳐지는 부분에서 문제가 발생
(구체 모델링)
문제의 원인?
끝 부분의 Vertex 상태들
-
위쪽은 ‘같은 위치’ 이지만 서로 다른 텍스쳐 좌표를 가지기에
문제가 없음 -
아래쪽이 ‘문제가 되는 케이스’
‘같은 삼각형’ 안에서
한 쪽의 텍스쳐 좌표는 (1.0,~)
다른 한쪽의 텍스쳐 좌표는 (0.0,~)
이러면 중간쪽의 텍스쳐 좌표가 ‘보간’이 되면서
난리가 난다…
(0~1 사이의 모든 것이 압축되어 있듯 표현이 된다…)
해결책?
-
이전에 구현한 ‘Sphere’ 방식처럼
‘중복된 영역’이지만 Texture Coord를 ‘다르게’ 가지는
Mesh를 사용(최선의 방식!)
(이전 예제에서 사용한 방식) -
텍스쳐 좌표를 ‘Vertex’ 단위가 아니라
‘픽셀 단위’로 적용하는 방식
(현재 사용할 방식)
예제 코드
Common.hlsli
struct PixelShaderInput
{
float4 posProj : SV_POSITION; // Screen position
float3 posModel : POSITION0; // Model position
float3 posWorld : POSITION1; // World position (조명 계산에 사용)
float3 normalWorld : NORMAL;
float2 texcoord : TEXCOORD;
float3 color : COLOR; // Normal lines 쉐이더에서 사용
};
- PS에서 처리하도록 Model Position용 코드 추가
VertexShader
PixelShaderInput main(VertexShaderInput input)
{
PixelShaderInput output;
float4 pos = float4(input.posModel, 1.0f);
output.posModel = pos.xyz; // model 좌표계 저장
pos = mul(pos, model);
output.posWorld = pos.xyz; // 월드 위치 따로 저장
pos = mul(pos, view);
pos = mul(pos, projection);
output.posProj = pos;
output.texcoord = input.texcoord;
output.color = float3(0.0f, 0.0f, 0.0f); // 다른 쉐이더에서 사용
float4 normal = float4(input.normalModel, 0.0f);
output.normalWorld = mul(normal, invTranspose).xyz;
output.normalWorld = normalize(output.normalWorld);
return output;
}
- posModel 을 저장해둔다
PixelShader
float2 uv;
uv.x = atan2(input.posModel.z, input.posModel.x) / (3.14592 * 2.0) + 0.5f;
uv.y = acos(input.posModel.y / 1.5) / 3.14592;
return useTexture ? float4(color, 1.0) * g_texture0.Sample(g_sampler, uv) : float4(color, 1.0);
- texCoord 대신 posModel 을 기반으로 한
uv 좌표를 사용한다
결과
텍스쳐링이 깔끔해졌다
이런 식으로 ‘픽셀 쉐이더 쪽’에서 텍스쳐 좌표를 계산하는 방식도 존재
(Sphere Mapping이 이 방식으로 이루어진다)
댓글남기기