Programming/컴퓨터그래픽스 (DX 11)

[Shader] 외곽선(OutLine) 패스

양양줘 2025. 11. 10. 16:35

 

아래 코드는 모두 DirectX 11 기준입니다.

 

외곽선 (OutLine)


외곽선(OutLine)법선(Normal)방향으로 모델을 약간 커지게 만든 뒤, 그 뒷면을 단색으로 색칠하는 방식으로 구현한다. 

 

외곽선을 그리기 위해선 총 2번의 Pass를 거치게 된다.

뒷면만 렌더링 하기 위해 DirectX기준 CullMode Front인 래스터라이저 옵션이 필요하다.

// [Model Render]
// 1) Pass 0, outline render
D3D::deviceContext->VSSetShader(D3D::Skinned_OutLine_VS.Get(), NULL, 0);
D3D::deviceContext->PSSetShader(D3D::OutLine_PS.Get(), NULL, 0);
D3D::deviceContext->RSSetState(D3D::rasterizerState.Get());
warrior->Render();
D3D::deviceContext->RSSetState(nullptr);

// 2) Pass 1, model render
D3D::deviceContext->VSSetShader(D3D::BaseLit_Skinned_VS.Get(), NULL, 0);
D3D::deviceContext->PSSetShader(D3D::BlinnPhongToon_PS.Get(), NULL, 0);
warrior->Render();

 

Pass 0 : 외곽선 렌더
  • CullMode = Front
  • 모델의 정점을 법선 방향으로 약간 확장한다.
  • 모델의 뒷면만 그려진다.

 

Pass 1 : 일반 렌더
  • 원래대로 렌더한다.

 

 

쉐이더 코드는 다음과 같다.

// Skeletal Mesh OutLine Vertex Shader
#include <shared.fxh>

PS_OutLine_INPUT main(VS_Weight_INPUT input)
{
    PS_OutLine_INPUT output = (PS_OutLine_INPUT) 0;

    // skinning 생략

    // world
    Matrix finalWorld = mul(weightedOffsetPose, world);
    output.pos = mul(float4(input.pos, 1.0f), finalWorld);
    
    // normal 방향으로 팽창
    //float outlineThickness = 0.3f;
    float3 normal = normalize(mul(input.normal, (float3x3) finalWorld));
    output.pos.xyz += normal * outlineThickness;

    output.pos = mul(output.pos, view); 
    output.pos = mul(output.pos, projection);

    return output;
}
// OutLine Pixel Shader
#include <shared.fxh>

float4 main(PS_OutLine_INPUT input) : SV_TARGET
{
    //float3 outlineColor = float3(1.0f, 1.0f, 1.0f);
    return float4(outlineColor, 1.0f);
}

 

 

 

 

 

자세한 코드는 10_CartoonRendering 프로젝트에서 확인할 수 있다. (쉐이더 코드는 WinBase 정적 라이브러리에 있다.)

 

 

 

GitHub - wooj22/DirectX3D11_Study: DirectX3D11 공부용 레포지토리입니다.

DirectX3D11 공부용 레포지토리입니다. Contribute to wooj22/DirectX3D11_Study development by creating an account on GitHub.

github.com