Skip to content

Commit

Permalink
Much better SSAO
Browse files Browse the repository at this point in the history
  • Loading branch information
CodingJellyfish committed Jan 16, 2025
1 parent f8c6c66 commit 6db816e
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 104 deletions.
11 changes: 8 additions & 3 deletions data/shaders/IBL.frag
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform sampler2D albedo;
uniform sampler2D ssao;

#ifdef GL_ES
layout (location = 0) out vec4 Diff;
Expand Down Expand Up @@ -76,8 +77,9 @@ void main(void)
{
vec2 uv = gl_FragCoord.xy / u_screen;
vec3 normal = DecodeNormal(texture(ntex, uv).xy);
float ao = texture(ssao, uv).x;

Diff = vec4(0.25 * DiffuseIBL(normal), 1.);
Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.);

float z = texture(dtex, uv).x;

Expand All @@ -86,8 +88,11 @@ void main(void)
// Extract roughness
float specval = texture(ntex, uv).z;

// Lagarde and de Rousiers 2014, "Moving Frostbite to PBR"
float ao_spec = clamp(pow(max(dot(normal, eyedir), 0.) + ao, exp2(-16.0 * (1.0 - specval) - 1.0)) - 1.0 + ao);

#ifdef GL_ES
Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval), 1.);
Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval) * ao_spec, 1.);
#else
// :::::::: Compute Space Screen Reflection ::::::::::::::::::::::::::::::::::::

Expand Down Expand Up @@ -123,7 +128,7 @@ void main(void)
outColor = fallback;
}

Spec = vec4(outColor.rgb, 1.0);
Spec = vec4(outColor.rgb * ao_spec, 1.0);
#endif

}
4 changes: 2 additions & 2 deletions data/shaders/bilateralH.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ out vec4 FragColor;

void main()
{
float sigma = 5.;
float sigma = 2.;

vec2 uv = gl_FragCoord.xy * pixel;
float X = uv.x;
Expand All @@ -23,7 +23,7 @@ void main()
g0 *= g1;
g1 *= g2;
float tmp_weight, total_weight = g0;
for (int i = 1; i < 9; i++) {
for (int i = 1; i < 3; i++) {
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X - float(i) * pixel.x, Y)).x - pixel_depth));
sum += texture(tex, vec2(X - float(i) * pixel.x, Y)) * g0 * tmp_weight;
total_weight += g0 * tmp_weight;
Expand Down
4 changes: 2 additions & 2 deletions data/shaders/bilateralV.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ out vec4 FragColor;

void main()
{
float sigma = 5.;
float sigma = 2.;

vec2 uv = gl_FragCoord.xy * pixel;
float X = uv.x;
Expand All @@ -23,7 +23,7 @@ void main()
g0 *= g1;
g1 *= g2;
float tmp_weight, total_weight = g0;
for (int i = 1; i < 9; i++) {
for (int i = 1; i < 3; i++) {
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X, Y - float(i) * pixel.y)).x - pixel_depth));
sum += texture(tex, vec2(X, Y - float(i) * pixel.y)) * g0 * tmp_weight;
total_weight += g0 * tmp_weight;
Expand Down
4 changes: 1 addition & 3 deletions data/shaders/combine_diffuse_color.frag
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
uniform sampler2D diffuse_map;
uniform sampler2D specular_map;
uniform sampler2D ssao_tex;
uniform sampler2D normal_color;
uniform sampler2D diffuse_color;
#if defined(GL_ES) && defined(GL_FRAGMENT_PRECISION_HIGH)
Expand Down Expand Up @@ -28,7 +27,6 @@ void main()
float specMapValue = texture(normal_color, tc).z;
float emitMapValue = diffuseMatColor.w;

float ao = texture(ssao_tex, tc).x;
vec3 DiffuseComponent = texture(diffuse_map, tc).xyz;
vec3 SpecularComponent = texture(specular_map, tc).xyz;

Expand All @@ -42,7 +40,7 @@ void main()
vec3 tmp = DiffuseComponent * mix(diffuseMatColor.xyz, vec3(0.0), metallicMapValue) + (metallicMatColor * SpecularComponent);

