mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-08 05:10:41 +01:00
feat(render): ground truth ambient occlusion darkens creases, recesses and the space under desks and frames, computed at half resolution from the reversed depth buffer with a depth-aware blur and multiplied into the image before motion blur, so it works with the default settings; thin parts in front of a surface, such as a steering wheel, shade it only from close by, and gfx.postfx.gtao.enabled, radius, intensity, directions and steps set it from the ini
This commit is contained in:
@@ -26,11 +26,12 @@ void gl::postfx::apply(opengl_texture &src, framebuffer *dst)
|
|||||||
apply({&src}, dst);
|
apply({&src}, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl::postfx::apply(std::vector<opengl_texture *> src, framebuffer *dst)
|
void gl::postfx::apply(std::vector<opengl_texture *> src, framebuffer *dst, bool clear)
|
||||||
{
|
{
|
||||||
if (dst)
|
if (dst)
|
||||||
{
|
{
|
||||||
dst->clear(GL_COLOR_BUFFER_BIT);
|
if (clear)
|
||||||
|
dst->clear(GL_COLOR_BUFFER_BIT);
|
||||||
dst->bind();
|
dst->bind();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ namespace gl
|
|||||||
|
|
||||||
void attach();
|
void attach();
|
||||||
void apply(opengl_texture &src, framebuffer *dst);
|
void apply(opengl_texture &src, framebuffer *dst);
|
||||||
void apply(std::vector<opengl_texture*> src, framebuffer *dst);
|
void apply(std::vector<opengl_texture*> src, framebuffer *dst, bool clear = true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,6 +214,13 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
|
|||||||
m_pfx_ssao_blur = std::make_unique<gl::postfx>("ssao_blur");
|
m_pfx_ssao_blur = std::make_unique<gl::postfx>("ssao_blur");
|
||||||
m_pfx_ssao_apply = std::make_unique<gl::postfx>("ssao_apply");
|
m_pfx_ssao_apply = std::make_unique<gl::postfx>("ssao_apply");
|
||||||
|
|
||||||
|
if (Global.gfx_postfx_gtao_enabled)
|
||||||
|
{
|
||||||
|
m_pfx_gtao = std::make_unique<gl::postfx>("gtao");
|
||||||
|
m_pfx_gtao_blur = std::make_unique<gl::postfx>("gtao_blur");
|
||||||
|
m_pfx_gtao_apply = std::make_unique<gl::postfx>("gtao_apply");
|
||||||
|
}
|
||||||
|
|
||||||
// Generate hemisphere kernel (z > 0 = toward surface normal)
|
// Generate hemisphere kernel (z > 0 = toward surface normal)
|
||||||
std::uniform_real_distribution<float> rnd(0.0f, 1.0f);
|
std::uniform_real_distribution<float> rnd(0.0f, 1.0f);
|
||||||
std::default_random_engine gen(42); // NOSONAR fixed seed on purpose, SSAO kernel has to be identical every run
|
std::default_random_engine gen(42); // NOSONAR fixed seed on purpose, SSAO kernel has to be identical every run
|
||||||
@@ -503,7 +510,7 @@ bool opengl33_renderer::init_viewport(viewport_config &vp)
|
|||||||
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
|
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
|
||||||
vp.msaa_fb->attach(*vp.msaa_rbd, GL_DEPTH_ATTACHMENT);
|
vp.msaa_fb->attach(*vp.msaa_rbd, GL_DEPTH_ATTACHMENT);
|
||||||
|
|
||||||
if (Global.gfx_postfx_chromaticaberration_enabled || Global.gfx_postfx_motionblur_enabled || Global.gfx_postfx_ssao_enabled)
|
if (Global.gfx_postfx_chromaticaberration_enabled || Global.gfx_postfx_motionblur_enabled || Global.gfx_postfx_ssao_enabled || Global.gfx_postfx_gtao_enabled)
|
||||||
{
|
{
|
||||||
vp.main_tex = std::make_unique<opengl_texture>();
|
vp.main_tex = std::make_unique<opengl_texture>();
|
||||||
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, 1, GL_CLAMP_TO_EDGE);
|
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, 1, GL_CLAMP_TO_EDGE);
|
||||||
@@ -566,6 +573,24 @@ bool opengl33_renderer::init_viewport(viewport_config &vp)
|
|||||||
if (!vp.ssao_blur_fb->is_complete()) { ErrorLog("ssao blur framebuffer setup failed"); return false; }
|
if (!vp.ssao_blur_fb->is_complete()) { ErrorLog("ssao blur framebuffer setup failed"); return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global.gfx_postfx_gtao_enabled)
|
||||||
|
{
|
||||||
|
int gtao_w = std::max(1, vp.width / 2);
|
||||||
|
int gtao_h = std::max(1, vp.height / 2);
|
||||||
|
|
||||||
|
vp.gtao_tex = std::make_unique<opengl_texture>();
|
||||||
|
vp.gtao_tex->alloc_rendertarget(GL_R8, GL_RED, gtao_w, gtao_h, 1, 1, GL_CLAMP_TO_EDGE);
|
||||||
|
vp.gtao_fb = std::make_unique<gl::framebuffer>();
|
||||||
|
vp.gtao_fb->attach(*vp.gtao_tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
if (!vp.gtao_fb->is_complete()) { ErrorLog("gtao framebuffer setup failed"); return false; }
|
||||||
|
|
||||||
|
vp.gtao_blur_tex = std::make_unique<opengl_texture>();
|
||||||
|
vp.gtao_blur_tex->alloc_rendertarget(GL_R8, GL_RED, gtao_w, gtao_h, 1, 1, GL_CLAMP_TO_EDGE);
|
||||||
|
vp.gtao_blur_fb = std::make_unique<gl::framebuffer>();
|
||||||
|
vp.gtao_blur_fb->attach(*vp.gtao_blur_tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
if (!vp.gtao_blur_fb->is_complete()) { ErrorLog("gtao blur framebuffer setup failed"); return false; }
|
||||||
|
}
|
||||||
|
|
||||||
if (!vp.main2_fb->is_complete())
|
if (!vp.main2_fb->is_complete())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1042,12 +1067,8 @@ if (!Global.gfx_skippipeline)
|
|||||||
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||||
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
|
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
|
||||||
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_DEPTH_BUFFER_BIT, GL_DEPTH_ATTACHMENT);
|
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_DEPTH_BUFFER_BIT, GL_DEPTH_ATTACHMENT);
|
||||||
|
|
||||||
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
|
|
||||||
model_ubo->update(model_ubs);
|
|
||||||
m_pfx_motionblur->apply({vp.main_tex.get(), vp.main_texv.get(), vp.main_texd.get()}, vp.main2_fb.get());
|
|
||||||
}
|
}
|
||||||
else if (Global.gfx_postfx_ssao_enabled)
|
else if (Global.gfx_postfx_ssao_enabled || Global.gfx_postfx_gtao_enabled)
|
||||||
{
|
{
|
||||||
// resolve color+depth so SSAO can sample the depth texture
|
// resolve color+depth so SSAO can sample the depth texture
|
||||||
vp.main_fb->clear(GL_COLOR_BUFFER_BIT);
|
vp.main_fb->clear(GL_COLOR_BUFFER_BIT);
|
||||||
@@ -1061,6 +1082,42 @@ if (!Global.gfx_skippipeline)
|
|||||||
vp.msaa_fb->blit_to(vp.main2_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
vp.msaa_fb->blit_to(vp.main2_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global.gfx_postfx_gtao_enabled)
|
||||||
|
{
|
||||||
|
int gtao_w = std::max(1, vp.width / 2);
|
||||||
|
int gtao_h = std::max(1, vp.height / 2);
|
||||||
|
bool const blend { glIsEnabled(GL_BLEND) == GL_TRUE };
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
model_ubs.param[0] = glm::vec4(Global.gfx_postfx_gtao_radius, Global.gfx_postfx_gtao_intensity, static_cast<float>(Global.gfx_postfx_gtao_directions), static_cast<float>(Global.gfx_postfx_gtao_steps));
|
||||||
|
model_ubs.param[1] = glm::vec4((GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control) ? 1.f : 0.f, 1000.f, 0.f, 0.f);
|
||||||
|
model_ubo->update(model_ubs);
|
||||||
|
glViewport(0, 0, gtao_w, gtao_h);
|
||||||
|
m_pfx_gtao->apply({ vp.main_texd.get() }, vp.gtao_fb.get());
|
||||||
|
m_pfx_gtao_blur->apply({ vp.gtao_tex.get(), vp.main_texd.get() }, vp.gtao_blur_fb.get());
|
||||||
|
|
||||||
|
glViewport(0, 0, vp.width, vp.height);
|
||||||
|
vp.main_fb->setup_drawing(1);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||||
|
m_pfx_gtao_apply->apply({ vp.gtao_blur_tex.get() }, vp.main_fb.get(), false);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
if (!blend)
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Global.gfx_postfx_motionblur_enabled)
|
||||||
|
{
|
||||||
|
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
|
||||||
|
model_ubo->update(model_ubs);
|
||||||
|
m_pfx_motionblur->apply({vp.main_tex.get(), vp.main_texv.get(), vp.main_texd.get()}, vp.main2_fb.get());
|
||||||
|
}
|
||||||
|
else if (Global.gfx_postfx_gtao_enabled && !Global.gfx_postfx_ssao_enabled)
|
||||||
|
{
|
||||||
|
vp.main2_fb->clear(GL_COLOR_BUFFER_BIT);
|
||||||
|
vp.main_fb->blit_to(vp.main2_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||||
|
}
|
||||||
|
|
||||||
// SSAO: depth -> occlusion -> blur -> modulate color into main2_fb
|
// SSAO: depth -> occlusion -> blur -> modulate color into main2_fb
|
||||||
if (Global.gfx_postfx_ssao_enabled && !Global.gfx_postfx_motionblur_enabled)
|
if (Global.gfx_postfx_ssao_enabled && !Global.gfx_postfx_motionblur_enabled)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -251,6 +251,11 @@ class opengl33_renderer : public gfx_renderer {
|
|||||||
std::unique_ptr<gl::framebuffer> ssao_fb;
|
std::unique_ptr<gl::framebuffer> ssao_fb;
|
||||||
std::unique_ptr<gl::framebuffer> ssao_blur_fb;
|
std::unique_ptr<gl::framebuffer> ssao_blur_fb;
|
||||||
|
|
||||||
|
std::unique_ptr<opengl_texture> gtao_tex;
|
||||||
|
std::unique_ptr<opengl_texture> gtao_blur_tex;
|
||||||
|
std::unique_ptr<gl::framebuffer> gtao_fb;
|
||||||
|
std::unique_ptr<gl::framebuffer> gtao_blur_fb;
|
||||||
|
|
||||||
// LDR backbuffer for offscreen rendering
|
// LDR backbuffer for offscreen rendering
|
||||||
std::unique_ptr<gl::framebuffer> backbuffer_fb;
|
std::unique_ptr<gl::framebuffer> backbuffer_fb;
|
||||||
std::unique_ptr<opengl_texture> backbuffer_tex;
|
std::unique_ptr<opengl_texture> backbuffer_tex;
|
||||||
@@ -513,6 +518,10 @@ class opengl33_renderer : public gfx_renderer {
|
|||||||
std::unique_ptr<opengl_texture> m_ssao_noise_tex;
|
std::unique_ptr<opengl_texture> m_ssao_noise_tex;
|
||||||
glm::vec3 m_ssao_kernel[32];
|
glm::vec3 m_ssao_kernel[32];
|
||||||
|
|
||||||
|
std::unique_ptr<gl::postfx> m_pfx_gtao;
|
||||||
|
std::unique_ptr<gl::postfx> m_pfx_gtao_blur;
|
||||||
|
std::unique_ptr<gl::postfx> m_pfx_gtao_apply;
|
||||||
|
|
||||||
std::unique_ptr<gl::program> m_shadow_shader;
|
std::unique_ptr<gl::program> m_shadow_shader;
|
||||||
std::unique_ptr<gl::program> m_alpha_shadow_shader;
|
std::unique_ptr<gl::program> m_alpha_shadow_shader;
|
||||||
|
|
||||||
|
|||||||
102
shaders/postfx_gtao.frag
Normal file
102
shaders/postfx_gtao.frag
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
in vec2 f_coords;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
#texture (depth_tex, 0, R)
|
||||||
|
uniform sampler2D depth_tex;
|
||||||
|
|
||||||
|
#include <common>
|
||||||
|
|
||||||
|
const float PI = 3.14159265;
|
||||||
|
const float HALF_PI = 1.57079633;
|
||||||
|
|
||||||
|
vec3 view_position(ivec2 texel)
|
||||||
|
{
|
||||||
|
vec2 size = vec2(textureSize(depth_tex, 0));
|
||||||
|
texel = clamp(texel, ivec2(0), ivec2(size) - 1);
|
||||||
|
float depth = max(texelFetch(depth_tex, texel, 0).r, 1e-6);
|
||||||
|
float ndcz = (param[1].x > 0.5 ? depth : depth * 2.0 - 1.0);
|
||||||
|
float z = -projection[3][2] / (ndcz + projection[2][2]);
|
||||||
|
vec2 ndc = (vec2(texel) + 0.5) / size * 2.0 - 1.0;
|
||||||
|
return vec3((-ndc.x * z - projection[2][0] * z) / projection[0][0],
|
||||||
|
(-ndc.y * z - projection[2][1] * z) / projection[1][1],
|
||||||
|
z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 size = vec2(textureSize(depth_tex, 0));
|
||||||
|
ivec2 center = ivec2(f_coords * size);
|
||||||
|
if (texelFetch(depth_tex, center, 0).r <= 0.0) {
|
||||||
|
out_color = vec4(1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 P = view_position(center);
|
||||||
|
vec3 V = normalize(-P);
|
||||||
|
vec3 right = view_position(center + ivec2(1, 0)) - P;
|
||||||
|
vec3 left = P - view_position(center - ivec2(1, 0));
|
||||||
|
vec3 up = view_position(center + ivec2(0, 1)) - P;
|
||||||
|
vec3 down = P - view_position(center - ivec2(0, 1));
|
||||||
|
vec3 N = normalize(cross(abs(right.z) < abs(left.z) ? right : left, abs(up.z) < abs(down.z) ? up : down));
|
||||||
|
if (dot(N, V) < 0.0)
|
||||||
|
N = -N;
|
||||||
|
|
||||||
|
float radius = param[0].x;
|
||||||
|
float pixels = radius * projection[1][1] * 0.5 * size.y / -P.z;
|
||||||
|
if (pixels < 2.0) {
|
||||||
|
out_color = vec4(1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pixels = min(pixels, size.y * 0.25);
|
||||||
|
|
||||||
|
int directions = max(int(param[0].z), 1);
|
||||||
|
int steps = max(int(param[0].w), 1);
|
||||||
|
float falloffrange = 0.6 * radius;
|
||||||
|
float falloffmul = -1.0 / falloffrange;
|
||||||
|
float falloffadd = (radius - falloffrange) / falloffrange + 1.0;
|
||||||
|
float noise = fract(52.9829189 * fract(dot(gl_FragCoord.xy, vec2(0.06711056, 0.00583715))));
|
||||||
|
float jitter = fract(noise * 1.61803399);
|
||||||
|
|
||||||
|
float visibility = 0.0;
|
||||||
|
for (int d = 0; d < directions; ++d)
|
||||||
|
{
|
||||||
|
float phi = (float(d) + noise) * PI / float(directions);
|
||||||
|
vec2 omega = vec2(cos(phi), sin(phi));
|
||||||
|
vec3 direction = vec3(omega, 0.0);
|
||||||
|
vec3 ortho = direction - dot(direction, V) * V;
|
||||||
|
vec3 axis = normalize(cross(ortho, V));
|
||||||
|
vec3 projected = N - axis * dot(N, axis);
|
||||||
|
float projectedlength = length(projected);
|
||||||
|
float cosn = clamp(dot(projected, V) / max(projectedlength, 1e-4), 0.0, 1.0);
|
||||||
|
float n = sign(dot(ortho, projected)) * acos(cosn);
|
||||||
|
float lowcos0 = cos(n + HALF_PI);
|
||||||
|
float lowcos1 = cos(n - HALF_PI);
|
||||||
|
float horizoncos0 = lowcos0;
|
||||||
|
float horizoncos1 = lowcos1;
|
||||||
|
for (int s = 0; s < steps; ++s)
|
||||||
|
{
|
||||||
|
float t = (float(s) + jitter) / float(steps);
|
||||||
|
t = t * t;
|
||||||
|
vec2 offset = omega * max(t * pixels, 1.5);
|
||||||
|
vec3 delta0 = view_position(center + ivec2(round(offset))) - P;
|
||||||
|
vec3 delta1 = view_position(center - ivec2(round(offset))) - P;
|
||||||
|
float length0 = length(delta0);
|
||||||
|
float length1 = length(delta1);
|
||||||
|
float weight0 = clamp(length(vec3(delta0.xy, delta0.z * (delta0.z > 0.0 ? 5.0 : 1.0))) * falloffmul + falloffadd, 0.0, 1.0);
|
||||||
|
float weight1 = clamp(length(vec3(delta1.xy, delta1.z * (delta1.z > 0.0 ? 5.0 : 1.0))) * falloffmul + falloffadd, 0.0, 1.0);
|
||||||
|
horizoncos0 = max(horizoncos0, mix(lowcos0, dot(delta0, V) / max(length0, 1e-4), weight0));
|
||||||
|
horizoncos1 = max(horizoncos1, mix(lowcos1, dot(delta1, V) / max(length1, 1e-4), weight1));
|
||||||
|
}
|
||||||
|
float h0 = -acos(clamp(horizoncos1, -1.0, 1.0));
|
||||||
|
float h1 = acos(clamp(horizoncos0, -1.0, 1.0));
|
||||||
|
h0 = n + clamp(h0 - n, -HALF_PI, HALF_PI);
|
||||||
|
h1 = n + clamp(h1 - n, -HALF_PI, HALF_PI);
|
||||||
|
float arc0 = (cosn + 2.0 * h0 * sin(n) - cos(2.0 * h0 - n)) * 0.25;
|
||||||
|
float arc1 = (cosn + 2.0 * h1 * sin(n) - cos(2.0 * h1 - n)) * 0.25;
|
||||||
|
visibility += projectedlength * (arc0 + arc1);
|
||||||
|
}
|
||||||
|
visibility = clamp(visibility / float(directions), 0.0, 1.0);
|
||||||
|
float fade = smoothstep(param[1].y * 0.75, param[1].y, -P.z);
|
||||||
|
out_color = vec4(mix(visibility, 1.0, fade));
|
||||||
|
}
|
||||||
13
shaders/postfx_gtao_apply.frag
Normal file
13
shaders/postfx_gtao_apply.frag
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
in vec2 f_coords;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
#texture (ao_tex, 0, R)
|
||||||
|
uniform sampler2D ao_tex;
|
||||||
|
|
||||||
|
#include <common>
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
out_color = vec4(vec3(pow(clamp(texture(ao_tex, f_coords).r, 0.0, 1.0), param[0].y)), 1.0);
|
||||||
|
}
|
||||||
45
shaders/postfx_gtao_blur.frag
Normal file
45
shaders/postfx_gtao_blur.frag
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
in vec2 f_coords;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
#texture (ao_tex, 0, R)
|
||||||
|
uniform sampler2D ao_tex;
|
||||||
|
|
||||||
|
#texture (depth_tex, 1, R)
|
||||||
|
uniform sampler2D depth_tex;
|
||||||
|
|
||||||
|
#include <common>
|
||||||
|
|
||||||
|
float view_distance(vec2 uv)
|
||||||
|
{
|
||||||
|
ivec2 size = textureSize(depth_tex, 0);
|
||||||
|
float depth = texelFetch(depth_tex, clamp(ivec2(uv * vec2(size)), ivec2(0), size - 1), 0).r;
|
||||||
|
if (depth <= 0.0)
|
||||||
|
return 1e6;
|
||||||
|
float ndcz = (param[1].x > 0.5 ? depth : depth * 2.0 - 1.0);
|
||||||
|
return projection[3][2] / (ndcz + projection[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 texel = 1.0 / vec2(textureSize(ao_tex, 0));
|
||||||
|
float center = view_distance(f_coords);
|
||||||
|
if (center >= 1e6) {
|
||||||
|
out_color = vec4(1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float sum = 0.0;
|
||||||
|
float weights = 0.0;
|
||||||
|
for (int y = -2; y <= 2; ++y)
|
||||||
|
{
|
||||||
|
for (int x = -2; x <= 2; ++x)
|
||||||
|
{
|
||||||
|
vec2 uv = f_coords + vec2(float(x), float(y)) * texel;
|
||||||
|
float difference = (view_distance(uv) - center) / (center * 0.02 + 0.01);
|
||||||
|
float weight = exp(-float(x * x + y * y) / 4.5 - difference * difference);
|
||||||
|
sum += texture(ao_tex, uv).r * weight;
|
||||||
|
weights += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_color = vec4(sum / max(weights, 1e-4));
|
||||||
|
}
|
||||||
@@ -1442,6 +1442,31 @@ global_settings::ConfigParse_gfx( cParser &Parser, std::string_view const Token
|
|||||||
Parser.getTokens(1);
|
Parser.getTokens(1);
|
||||||
Parser >> gfx_postfx_chromaticaberration_enabled;
|
Parser >> gfx_postfx_chromaticaberration_enabled;
|
||||||
}
|
}
|
||||||
|
else if (Token == "gfx.postfx.gtao.enabled")
|
||||||
|
{
|
||||||
|
Parser.getTokens(1);
|
||||||
|
Parser >> gfx_postfx_gtao_enabled;
|
||||||
|
}
|
||||||
|
else if (Token == "gfx.postfx.gtao.radius")
|
||||||
|
{
|
||||||
|
Parser.getTokens(1);
|
||||||
|
Parser >> gfx_postfx_gtao_radius;
|
||||||
|
}
|
||||||
|
else if (Token == "gfx.postfx.gtao.intensity")
|
||||||
|
{
|
||||||
|
Parser.getTokens(1);
|
||||||
|
Parser >> gfx_postfx_gtao_intensity;
|
||||||
|
}
|
||||||
|
else if (Token == "gfx.postfx.gtao.directions")
|
||||||
|
{
|
||||||
|
Parser.getTokens(1);
|
||||||
|
Parser >> gfx_postfx_gtao_directions;
|
||||||
|
}
|
||||||
|
else if (Token == "gfx.postfx.gtao.steps")
|
||||||
|
{
|
||||||
|
Parser.getTokens(1);
|
||||||
|
Parser >> gfx_postfx_gtao_steps;
|
||||||
|
}
|
||||||
else if (Token == "gfx.format.color")
|
else if (Token == "gfx.format.color")
|
||||||
{
|
{
|
||||||
Parser.getTokens(1);
|
Parser.getTokens(1);
|
||||||
@@ -1753,6 +1778,11 @@ global_settings::export_as_text( std::ostream &Output ) const {
|
|||||||
export_as_text( Output, "gfx.postfx.motionblur.shutter", gfx_postfx_motionblur_shutter );
|
export_as_text( Output, "gfx.postfx.motionblur.shutter", gfx_postfx_motionblur_shutter );
|
||||||
// TODO: export gfx_postfx_motionblur_format
|
// TODO: export gfx_postfx_motionblur_format
|
||||||
export_as_text( Output, "gfx.postfx.chromaticaberration.enabled", gfx_postfx_chromaticaberration_enabled );
|
export_as_text( Output, "gfx.postfx.chromaticaberration.enabled", gfx_postfx_chromaticaberration_enabled );
|
||||||
|
export_as_text( Output, "gfx.postfx.gtao.enabled", gfx_postfx_gtao_enabled );
|
||||||
|
export_as_text( Output, "gfx.postfx.gtao.radius", gfx_postfx_gtao_radius );
|
||||||
|
export_as_text( Output, "gfx.postfx.gtao.intensity", gfx_postfx_gtao_intensity );
|
||||||
|
export_as_text( Output, "gfx.postfx.gtao.directions", gfx_postfx_gtao_directions );
|
||||||
|
export_as_text( Output, "gfx.postfx.gtao.steps", gfx_postfx_gtao_steps );
|
||||||
// TODO: export gfx_format_color
|
// TODO: export gfx_format_color
|
||||||
// TODO: export gfx_format_depth
|
// TODO: export gfx_format_depth
|
||||||
export_as_text( Output, "gfx.skiprendering", gfx_skiprendering );
|
export_as_text( Output, "gfx.skiprendering", gfx_skiprendering );
|
||||||
|
|||||||
@@ -293,6 +293,11 @@ struct global_settings {
|
|||||||
GLenum gfx_format_color = GL_RGB16F;
|
GLenum gfx_format_color = GL_RGB16F;
|
||||||
GLenum gfx_format_depth = GL_DEPTH_COMPONENT32F;
|
GLenum gfx_format_depth = GL_DEPTH_COMPONENT32F;
|
||||||
bool gfx_postfx_chromaticaberration_enabled = true;
|
bool gfx_postfx_chromaticaberration_enabled = true;
|
||||||
|
bool gfx_postfx_gtao_enabled = true;
|
||||||
|
float gfx_postfx_gtao_radius = 0.35f;
|
||||||
|
float gfx_postfx_gtao_intensity = 2.0f;
|
||||||
|
int gfx_postfx_gtao_directions = 2;
|
||||||
|
int gfx_postfx_gtao_steps = 8;
|
||||||
bool gfx_skippipeline = false;
|
bool gfx_skippipeline = false;
|
||||||
bool gfx_extraeffects = true;
|
bool gfx_extraeffects = true;
|
||||||
bool gfx_shadergamma = false;
|
bool gfx_shadergamma = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user