블러 효과의 기본.
박스 샘플링 기법이 아닌, 가우스 함수 기법을 흉내내어 작성한다.
블러는, 기본적으로 주위의 색이 자신의 픽셀에 영향을 끼친다는 원리로 제작된다.
즉 셈플러에서 텍스쳐를 7개를 받아 온다고 치면,
가운데의 자기 색깔을 제외하고 좌우 3픽셀씩에서 각각 색상값을 더 얻어와서
자기 위치에다가 더해버리는 방식으로 제작되는 것이다.
물론 멀리 있을수록 가중치는 엷기 때문에 엷게 더해진다.
그렇게 해서 y축 (세로) 로만 블러 효과를 낸 예제는 다음과 같다.
(세로 가로 다 낼 수도 있지만 그러면 7*7= 49 개의 매트릭스 계산을 해야 하기 때문에, 2패스(7+7 =14)를 사용한다)
1pass의 핵심공식은 이거다.
color += tex2D(Texture0,float2(In.TexCoord.x+gaussFilter[i].x * texScaler,
In.TexCoord.y+gaussFilter[i].y * texScaler))
*gaussFilter[i].w;
원본 이미지는 다음과 같음.
그걸 y축 블러 효과로 만들었다.
설명 쓰다가 마지막에서 4배 뻥튀기 데이터를 발견.
뭐하는 짓이야.
어쩐지 너무 하얗게 날라간다 했어.
뻥튀기를 없애면 이렇게 나온다.
오 이제 좀 블러같다.좀 약해 보이기는 하는데.. 그래서 넣었구나.
//버텍스 쉐이더 부
struct VS_OUTPUT
{
float4 pos : POSITION0;
float2 texCoord : TEXCOORD0;
};
VS_OUTPUT vs_main( float4 inPos: POSITION )
{
VS_OUTPUT o = (VS_OUTPUT) 0;
//포지션을 mul로 메트릭스와 곱하는 것 처럼 sign으로 변환했다.
inPos.xy = sign( inPos.xy);
//그리고나서 출력은, z값을 0으로, a값은 1로 해서 합쳤다. 아마도 2D니까 z값은 0인거 같은데,
//xy를 왜 sign으로 해야 하는지는 잘 모르겠다. 아시는분 ?
o.pos = float4( inPos.xy, 0.0f, 1.0f);
// get into range [0,1] 입력범위를 0과 1 사이에 넣는단다.
//으음. 한눈엔 잘 모르겠다. 텍스쳐 코디네이트를 받지 않고, 포지션에서만 받는다라…
// 0에서 1이면 처음부터 끝까지겠지. 아…. 이건 설마 양수로 만들기 위한 것?
//이건 물어봐야겠다.
o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f;
return o;
}
//픽셀 쉐이더 부
//쌈빡하게 샘플러 정의해 주시고.
sampler2D Texture0;
//float4 짜리 7줄의 행열 만들어 주신다.
//현재 Y의 값이 -3부터 +3까지 변하고,
//각 행열당 가중치가 나와 있다.
float4 gaussFilter[7] =
{
0.0,-3.0,0.0, 1.0/64.0,
0.0,-2.0,0.0, 6.0/64.0,
0.0,-1.0,0.0, 15.0/64.0,
0.0, 0.0,0.0, 20.0/64.0,
0.0, 1.0,0.0, 15.0/64.0,
0.0, 2.0,0.0, 6.0/64.0,
0.0, 3.0,0.0, 1.0/64.0
};
//텍스쳐가 128픽셀인가부다. 비율로 나타내 주기 위해 이렇게 쓴다.
float texScaler = 1.0/128.0;
//없어도 상관없을듯. 에니메이션 시킬때라던가 그럴땔 위해서 있는 듯
float texOffset = 0.0;
struct PS_INPUT
{
float2 TexCoord : TEXCOORD0;
};
struct PS_OUTPUT
{
float4 Color : COLOR;
};
PS_OUTPUT ps_main (PS_INPUT In)
{
PS_OUTPUT Out;
float4 color = 0.0;
//앗싸 for문이다. 행열과 같게 7번 돌린다.
int i;
for (i=0;i<7;i++)
{
//그리고는 한 픽셀에 값을 누적시킨다.
//텍스 스케일러가 각 픽셀 위치값을 이동시키고, w 데이터가 가중치를 결정해 주는 것을 볼 수 있다.
color += tex2D(Texture0,float2(In.TexCoord.x+gaussFilter[i].x * texScaler+texOffset,
In.TexCoord.y+gaussFilter[i].y * texScaler+texOffset))
*gaussFilter[i].w;
}
//걍 4배 뻥튀기?!?
Out.Color = color * 4.0;
return Out;
}