vec3 emitCol = diffuseMatColor.xyz + (diffuseMatColor.xyz * diffuseMatColor.xyz * emitMapValue * emitMapValue * 10.0);
vec4 color_1 = vec4(tmp * ao + (emitMapValue * emitCol), 1.0);
vec4 color_1 = vec4(tmp + (emitMapValue * emitCol), 1.0);

// Fog
float depth = texture(depth_stencil, tc).x;
Expand Down
7 changes: 5 additions & 2 deletions data/shaders/degraded_ibl.frag
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
uniform sampler2D ntex;
uniform sampler2D ssao;

#ifdef GL_ES
layout (location = 0) out vec4 Diff;
Expand All @@ -17,7 +18,9 @@ void main(void)
{
vec2 uv = gl_FragCoord.xy / u_screen;
vec3 normal = DecodeNormal(texture(ntex, uv).xy);
vec3 spec_color = vec3(0.031, 0.106, 0.173);
float ao = texture(ssao, uv).x;

Diff = vec4(0.25 * DiffuseIBL(normal), 1.);
Spec = vec4(0.031, 0.106, 0.173, 1.);
Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.);
Spec = vec4(spec_color * ao, 1.);
}
42 changes: 27 additions & 15 deletions data/shaders/ssao.frag
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/
// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/
// and implementations here https://github.com/google/filament/blob/026b985c07b7eec4f678e0e5130d0a4e742e9c61/filament/src/materials/ssao/saoImpl.fs

uniform sampler2D dtex;
uniform float radius;
uniform float k;
uniform float sigma;
out float AO;

const float tau = 7.;
const float beta = 0.002;
const float epsilon = .00001;
const float bias = .0005;
const float thickness = 10.0;

#define SAMPLES 16
const float invSamples = 0.0625; // 1. / SAMPLES
#define SAMPLES 8
const float invSamples = 0.125; // 1. / SAMPLES

vec3 getXcYcZc(int x, int y, float zC)
{
Expand All @@ -22,6 +22,12 @@ vec3 getXcYcZc(int x, int y, float zC)
return vec3(xC, yC, zC);
}

float interleavedGradientNoise(highp vec2 w)
{
const vec3 m = vec3(0.06711056, 0.00583715, 52.9829189);
return fract(m.z * fract(dot(w, m.xy)));
}

void main(void)
{
vec2 uv = gl_FragCoord.xy / u_screen;
Expand All @@ -34,32 +40,38 @@ void main(void)
vec3 ddy = dFdy(FragPos);
vec3 norm = normalize(cross(ddy, ddx));

float r = radius / FragPos.z;
float phi = 3. * float((x ^ y) + x * y);
float r = radius / FragPos.z * 0.5;
float phi = interleavedGradientNoise(vec2(gl_FragCoord.x, gl_FragCoord.y));
float bl = 0.0;
float m = log2(r) + 6. + log2(invSamples);

float theta = mod(2. * 3.14 * tau * .5 * invSamples + phi, 6.283185307179586);
float peak = 0.1 * radius;
float peak2 = peak * peak;
float intensity = 2.0 * 3.14159 * sigma * peak * invSamples;

float theta = phi * 2.0 * 2.4 * 3.14159;
vec2 rotations = vec2(cos(theta), sin(theta)) * u_screen;
vec2 offset = vec2(cos(invSamples), sin(invSamples));

for(int i = 0; i < SAMPLES; ++i) {
for(int i = 0; i < SAMPLES; ++i)
{
float alpha = (float(i) + .5) * invSamples;
rotations = vec2(rotations.x * offset.x - rotations.y * offset.y, rotations.x * offset.y + rotations.y * offset.x);
float h = r * alpha;
vec2 localoffset = h * rotations;

m = m + .5;
ivec2 ioccluder_uv = ivec2(x, y) + ivec2(localoffset);

if (ioccluder_uv.x < 0 || ioccluder_uv.x > int(u_screen.x) || ioccluder_uv.y < 0 || ioccluder_uv.y > int(u_screen.y)) continue;
ivec2 ioccluder_uv = clamp(ivec2(x, y) + ivec2(localoffset), ivec2(0), ivec2(u_screen));

float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / u_screen, max(m, 0.)).x;
vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth);

vec3 vi = OccluderPos - FragPos;
bl += max(0., dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon);
float vv = dot(vi, vi);
float vn = dot(vi, norm);
float w = max(0.0, 1.0 - vv / thickness / thickness);
w = w * w;
bl += w * max(0., vn - FragPos.z * bias) / (vv + peak);
}

