프로그래밍 2015.05.12 21:57

 

shadow vsm 구현 - 그림자 경계 다듬기 04

 

 

vsm 의 좀더 자세한 정보, 깊이버퍼값 기록과

픽셀 쉐이더에서 컬러값을 계산하는 방식은 

 

쉐이더 그림자 vsm pcf - 01       <----- 요기를 참조해 주세요.

 

 

 

vsm 기법에서 사용하는

체비쇼프 방정식 함수 입니다.

 

GpuGems 3 권을 참고하였습니다.

(그대로 베낀 것입니다)

 

// Computes Chebyshev's Inequality
// Returns an upper bound given the first two moments and mean
float ChebyshevUpperBound( float2 Moments, float Mean, float MinVariance )
{
    // Standard shadow map comparison
    float p = (Mean <= Moments.x);
   
    // Compute variance
    float Variance = Moments.y - (Moments.x * Moments.x);
    Variance = max(Variance, MinVariance);
   
    // Compute probabilistic upper bound
    float d     = (Mean - Moments.x);
    float p_max = Variance / (Variance + d*d);
   
    return max(p, p_max);
}

 

moments.x 는 깊이 버퍼 텍스쳐의 r 채널값

moments.y 는 moments.x * moments.x 값이 저장된 텍스쳐의 g 채널값

Mean 은 그림자 리시버( 그림자가 드리워질 면 )의 깊이값

MinVariance 는 최소 편차값( 이 값 이하라면, 그림자가 없는것으로 간주 )

 

vsm 에서 체비쇼프 방정식을 이용하는 이론적인 부분은

 

http://allosha.tistory.com/29      <------ 여기서 참고하실수 있습니다.

 

 

 

2진 판정이 아닌, 빛이 비칠 확률을 구하는 것이며, 결과값은 0~1,

그대로 그림자의 명암으로 사용할 수 있습니다.

 

 

위 코드를 살펴보면,

moments.y 자체가 원래 moments.x * moments.x 를 구한 값인데,

여기서

float Variance = Moments.y - (Moments.x * Moments.x);

이런 식으로 편차를 구합니다.

 

그림자 리시버에서 moments 값을 받아올때는,

필터링된 깊이 텍스쳐의 값을 받아오게 됩니다.

(즉, 깊이버퍼 텍스쳐는 반드시 필터링 옵션이 걸려 있어야 합니다.)

따라서 경계부분의 값이 필터링이 되면서, 

값이 보간되게 되고,  Moments.y 와 moments.x 의 값은 원본값보다

좀 더 큰 차이가 만들어 집니다.

 

 

온리 깊이버퍼 그림자에서 depth 값 하나만을 남기는 대신에

vsm 에서는 depth * depth 값을 추가하여 남깁니다.

 

moments 값을 구할때

미분계수를 구해서 값차이를 좀더 크게 만들어 주는 방법도 있습니다.

 

float2 ComputeMoments( float _fDepth, float2 _uv )
{
    float2 Moments;
 
   Moments.x = _fDepth;
   //Moments.y = _fDepth * _fDepth;

  

   //깊이의 미분계수를 계산한다.
   float dx = ddx(_fDepth);
   float dy = ddy(_fDepth); 
   Moments.y = _fDepth * _fDepth + 0.25f * (dx*dx + dy*dy);
 

   return Moments;
}

 

moments.y 값을 좀더 크게 만들어 주는 것입니다만,

기대했던 것과는 달리 경계가 더 부드러워지는 눈에 확 띄는 효과는 없었습니다.

 

moments 값이 0~1 사이의 미세한 값이라 그런것 같습니다만,

moments 값을 뻥튀기해서 사용한다든지 할때는 좀더 경계를 완하시키는데

도움이 될지도 모르겠습니다.

 

이어서 계속 설명드리겠습니다.

 

 

 

저작자 표시 비영리 변경 금지
신고
posted by 죠운죠운
TAG

댓글을 달아 주세요


티스토리 툴바