Commit f8730072 authored by Florian Oetke's avatar Florian Oetke
Browse files

better upsampling; higher resolution specular; normal based AO tweaks; general GI tweaks

parent 3be4fd8c
......@@ -48,7 +48,7 @@ vec3 expose(vec3 color, float threshold) {
float avg_luminance = max(exp(texture(avg_log_luminance_sampler, vec2(0.5, 0.5)).r), 0.001);
float key = 1.03f - (2.0f / (2 + log(avg_luminance + 1)/log(10)));
float exposure = log2(clamp(key/avg_luminance, 0.4, 5.0));
float exposure = log2(clamp(key/avg_luminance, 0.6, 5.0)+0.2);
exposure -= threshold;
return color * exp2(exposure);
......
......@@ -26,7 +26,7 @@ vec3 expose(vec3 color, float threshold) {
float avg_luminance = max(exp(texture(avg_log_luminance_sampler, vec2(0.5, 0.5)).r), 0.001);
float key = 1.03f - (2.0f / (2 + log(avg_luminance + 1)/log(10)));
float exposure = log2(clamp(key/avg_luminance, 0.8, 5.0));
float exposure = log2(clamp(key/avg_luminance, 0.8, 5.0)+0.5);
exposure -= threshold;
return max(color * exp2(exposure), vec3(0));
......
......@@ -2,6 +2,7 @@
#define COLOR_CONVERSION_INCLUDED
// source: http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
......
......@@ -29,32 +29,36 @@ layout(push_constant) uniform Push_constants {
void main() {
vec3 diffuse;
out_color = vec4(calculate_gi(vertex_out.tex_coords, vertex_out.tex_coords, 0,
out_color = vec4(calculate_gi(vertex_out.tex_coords, vertex_out.tex_coords, 1,
result_diff_sampler, result_spec_sampler,
albedo_sampler, mat_data_sampler, brdf_sampler, diffuse), 0.0);
// out_color = vec4(1,1,1,1);
if(pcs.prev_projection[3][3]>0.0) {
float ao = mix(1.0, texture(ao_sampler, vertex_out.tex_coords).r, pcs.prev_projection[3][3]);
float ao = upsampled_result(depth_sampler, mat_data_sampler, ao_sampler, 1, 0,
vertex_out.tex_coords, 1.0).r;
ao = mix(1.0, ao, pcs.prev_projection[3][3]);
out_color.rgb *= ao*0.9 + 0.1;
}
if(pcs.prev_projection[2][3]>=0) {
out_color.rgb = textureLod(result_diff_sampler, vertex_out.tex_coords, pcs.prev_projection[2][3]).rgb;
if(pcs.prev_projection[2][3]==0) {
out_color.rgb = upsampled_result(depth_sampler, mat_data_sampler, result_spec_sampler,
1, 0, vertex_out.tex_coords, 1.0).rgb;
out_color.a = 1;
} else if(pcs.prev_projection[2][3]>=1) {
out_color.rgb = textureLod(result_diff_sampler, vertex_out.tex_coords, pcs.prev_projection[2][3]-1).rgb;
out_color.a = 1;
/*
out_color.rgb = texelFetch(depth_sampler, ivec2(vertex_out.tex_coords
* textureSize(depth_sampler, int(pcs.prev_projection[2][3]))),
int(pcs.prev_projection[2][3])).rrr;
*/
out_color.a = 1;
// out_color = vec4(textureLod(mat_data_sampler, vertex_out.tex_coords, pcs.prev_projection[2][3]).rgb, 1.0);
// out_color = vec4(decode_normal(texelFetch(mat_data_sampler, ivec2(vertex_out.tex_coords*textureSize(mat_data_sampler, int(pcs.prev_projection[2][3]))), int(pcs.prev_projection[2][3])).rg), 1.0);
}
// out_color = vec4(decode_normal(textureLod(mat_data_sampler, vertex_out.tex_coords, 0).rg), 1.0);
// out_color = vec4(textureLod(mat_data_sampler, vertex_out.tex_coords, 0).rgb, 1.0);
// out_color = vec4(textureLod(albedo_sampler, vertex_out.tex_coords, 0).rgb, 1.0);
// out_color = vec4(texture(ao_sampler, vertex_out.tex_coords).rrr, 1.0);
}
......@@ -49,8 +49,8 @@ vec3 calculate_gi(vec2 uv, vec2 gi_uv, int gi_lod, sampler2D diff_sampler, sampl
sampler2D albedo_sampler, sampler2D mat_sampler, sampler2D brdf_sampler,
out vec3 diffuse) {
// load diff + spec GI
vec3 radiance = upsampled_result(depth_sampler, diff_sampler, 0, gi_lod, gi_uv, 0.5).rgb;
vec3 specular = upsampled_result(depth_sampler, spec_sampler, 0, 0, gi_uv, 2.0).rgb;
vec3 radiance = upsampled_result(depth_sampler, mat_data_sampler, diff_sampler, gi_lod, 0, gi_uv, 0.5).rgb;
vec3 specular = upsampled_result(depth_sampler, mat_data_sampler, spec_sampler, gi_lod, 0, gi_uv, 2.0).rgb;
return calculate_gi(uv, radiance, specular, albedo_sampler, mat_sampler, brdf_sampler, diffuse);
}
......
......@@ -67,15 +67,15 @@ void main() {
if(prev_uv.x>0.0 && prev_uv.x<1.0 && prev_uv.y>0.0 && prev_uv.y<1.0) {
// load diff + spec GI
vec3 radiance = upsampled_result(prev_depth_sampler, history_diff_sampler, 0, 0, prev_uv.xy, 1.0).rgb;
vec3 specular = upsampled_result(prev_depth_sampler, history_spec_sampler, 0, 0, prev_uv.xy, 1.0).rgb;
vec3 radiance = upsampled_result(prev_depth_sampler, mat_data_sampler, history_diff_sampler, 0, 0, prev_uv.xy, 1.0).rgb;
vec3 specular = upsampled_result(prev_depth_sampler, mat_data_sampler, history_spec_sampler, 0, 0, prev_uv.xy, 1.0).rgb;
vec3 diffuse;
vec3 gi = calculate_gi(vertex_out.tex_coords, radiance, specular,
albedo_sampler, mat_data_sampler, brdf_sampler, diffuse);
float ao = mix(1.0, texture(ao_sampler, vertex_out.tex_coords).r, ao_factor);
ao = ao*0.8 + 0.2;
ao = ao*0.5 + 0.5;
out_input = vec4(diffuse * ao, 0.0);
......
......@@ -16,6 +16,8 @@ layout(set=1, binding = 1) uniform sampler2D depth_sampler;
layout(set=1, binding = 2) uniform sampler2D mat_data_sampler;
layout(set=1, binding = 3) uniform sampler2D result_sampler;
layout(set=1, binding = 4) uniform sampler2D history_weight_sampler;
layout(set=1, binding = 5) uniform sampler2D depth_all_levels_sampler;
layout(set=1, binding = 6) uniform sampler2D mat_data_all_levels_sampler;
layout (constant_id = 0) const bool LAST_SAMPLE = false;
layout (constant_id = 1) const float R = 40;
......@@ -49,7 +51,7 @@ void main() {
float base_mip = pcs.prev_projection[3][3];
if(current_mip < max_mip)
out_color = vec4(upsampled_result(depth_sampler, result_sampler, 0, 0, vertex_out.tex_coords, 1.0).rgb, 1.0);
out_color = vec4(upsampled_result(depth_all_levels_sampler, mat_data_all_levels_sampler, result_sampler, int(current_mip), 0, vertex_out.tex_coords, 1.0).rgb, 1.0);
else
out_color = vec4(0,0,0, 1);
......@@ -62,7 +64,7 @@ void main() {
ivec2(vertex_out.tex_coords * textureSize(history_weight_sampler, 0)),
0).r;
out_color *= 1.0 - (history_weight*0.8);
out_color *= 1.0 - (history_weight*0.9);
}
out_color = max(out_color, vec4(0));
......@@ -70,6 +72,14 @@ void main() {
const float PI = 3.14159265359;
vec3 saturation(vec3 c, float change) {
vec3 f = vec3(0.299,0.587,0.114);
float p = sqrt(c.r*c.r*f.r + c.g*c.g*f.g + c.b*c.b*f.b);
return vec3(p) + (c-vec3(p))*vec3(change);
}
vec3 gi_sample(int lod) {
vec2 texture_size = textureSize(color_sampler, 0);
ivec2 uv = ivec2(vertex_out.tex_coords * texture_size);
......@@ -109,11 +119,14 @@ vec3 gi_sample(int lod) {
// could be used to blend between screen-space and static GI
// float visibility = 1.0 - (samples_used / float(SAMPLES));
if(PRIORITISE_NEAR_SAMPLES)
c = c * pow(2.0, max(lod*2, 3));
c = c * pow(2.0, clamp(lod*2 + depth*3, 2, 8));
else
c = c * pow(2.0, lod*2);
// c = saturation(c, 1.1);
// fade out if too few samples hit anything on screen
// c *= smoothstep(0.1, 0.2, samples_used/SAMPLES);
......@@ -169,7 +182,7 @@ vec3 calc_illumination_from(int lod, vec2 tex_size, ivec2 src_uv, vec2 shaded_uv
return vec3(0,0,0);
}
float r2 = max(r*r, 0.1);
float r2 = r*r;
vec3 dir = diff / r;
vec3 radiance = texelFetch(color_sampler, src_uv, 0).rgb;
......
......@@ -135,7 +135,7 @@ void main() {
vec3 raycast_hit_point;
if(traceScreenSpaceRay1(P+dir*0.25, dir, pcs.projection, depth_sampler,
depthSize, 1.0, global_uniforms.proj_planes.x,
max(4, 4), 0.1, 128, 32.0, int(startLod + 0.5),
max(4, 4), 0.5, 128, 32.0, int(startLod + 0.5),
raycast_hit_uv, raycast_hit_point)) {
vec3 L = raycast_hit_point - P;
......@@ -144,10 +144,9 @@ void main() {
float factor_distance = 1.0 - length(raycast_hit_point - P) / 16.0;
out_color.rgb = max(color * factor_distance, vec3(0));
} else {
out_color.rgb = textureLod(result_sampler, vertex_out.tex_coords, startLod).rgb / (2*PI*PI);
}
//out_color.rgb = max(out_color.rgb, textureLod(result_sampler, vertex_out.tex_coords, startLod).rgb / (2*PI*PI));
// out_color.rgb *= 0.6;
float history_weight = texelFetch(history_weight_sampler,
ivec2(vertex_out.tex_coords * textureSize(history_weight_sampler, 0)),
......
......@@ -14,8 +14,8 @@ layout(location = 0) out vec4 out_color;
layout (constant_id = 0) const int SAMPLES = 16;
layout (constant_id = 1) const int LOG_MAX_OFFSET = 4;
layout (constant_id = 2) const int SPIRAL_TURNS = 7;
layout (constant_id = 3) const float RADIUS = 0.7;
layout (constant_id = 4) const float BIAS = 0.01;
layout (constant_id = 3) const float RADIUS = 1.3;
layout (constant_id = 4) const float BIAS = 0.025;
layout(set=1, binding = 0) uniform sampler2D depth_sampler;
layout(set=1, binding = 1) uniform sampler2D mat_data_sampler;
......@@ -46,6 +46,13 @@ vec3 to_view_space(ivec2 ss_p, int mip) {
return mix(view_ray_x1, view_ray_x2, uv.y) * depth;
}
vec3 get_normal(ivec2 ss_p, int mip) {
return decode_normal(texelFetch(mat_data_sampler, ss_p, 0).rg);
ss_p = clamp(ss_p >> mip, ivec2(0), textureSize(mat_data_sampler, mip+MIN_MIP) - ivec2(1));
return decode_normal(texelFetch(mat_data_sampler, ss_p, mip+MIN_MIP).rg);
}
vec2 to_uv(vec3 pos) {
vec4 p = global_uniforms.proj_mat * vec4(pos, 1.0);
return (p.xy / p.w) * 0.5 + 0.5;
......@@ -61,13 +68,6 @@ vec2 tap_location(int i, float spin_angle, out float out_ss_radius) {
return vec2(cos(angle), sin(angle));
}
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
vec3 get_offset_position(ivec2 ss_center, vec2 dir, float ss_radius) {
int mip = clamp(int(floor(log2(ss_radius))) - LOG_MAX_OFFSET, 0, int(pcs.options.x));
return to_view_space(ivec2(ss_center + dir*ss_radius), mip);
}
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius */
float sample_ao(ivec2 ss_center, vec3 C, vec3 n_C, float ss_disk_radius, int i, float random_pattern_rotation_angle) {
......@@ -77,7 +77,10 @@ float sample_ao(ivec2 ss_center, vec3 C, vec3 n_C, float ss_disk_radius, int i,
ss_r *= ss_disk_radius;
// The occluding point in camera space
vec3 Q = get_offset_position(ss_center, unit_offset, ss_r);
int mip = clamp(int(floor(log2(ss_disk_radius))) - LOG_MAX_OFFSET, 0, int(pcs.options.x));
ivec2 ss_p = ivec2(ss_center + unit_offset*ss_r);
vec3 Q = to_view_space(ss_p, mip);
vec3 v = Q - C;
......@@ -86,9 +89,13 @@ float sample_ao(ivec2 ss_center, vec3 C, vec3 n_C, float ss_disk_radius, int i,
const float epsilon = 0.01;
vec3 N = get_normal(ss_p, mip);
float boost = smoothstep(0.01, 0.08, abs(dot(N, n_C)))*0.8+0.2;
boost += smoothstep(0.9, 1.0, abs(dot(N, n_C)))*2;
float f = max(RADIUS*RADIUS - vv, 0.0);
return f * f * f * max((vn - BIAS) / (epsilon + vv), 0.0);
return f * f * f * max((vn - BIAS) / (epsilon + vv), 0.0) * boost;
}
/** Used for packing Z into the GB channels */
......@@ -134,7 +141,7 @@ void main() {
float temp = RADIUS * RADIUS * RADIUS;
sum /= temp * temp;
out_color.r = max(0.0, 1.0 - sum * (5.0 / SAMPLES));
out_color.r = pow(out_color.r+0.02, 1.0 + (out_color.r-0.1));
out_color.r = pow(out_color.r, 1.0 + out_color.r*2);
// Bilateral box-filter over a quad for free, respecting depth edges
// (the difference that this makes is subtle)
......
......@@ -3,7 +3,7 @@
#extension GL_ARB_shading_language_420pack : enable
#include "normal_encoding.glsl"
#include "global_uniforms.glsl"
layout(location = 0) in Vertex_data {
vec2 uv_center;
......@@ -22,10 +22,12 @@ layout (constant_id = 0) const bool HORIZONTAL = true;
layout(set=1, binding = 0) uniform sampler2D depth_sampler;
layout(set=1, binding = 1) uniform sampler2D color_sampler;
vec3 read(vec2 uv, float center_depth, inout float weight_sum, float static_weight) {
float d = texture(depth_sampler, vertex_out.uv_center).r;
float d = texelFetch(depth_sampler, ivec2(uv*textureSize(depth_sampler, 0)), 0).r;
float dz = center_depth - d;
float w = clamp(exp(-dz*dz), 0.1, 1.0) * static_weight;
float d_dev = mix(0.02, 1.0, d) / global_uniforms.proj_planes.y;
float w = exp(-dz*dz/(2*d_dev*d_dev)) * static_weight;
weight_sum += w;
return texture(color_sampler, uv).rgb * w;
......
......@@ -19,16 +19,24 @@ float weight_offset(float x, float sharpness) {
float weight_depth(float x, float depth_dev) {
float b = 0;
float c = depth_dev;
return 0.2 * exp(- (x-b)*(x-b) / (2*c*c));
return 0.3 * exp(- (x-b)*(x-b) / (2*c*c));
}
float weight_mat_data(float x) {
return max(0.005, 1 - smoothstep(0.1, 0.3, x));
}
vec4 upsampled_result(sampler2D depth_sampler, sampler2D color_sampler, int depth_lod, int color_lod, vec2 tex_coords, float sharpness) {
vec2 color_size = textureSize(color_sampler, color_lod);
vec2 depth_size = textureSize(depth_sampler, depth_lod);
vec4 upsampled_result(sampler2D depth_sampler, sampler2D mat_data_sampler, sampler2D color_sampler,
int depth_lod, int color_lod, vec2 tex_coords, float sharpness) {
vec2 color_size = textureSize(color_sampler, color_lod);
vec2 depth_size = textureSize(depth_sampler, 0);
vec2 mat_data_size = textureSize(mat_data_sampler, depth_lod);
float depth = texelFetch(depth_sampler, ivec2(textureSize(depth_sampler, 0)*tex_coords), 0).r;
float depth_dev = mix(0.05, 1.5, depth) / global_uniforms.proj_planes.y;
vec2 normal = texelFetch(mat_data_sampler, ivec2(textureSize(mat_data_sampler, 0)*tex_coords), 0).xy;
float depth = texelFetch(depth_sampler, ivec2(depth_size*tex_coords), depth_lod).r;
float depth_dev = mix(0.05, 1.0, depth) / global_uniforms.proj_planes.y;
float weight_sum = 0;
vec4 color = vec4(0,0,0,0);
......@@ -37,9 +45,13 @@ vec4 upsampled_result(sampler2D depth_sampler, sampler2D color_sampler, int dept
vec2 offset = vec2(x,y);
vec2 p = tex_coords + offset / color_size;
float d = texelFetch(depth_sampler, ivec2(depth_size * p), depth_lod).r;
float d = texelFetch(depth_sampler, ivec2(depth_size * p), 0).r;
vec2 n = texelFetch(mat_data_sampler, ivec2(mat_data_size * p), depth_lod).xy;
vec2 normal_diff = normal - n;
float weight = weight_offset(dot(offset,offset), sharpness) * weight_depth(depth-d, depth_dev);
float weight = weight_offset(dot(offset,offset), sharpness)
* weight_depth(depth-d, depth_dev)
* weight_mat_data(dot(normal_diff, normal_diff));
vec4 c = texelFetch(color_sampler, ivec2(color_size * p), color_lod);
color += weight * c / (1 + luminance_ups(c.rgb));
......@@ -47,6 +59,9 @@ vec4 upsampled_result(sampler2D depth_sampler, sampler2D color_sampler, int dept
}
}
if(weight_sum<0.01)
return vec4(0,0,0,0);
color /= weight_sum;
return color / (1 - luminance_ups(color.rgb));
}
......
......@@ -29,7 +29,7 @@ namespace mirrage {
renderer::make_pass_factory<renderer::Gi_pass_factory>(),
renderer::make_pass_factory<renderer::Taa_pass_factory>(),
renderer::make_pass_factory<renderer::Tone_mapping_pass_factory>(),
//renderer::make_pass_factory<renderer::Bloom_pass_factory>(),
renderer::make_pass_factory<renderer::Bloom_pass_factory>(),
renderer::make_pass_factory<renderer::Blit_pass_factory>(),
renderer::make_pass_factory<renderer::Gui_pass_factory>()
)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment