Mirror한 모델링 hlsl에서 강제로 맞추기

Ashred·2025년 5월 28일

3dsMAX에서 제공하는 StandardFX11 셰이더

HLSL 셰이더를 적용한 오브젝트를 Mirror 하게되면, 면이 뒤집힌 것 처럼 보이는 경우가 있다. 그 이유는 스케일에 -1을 곱하면 행렬의 좌표계가 왼손 좌표계로 뒤바뀌기 때문이다.

모델링 작업을 할 때, Mirror(특히 instance) 기능을 자주 사용하다보니 Reset Xform을 사용할 수 없는 번거로움이 있었다. 작업자들의 니즈가 있어서 이 부분을 개선하기 위해 코드 수정을 해보려고 한다.


문제점

Cull Mode

기존

technique11 ToonShading
{
	pass Main
	{
		SetVertexShader(CompileShader(vs_5_0, ShaderVertex()));
		SetPixelShader(CompileShader(ps_5_0, ShaderPixel()));
		SetDepthStencilState(DepthTestOn, 0);
		SetRasterizerState(Cull_Back);
	}
    pass Outline
	{
		SetVertexShader(CompileShader(vs_5_0, ShaderVertex_Outline()));
		SetPixelShader(CompileShader(ps_5_0, ShaderPixel_Outline()));
		SetDepthStencilState(DepthTestOn, 0);
		SetRasterizerState(Cull_Front);
	}
}

변경

DepthStencilState DepthTestOn
{
    DepthEnable                 = TRUE;
    DepthWriteMask              = All;
    DepthFunc                   = LESS_EQUAL;
};

DepthStencilState DepthTestOutline
{
    DepthEnable                 = TRUE;
    DepthWriteMask              = ZERO;
    DepthFunc                   = LESS_EQUAL;
};

technique11 ToonShading_Outline_Front
{
    pass Main
    {
        SetVertexShader(CompileShader(vs_5_0, ShaderVertex()));
        SetPixelShader(CompileShader(ps_5_0, ShaderPixel()));
        SetDepthStencilState(DepthTestOn, 0);
        SetRasterizerState(Cull_Back);
    }
    pass Outline
    {
        SetVertexShader(CompileShader(vs_5_0, ShaderVertex_Outline()));
        SetPixelShader(CompileShader(ps_5_0, ShaderPixel_Outline()));
        SetDepthStencilState(DepthTestOutline, 0);
        SetRasterizerState(Cull_Outline_Front);
    }
}

technique11 ToonShading_Outline_Back
{
    pass Main
    {
        SetVertexShader(CompileShader(vs_5_0, ShaderVertex()));
        SetPixelShader(CompileShader(ps_5_0, ShaderPixel()));
        SetDepthStencilState(DepthTestOn, 0);
        SetRasterizerState(Cull_None);
    }
    pass Outline
    {
        SetVertexShader(CompileShader(vs_5_0, ShaderVertex_Outline()));
        SetPixelShader(CompileShader(ps_5_0, ShaderPixel_Outline()));
        SetDepthStencilState(DepthTestOutline, 0);
        SetRasterizerState(Cull_Outline_Back);
    }
}

Cull Mode란?

GPU가 어떤 면을 그리고, 어떤 면을 버릴지 선택하는 것.

Back (기본값)

  • 성능 최적화용.
  • 대부분의 경우 모델의 앞면만 보이면 되기 때문에 뒷면은 그리지 않게 함.

Front

  • 일부러 뒷면만 그리고 싶을 때 (아웃라인 셰이더 등)

None

  • 앞뒤 둘다 그림.
  • 모든 면을 보여야 할 때 사용.
  • 성능 소모 증가, 깊이 충돌 발생 가능성.

cull mode를 None으로 놓고 양면을 그려서 메시가 반대쪽으로 뒤집어보이는 현상을 막는다.
그리고 technique을 각각 추가해 사용자가 mirror를 한 오브젝트는 직접 back모드로 전환할 수 있도록 한다.


결과

이로써 툰셰이더를 활용하면서도 instance를 사용할 수 있게 되었다!

0개의 댓글