'SSGI'에 해당되는 글 1건

  1. 2010.03.17 SSGI 관련 정리 (소스 포함)

아래에서 퍼옴
http://eppengine.com/zbxe/2985#2



SSGI 는 GI 를 화면공간에서 처리하는 기법으로 화면상에 나타나 있는 모든 오브젝트들은 빛을 반사하여 발광하는 주체가 된다는 개념으로 예를들어, 붉은색 대리석 바닦에 놓여 있는 오브젝트의 경우 아래쪽은 ( 대리석과 맞닿아 있는 부분) 붉은색 빛이 표현 되어져야 한다 는 개념. 물론 SSGI 는 태생적으로 화면공간에서의 처리기법 이므로 화면밖의 오브젝트에대해서는 GI 개념을 적용하기가 애매한 부분이 있다. 전 처리를 통해 물론 해결은 가능하지만, 일반적인 기법에서는 화면밖의 붉은색 오브젝트는 화면안쪽에 있는 어떠한 오브젝트에도 영향을 주지 못한다.
그럼에도 SSGI 를 사용하지 않는 경우보다 훨씬 사실적이고 자연스러운 표현이 가능하다.
SSGI 는 크게 3가지 방식으로 사용되는데 전처리를 통해 마스킹 해 놓는 방식, 깊이만을 활용한 방식, 깊이와 노멀을 둘다 활용하는 방식이 있다. 아래는 깊이만을 활용한 방식이다.

uniform sampler2D som;  // Depth texture 
uniform sampler2D rand; // Random texture
uniform sampler2D color; // Color texture


uniform vec2 camerarange = vec2(1.0, 1024.0);
     
   float pw = 1.0/800.0*0.5;
   float ph = 1.0/600.0*0.5

   float readDepth(in vec2 coord) 
   { 
     if (coord.x<0||coord.y<0) return 1.0;
      float nearZ = camerarange.x; 
      float farZ =camerarange.y; 
      float posZ = texture2D(som, coord).x;  
      return (2.0 * nearZ) / (nearZ + farZ - posZ * (farZ - nearZ)); 
   }  

   vec3 readColor(in vec2 coord) 
   { 
     return texture2D(color, coord).xyz; 
   }

   float compareDepths(in float depth1, in float depth2) 
   { 
     float gauss = 0.0;
     float diff = (depth1 - depth2)*100.0; //depth difference (0-100)
     float gdisplace = 0.2; //gauss bell center
     float garea = 3.0; //gauss bell width

     //reduce left bell width to avoid self-shadowing
     if (diff<gdisplace) garea = 0.2;

     gauss = pow(2.7182,-2*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));

     return max(0.2,gauss); 
   } 

   vec3 calAO(float depth,float dw, float dh, inout float ao) 
   { 
     float temp = 0;
     vec3 bleed = vec3(0.0,0.0,0.0);
     float coordw = gl_TexCoord[0].x + dw/depth;
     float coordh = gl_TexCoord[0].y + dh/depth;

     if (coordw  < 1.0 && coordw  > 0.0 && coordh < 1.0 && coordh  > 0.0){

     vec2 coord = vec2(coordw , coordh);
     temp = compareDepths(depth, readDepth(coord));
        bleed = readColor(coord);

     }
     ao += temp;
     return temp*bleed; 
   }  
    
   void main(void
   { 
     //randomization texture:
     vec2 fres = vec2(20,20);
     vec3 random = texture2D(rand, gl_TexCoord[0].st*fres.xy);
     random = random*2.0-vec3(1.0);

     //initialize stuff:
     float depth = readDepth(gl_TexCoord[0]);
     vec3 gi = vec3(0.0,0.0,0.0); 
     float ao = 0.0;

     for(int i=0; i<8; ++i)
     { 
       //calculate color bleeding and ao:
       gi += calAO(depth,  pw, ph,ao); 
       gi += calAO(depth,  pw, -ph,ao); 
       gi += calAO(depth,  -pw, ph,ao); 
       gi += calAO(depth,  -pw, -ph,ao);
    
       //sample jittering:
       pw += random.x*0.0005;
       ph += random.y*0.0005;

       //increase sampling area:
       pw *= 1.4
       ph *= 1.4;   
     }        

     //final values, some adjusting:
     vec3 finalAO = vec3(1.0-(ao/32.0));
     vec3 finalGI = (gi/32)*0.6;

     gl_FragColor = vec4(readColor(gl_TexCoord[0])*finalAO+finalGI,1.0); 
   } 


장점, 단점은 ssao 랑 비슷

'게임 개발 > 3D 게임 플밍' 카테고리의 다른 글

Light Shaft  (0) 2010.03.17
SSAO (Screen Space Ambient Occlusion) 처리 기법(소스포함)  (0) 2010.03.17
언리얼 엔진 3 ( Unreal Engine 3 )  (0) 2009.12.03
BSP를 이용한 3D Game Programming  (0) 2005.11.16
GLUT 시작  (0) 2005.11.11
Posted by 노을삼킨별
,