armory/Shaders/ssdo_pass/ssdo_pass.frag.glsl
2016-10-25 13:01:20 +02:00

154 lines
7.2 KiB
GLSL
Executable file

// http://kayru.org/articles/dssdo/
#version 450
#ifdef GL_ES
precision mediump float;
#endif
#include "../compiled.glsl"
#include "../std/gbuffer.glsl"
// octahedronWrap
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D snoise;
uniform mat4 invVP;
uniform vec3 eye;
const vec2 screenSize = vec2(800.0, 600.0);
const vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
const int num_samples = 32;
const float g_occlusion_radius = 0.279710;
const float g_occlusion_max_distance = 0.639419;
const float fudge_factor_l0 = 2.0;
const float fudge_factor_l1 = 10.0;
const float sh2_weight_l0 = fudge_factor_l0 * 0.28209; //0.5*sqrt(1.0/pi);
const vec3 sh2_weight_l1 = vec3(fudge_factor_l1 * 0.48860); //0.5*sqrt(3.0/pi);
const vec4 sh2_weight = vec4(sh2_weight_l1, sh2_weight_l0) / num_samples;
in vec2 texCoord;
out vec4 fragColor;
vec4 doDO(vec3 point, vec3 noise, float radius, vec3 center_pos, float max_distance_inv, vec3 center_normal) {
vec2 textureOffset = reflect( point.xy, noise.xy ).xy * radius;
vec2 sample_tex = texCoord + textureOffset;
// float depth = 1.0 - texture(gbuffer0, sample_tex).a;
float depth = texture(gbufferD, sample_tex).r * 2.0 - 1.0;
vec3 sample_pos = getPos2(invVP, depth, sample_tex);
vec3 center_to_sample = sample_pos - center_pos;
float dist = length(center_to_sample);
vec3 center_to_sample_normalized = center_to_sample / dist;
float attenuation = 1.0 - clamp(dist * max_distance_inv, 0.0, 1.0);
float dp = dot(center_normal, center_to_sample_normalized);
const float attenuation_angle_threshold = 0.1;
attenuation = attenuation*attenuation * step(attenuation_angle_threshold, dp);
return attenuation * sh2_weight * vec4(center_to_sample_normalized, 1.0);
}
void main() {
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
if (depth == 1.0) {
fragColor = vec4(1.0);
return;
}
vec3 points[num_samples];
points[0] = vec3(-0.134, 0.044, -0.825);
points[1] = vec3(0.045, -0.431, -0.529);
points[2] = vec3(-0.537, 0.195, -0.371);
points[3] = vec3(0.525, -0.397, 0.713);
points[4] = vec3(0.895, 0.302, 0.139);
points[5] = vec3(-0.613, -0.408, -0.141);
points[6] = vec3(0.307, 0.822, 0.169);
points[7] = vec3(-0.819, 0.037, -0.388);
points[8] = vec3(0.376, 0.009, 0.193);
points[9] = vec3(-0.006, -0.103, -0.035);
points[10] = vec3(0.098, 0.393, 0.019);
points[11] = vec3(0.542, -0.218, -0.593);
points[12] = vec3(0.526, -0.183, 0.424);
points[13] = vec3(-0.529, -0.178, 0.684);
points[14] = vec3(0.066, -0.657, -0.570);
points[15] = vec3(-0.214, 0.288, 0.188);
points[16] = vec3(-0.689, -0.222, -0.192);
points[17] = vec3(-0.008, -0.212, -0.721);
points[18] = vec3(0.053, -0.863, 0.054);
points[19] = vec3(0.639, -0.558, 0.289);
points[20] = vec3(-0.255, 0.958, 0.099);
points[21] = vec3(-0.488, 0.473, -0.381);
points[22] = vec3(-0.592, -0.332, 0.137);
points[23] = vec3(0.080, 0.756, -0.494);
points[24] = vec3(-0.638, 0.319, 0.686);
points[25] = vec3(-0.663, 0.230, -0.634);
points[26] = vec3(0.235, -0.547, 0.664);
points[27] = vec3(0.164, -0.710, 0.086);
points[28] = vec3(-0.009, 0.493, -0.038);
points[29] = vec3(-0.322, 0.147, -0.105);
points[30] = vec3(-0.554, -0.725, 0.289);
points[31] = vec3(0.534, 0.157, -0.250);
vec2 enc = texture(gbuffer0, texCoord).rg;
vec3 currentNormal;
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
currentNormal = normalize(currentNormal);
vec3 currentPos = getPos2(invVP, depth, texCoord);
// float currentDistance = length(currentPos);
vec2 noise_texture_size = vec2(8.0,8.0);
vec3 center_pos = currentPos;
vec3 eye_pos = eye;
float center_depth = distance(eye_pos, center_pos);
float radius = g_occlusion_radius / center_depth;
float max_distance_inv = 1.0 / g_occlusion_max_distance;
// float attenuation_angle_threshold = 0.1;
vec3 noise = texture(snoise, (texCoord * screenSize) / noise_texture_size).xyz * 2.0 - 1.0;
vec3 center_normal = currentNormal;
vec4 occlusion_sh2 = vec4(0.0);
// for( int i=0; i<num_samples; ++i ) {
occlusion_sh2 += doDO(points[0], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[1], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[2], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[3], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[4], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[5], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[6], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[7], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[8], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[9], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[10], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[11], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[12], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[13], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[14], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[15], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[16], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[17], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[18], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[19], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[20], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[21], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[22], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[23], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[24], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[25], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[26], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[27], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[28], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[29], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[30], noise, radius, center_pos, max_distance_inv, center_normal);
occlusion_sh2 += doDO(points[31], noise, radius, center_pos, max_distance_inv, center_normal);
// }
fragColor = vec4(vec3(1.0 - occlusion_sh2.rgb), 1.0);
}