[ Dx11 ] (solution) Motion Blur에 사용하는 셰이더 호출 횟수 줄이기
문제
모션블러 효과를 생성하기 위해 여러 개의 이미지들을 생성, 이러한 작업을 프레임마다 진행해야 한다. 이로 인해 프래그먼트 셰이더의 호출이 매우 빈번해져 성능에 영향을 줄 수 있으므로 fullscreen quad를 사용, 프래그먼트 셰이더 호출 횟수를 줄인다.
해결
뷰포트를 생성하기 위해 하나의 큰 사각형을 만들어야 하나, 사각형은 2개의 삼각형으로 이루어져, 프래그먼트 셰이더를 2번 호출해야 한다. 그러나 하나의 큰 삼각형을 그려, 화면을 채운다면 1개의 삼각형으로도 뷰포트를 생성할 수 있다. 이는 레스터라이저에서 내부 픽셀에 대해서만 프래그먼트를 생성하는 것을 이용하여 다른 영향 없이 프래그먼트 셰이더의 호출 횟수를 감소시킬 수 있다.
사각형의 정보를 임포트하여,
1
2
3
4
5
6
7
8
9
#FSQ
v -1 -1 0
v -1 1 0
v 1 -1 0
v 1 1 0
f 2/2/1 1/1/1 3/3/1
f 2/2/1 3/3/1 4/4/1
쉐이더에서 단일 삼각형의 뷰포트를 생성할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct QuadOutput
{
float4 pos : SV_Position;
float2 tex : TEXCOORD0;
};
QuadOutput FullScreenTriVS(uint id : SV_VertexID)
{
QuadOutput output = (QuadOutput)0.0f;
output.tex = float2((id << 1) & 2, id & 2);
output.pos = float4(output.tex * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
return output;
}
그리고 이 정보를 토대로 픽셀 셰이더에 넘겨, 풀스크린쿼드 이미지를 생성한다.
1
2
3
4
5
6
7
8
9
technique11 Rendering
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, FullScreenTriVS()));
SetPixelShader(CompileShader(ps_5_0, Rendering()));
SetRasterizerState(rasterizerState_New);
}
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.