티스토리 뷰

Game/MMD

Shadow Mapping (5)

newpolaris 2017. 7. 25. 18:04

Gaussian weighted PCF 방식이다

좀더 최적화 된 형태로 아래 걸 사용해보았다.

http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/

위의 링크에서 볼 수 있으며, 아직 정해진 이름은 없다.

q = {
{0, 0, 0, 0, 0, 0, 0}, 
{0, a*a, a*b, a*c, a*b, a*a, 0}, 
{0, b*a, b*b, b*c, b*b, b*a, 0}, 
{0, c*a, c*b, c*c, c*b, c*a, 0}, 
{0, b*a, b*b, b*c, b*b, b*a, 0}, 
{0, a*a, a*b, a*c, a*b, a*a, 0}, 
{0, 0, 0, 0, 0, 0, 0}}

k[x_, y_] := s*t*q[[x, y]] + (1 - s)*t*q[[x + 1, y]] + s*(1 - t)*q[[x, y + 1]] + (1 - s)*(1 - t)*q[[x + 1, y + 1]]

eq[1, x_, y_] := (k[x, y] == (1 - u) (1 - v) w) 
eq[2, x_, y_] := (k[x + 1, y] == u (1 - v)*w) 
eq[3, x_, y_] := (k[x, y + 1] == (1 - u) v*w) 
eq[4, x_, y_] := (k[x + 1, y + 1] == u*v*w)

우선 1,1 점에 대해 조사하면,

Solve[{eq[1, 1, 1], eq[2, 1, 1], eq[3, 1, 1], eq[4, 1, 1]}, {u, v, w}] 

u -> (b + a s - b s)/(a + b - b s) 
v -> (b + a t - b t)/(a + b - b t) 
w -> (a + b - b s) (a + b - b t)

1,1 에서 5,5 까지 (matrix의 0 이 아닌 부분)에 대해 조사하고 정리한 후 대략적인 근사값인 a, b, c 에 대해 1, 3, 4를 넣으면 아래와 같이 된다고 한다.

float uw0 = (4 - 3 * s); 
float uw1 = 7;
float uw2 = (1 + 3 * s);
float u0 = (3 - 2 * s) / uw0 - 2;
float u1 = (3 + s) / uw1;
float u2 = s / uw2 + 2;
float vw0 = (4 - 3 * t);
float vw1 = 7;
float vw2 = (1 + 3 * t);
float v0 = (3 - 2 * t) / vw0 - 2;
float v1 = (3 + t) / vw1;
float v2 = t / vw2 + 2;
float sum = 0;
sum += uw0 * vw0 * do_pcf_sample(base_uv, u0, v0, z, dz_duv);
sum += uw1 * vw0 * do_pcf_sample(base_uv, u1, v0, z, dz_duv);
sum += uw2 * vw0 * do_pcf_sample(base_uv, u2, v0, z, dz_duv);
sum += uw0 * vw1 * do_pcf_sample(base_uv, u0, v1, z, dz_duv);
sum += uw1 * vw1 * do_pcf_sample(base_uv, u1, v1, z, dz_duv);
sum += uw2 * vw1 * do_pcf_sample(base_uv, u2, v1, z, dz_duv);
sum += uw0 * vw2 * do_pcf_sample(base_uv, u0, v2, z, dz_duv);
sum += uw1 * vw2 * do_pcf_sample(base_uv, u1, v2, z, dz_duv);
sum += uw2 * vw2 * do_pcf_sample(base_uv, u2, v2, z, dz_duv);
sum *= 1.0f / 144;

w sample(u,v) 를 (1,1)에서 전개하면, uw0vw0 * sample(u0, v0) 이다.
u0 의 -2, u2 의 +2는 0 기준 좌우 2칸 위치를 표시하기 위한것

아이디어 자체는, Gaussian blur 과정의 가속화를 위한 아래 링크에서 쓰인 것과 동일하다

http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/

다만, shadow map 과정에서 쓰이므로 간단한 shadow map 생성 방법에서 사용하는

PS shader 에서는 이걸 분리하여 적용하는 건 힘드므로 separable kernel 을 2번

적용하지 않고 결합시켜둔 형태이다.

바로 위의 Efficient 관련 자료

https://software.intel.com/en-us/blogs/2014/07/15/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms https://github.com/manuelbua/blur-ninja

결과는 괜찮다. 비용도 안비싼편

'Game > MMD' 카테고리의 다른 글

Shadow mapping (7)  (0) 2017.07.28
Shadow Mapping (6)  (0) 2017.07.26
Shadow Mapping (4)  (0) 2017.07.24
Shadow Mapping (3)  (0) 2017.07.24
FXAA  (0) 2017.07.18
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크