AO = max(pow(1.0 - min(2. * sigma * bl * invSamples, 0.99), k), 0.);
AO = pow(max(1.0 - sqrt(bl * intensity), 0.), k);
}
22 changes: 14 additions & 8 deletions src/graphics/lighting_passes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class PointLightScatterShader : public TextureShader<PointLightScatterShader,
};

// ============================================================================
class IBLShader : public TextureShader<IBLShader, 4>
class IBLShader : public TextureShader<IBLShader, 5>
{
public:
IBLShader()
Expand All @@ -181,20 +181,22 @@ class IBLShader : public TextureShader<IBLShader, 4>
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED,
2, "probe", ST_TRILINEAR_CUBEMAP,
3, "albedo",ST_NEAREST_FILTERED);
3, "albedo",ST_NEAREST_FILTERED,
4, "ssao", ST_NEAREST_FILTERED);
} // IBLShader
}; // IBLShader

// ============================================================================
class DegradedIBLShader : public TextureShader<DegradedIBLShader, 1>
class DegradedIBLShader : public TextureShader<DegradedIBLShader, 2>
{
public:
DegradedIBLShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "degraded_ibl.frag");
assignUniforms();
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED);
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "ssao", ST_NEAREST_FILTERED);
} // DegradedIBLShader
}; // DegradedIBLShader

Expand Down Expand Up @@ -298,7 +300,8 @@ static void renderPointLights(unsigned count,
void LightingPasses::renderEnvMap(GLuint normal_depth_texture,
GLuint depth_stencil_texture,
GLuint specular_probe,
GLuint albedo_buffer)
GLuint albedo_buffer,
GLuint ssao_texture)
{
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
Expand All @@ -311,7 +314,7 @@ void LightingPasses::renderEnvMap(GLuint normal_depth_texture,
glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO());

DegradedIBLShader::getInstance()
->setTextureUnits(normal_depth_texture);
->setTextureUnits(normal_depth_texture, ssao_texture);
DegradedIBLShader::getInstance()->setUniforms();
}
else
Expand All @@ -323,7 +326,8 @@ void LightingPasses::renderEnvMap(GLuint normal_depth_texture,
normal_depth_texture,
depth_stencil_texture,
specular_probe,
albedo_buffer);
albedo_buffer,
ssao_texture);
IBLShader::getInstance()->setUniforms();
}

Expand Down Expand Up @@ -434,14 +438,16 @@ void LightingPasses::renderLights( bool has_shadow,
GLuint depth_stencil_texture,
GLuint albedo_texture,
const FrameBuffer* shadow_framebuffer,
GLuint ssao_texture,
GLuint specular_probe)
{
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
renderEnvMap(normal_depth_texture,
depth_stencil_texture,
specular_probe,
albedo_texture);
albedo_texture,
ssao_texture);
}

// Render sunlight if and only if track supports shadow
Expand Down
4 changes: 3 additions & 1 deletion src/graphics/lighting_passes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class LightingPasses
void renderEnvMap(GLuint normal_depth_texture,
GLuint depth_stencil_texture,
GLuint specular_probe,
GLuint albedo_buffer);
GLuint albedo_buffer,
GLuint ssao_buffer);

/** Generate diffuse and specular map */
void renderSunlight(const core::vector3df &direction,
Expand All @@ -65,6 +66,7 @@ class LightingPasses
GLuint depth_stencil_texture,
GLuint albedo_texture,
const FrameBuffer* shadow_framebuffer,
GLuint ssao_texture,
GLuint specular_probe);
void renderLightsScatter(GLuint depth_stencil_texture,
const FrameBuffer& half1_framebuffer,
Expand Down
Loading

0 comments on commit 6db816e

Please sign in to comment.