SSGI

  • SSGI / Screen Space Global Illumination
  • Illumination : 조명

구현

  • 반구 주변의 점으로 가려짐 정도(Occlusion factor) 계산
    • 성능상 샘플링 갯수를 줄이는게...
  • 계산된 가려짐 정도를 블러(Blur)로 적당히 흐려지게 만들기
  • 원본 텍스쳐에 적용

Case

// [(X) SSGI 관련 정리 (소스 포함)](http://eppengine.com/zbxe/programmig/2985)
// - backup article: https://babytook.tistory.com/157

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); 
}  

Ref