From 1da2b3558e5dbf788fa144064e268f1d39df8e59 Mon Sep 17 00:00:00 2001 From: NULL511 Date: Mon, 4 Sep 2023 03:09:25 -0400 Subject: [PATCH] add sample count --- .../config/client/IDhApiGraphicsConfig.java | 2 ++ .../config/client/DhApiGraphicsConfig.java | 4 +++ .../distanthorizons/core/config/Config.java | 5 ++++ .../render/renderer/shaders/SSAORenderer.java | 6 ++++- .../assets/distanthorizons/lang/en_us.json | 6 +++-- core/src/main/resources/shaders/ssao/ao.frag | 26 +++++++++---------- .../main/resources/shaders/ssao/apply.frag | 21 +++++++-------- 7 files changed, 43 insertions(+), 27 deletions(-) diff --git a/api/src/main/java/com/seibel/distanthorizons/api/interfaces/config/client/IDhApiGraphicsConfig.java b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/config/client/IDhApiGraphicsConfig.java index ea8478856..b5bfce8f0 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/interfaces/config/client/IDhApiGraphicsConfig.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/config/client/IDhApiGraphicsConfig.java @@ -96,6 +96,8 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup IDhApiConfigValue ambientOcclusion_MinLight(); + IDhApiConfigValue ambientOcclusion_BlurRadius(); + IDhApiConfigValue transparency(); /** Defines what blocks won't be rendered as LODs. */ diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java index 55dfa5758..478645a28 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java @@ -104,6 +104,10 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig public IDhApiConfigValue ambientOcclusion_MinLight() { return new DhApiConfigValue(Config.Client.Advanced.Graphics.Quality.ssaoMinLight); } + @Override + public IDhApiConfigValue ambientOcclusion_BlurRadius() + { return new DhApiConfigValue(Config.Client.Advanced.Graphics.Quality.ssaoBlurRadius); } + @Override public IDhApiConfigValue transparency() { return new DhApiConfigValue(Config.Client.Advanced.Graphics.Quality.transparency); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index 3ee3ff8b1..e74e4900d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -204,6 +204,11 @@ public class Config .comment("Minimum brightness of Screen Space Ambient Occlusion effect") .build(); + public static ConfigEntry ssaoBlurRadius = new ConfigEntry.Builder() + .set(2) + .comment("Radius in pixels of Screen Space Ambient Occlusion blurring") + .build(); + public static ConfigEntry horizontalQuality = new ConfigEntry.Builder() .set(EHorizontalQuality.MEDIUM) .comment("" diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java index bd6ad3988..fcd01ecab 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAORenderer.java @@ -55,8 +55,8 @@ public class SSAORenderer public int gSampleCountUniform; public int gRadiusUniform; public int gStrengthUniform; - public int gBiasUniform; public int gMinLightUniform; + public int gBiasUniform; public int gDepthMapUniform; } @@ -67,6 +67,7 @@ public class SSAORenderer public int gSSAOMapUniform; public int gDepthMapUniform; public int gViewSizeUniform; + public int gBlurRadiusUniform; public int gNearUniform; public int gFarUniform; } @@ -109,6 +110,7 @@ public class SSAORenderer this.applyShaderUniforms.gSSAOMapUniform = this.applyShader.getUniformLocation("gSSAOMap"); this.applyShaderUniforms.gDepthMapUniform = this.applyShader.getUniformLocation("gDepthMap"); this.applyShaderUniforms.gViewSizeUniform = tryGetUniformLocation(this.applyShader, "gViewSize"); + this.applyShaderUniforms.gBlurRadiusUniform = tryGetUniformLocation(this.applyShader, "gBlurRadius"); this.applyShaderUniforms.gNearUniform = tryGetUniformLocation(this.applyShader, "gNear"); this.applyShaderUniforms.gFarUniform = tryGetUniformLocation(this.applyShader, "gFar"); @@ -192,6 +194,7 @@ public class SSAORenderer invertedPerspective.invert(); int sampleCount = Config.Client.Advanced.Graphics.Quality.ssaoSampleCount.get(); + int blurRadius = Config.Client.Advanced.Graphics.Quality.ssaoBlurRadius.get(); float radius = Config.Client.Advanced.Graphics.Quality.ssaoRadius.get().floatValue(); float strength = Config.Client.Advanced.Graphics.Quality.ssaoStrength.get().floatValue(); float minLight = Config.Client.Advanced.Graphics.Quality.ssaoMinLight.get().floatValue(); @@ -229,6 +232,7 @@ public class SSAORenderer GL32.glActiveTexture(GL32.GL_TEXTURE1); GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId()); GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 1); + GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius); if (this.applyShaderUniforms.gViewSizeUniform >= 0) GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height); diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json index 526ecdf8e..0cade8c24 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -96,6 +96,8 @@ "How quickly LODs drop off in quality.\n\nLarger numbers will improve how distant terrain looks\nbut will increase memory and GPU usage.", "distanthorizons.config.client.advanced.graphics.quality.ssao": "SSAO", + "distanthorizons.config.client.advanced.graphics.quality.ssao.@tooltip": + "Screen Space Ambient Occlusion adds depth to the lighting of blocks.", "distanthorizons.config.client.advanced.graphics.quality.ssaoSampleCount": "SSAO Sample Count", "distanthorizons.config.client.advanced.graphics.quality.ssaoRadius": @@ -106,8 +108,8 @@ "SSAO Min Light", "distanthorizons.config.client.advanced.graphics.quality.ssaoBias": "SSAO Bias", - "distanthorizons.config.client.advanced.graphics.quality.ssao.@tooltip": - "Screen Space Ambient Occlusion adds depth to the lighting of blocks.", + "distanthorizons.config.client.advanced.graphics.quality.ssaoBlurRadius": + "SSAO Blur Radius", "distanthorizons.config.client.advanced.graphics.quality.horizontalQuality": "Horizontal Quality", "distanthorizons.config.client.advanced.graphics.quality.horizontalQuality.@tooltip": diff --git a/core/src/main/resources/shaders/ssao/ao.frag b/core/src/main/resources/shaders/ssao/ao.frag index 94901abba..149736efb 100644 --- a/core/src/main/resources/shaders/ssao/ao.frag +++ b/core/src/main/resources/shaders/ssao/ao.frag @@ -1,8 +1,9 @@ #version 150 core #extension GL_ARB_derivative_control : enable +#define SAMPLE_MAX 64 + #define saturate(x) (clamp((x), 0.0, 1.0)) -#define rcp(x) (1.0 / (x)) in vec2 TexCoord; @@ -40,28 +41,26 @@ vec3 calcViewPosition(const in vec3 clipPos) { float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 viewNormal) { - float inv = rcp(gSampleCount); - float rStep = inv * gRadius; - float dither = InterleavedGradientNoise(gl_FragCoord.xy); float rotatePhase = dither * TAU; + float rStep = gRadius / gSampleCount; - float radius = rStep; vec2 offset; float ao = 0.0; int sampleCount = 0; - for (int i = 0; i < gSampleCount; i++) { - offset.x = sin(rotatePhase); - offset.y = cos(rotatePhase); - offset *= radius; + float radius = rStep; + for (int i = 0; i < clamp(gSampleCount, 1, SAMPLE_MAX); i++) { + vec2 offset = vec2( + sin(rotatePhase), + cos(rotatePhase) + ) * radius; + radius += rStep; - rotatePhase += GOLDEN_ANGLE; vec3 sampleViewPos = viewPos + vec3(offset, -0.1); vec3 sampleClipPos = unproject(gProj * vec4(sampleViewPos, 1.0)) * 0.5 + 0.5; - //if (sampleClipPos != saturate(sampleClipPos)) continue; sampleClipPos = saturate(sampleClipPos); float sampleClipDepth = textureLod(gDepthMap, sampleClipPos.xy, 0.0).r; @@ -77,8 +76,7 @@ float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 float sampleNoLm = max(dot(viewNormal, sampleNormal) - gBias, 0.0); float aoF = 1.0 - saturate(sampleDist / gRadius); ao += sampleNoLm * aoF; - - sampleCount += 1; + sampleCount++; } ao /= max(sampleCount, 1); @@ -92,10 +90,12 @@ void main() { float fragmentDepth = textureLod(gDepthMap, TexCoord, 0).r; float occlusion = 0.0; + // Do not apply to sky if (fragmentDepth < 1.0) { vec3 viewPos = calcViewPosition(vec3(TexCoord, fragmentDepth)); #ifdef GL_ARB_derivative_control + // Get higher precision derivatives when available vec3 viewNormal = cross(dFdxFine(viewPos.xyz), dFdyFine(viewPos.xyz)); #else vec3 viewNormal = cross(dFdx(viewPos.xyz), dFdy(viewPos.xyz)); diff --git a/core/src/main/resources/shaders/ssao/apply.frag b/core/src/main/resources/shaders/ssao/apply.frag index f91e787b2..44026c96c 100644 --- a/core/src/main/resources/shaders/ssao/apply.frag +++ b/core/src/main/resources/shaders/ssao/apply.frag @@ -1,7 +1,5 @@ #version 150 core -#define ENABLE_SSAO_BLUR - in vec2 TexCoord; out vec4 fragColor; @@ -9,6 +7,7 @@ out vec4 fragColor; uniform sampler2D gSSAOMap; uniform sampler2D gDepthMap; uniform vec2 gViewSize; +uniform int gBlurRadius; uniform float gNear; uniform float gFar; @@ -25,20 +24,19 @@ float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, float g_sigmaX = 1.6; float g_sigmaY = 1.6; - const float c_halfSamplesX = 2.0; - const float c_halfSamplesY = 2.0; + int radius = clamp(gBlurRadius, 1, 3); vec2 pixelSize = 1.0 / gViewSize; float accum = 0.0; float total = 0.0; - for (float iy = -c_halfSamplesY; iy <= c_halfSamplesY; iy++) { + for (int iy = -radius; iy <= radius; iy++) { float fy = Gaussian(g_sigmaY, iy); - for (float ix = -c_halfSamplesX; ix <= c_halfSamplesX; ix++) { + for (int ix = -radius; ix <= radius; ix++) { float fx = Gaussian(g_sigmaX, ix); - vec2 sampleTex = texcoord + vec2(ix, iy) * pixelSize; + vec2 sampleTex = texcoord + ivec2(ix, iy) * pixelSize; float sampleValue = textureLod(gSSAOMap, sampleTex, 0).r; float sampleDepth = textureLod(gDepthMap, sampleTex, 0).r; float sampleLinearDepth = linearizeDepth(sampleDepth); @@ -66,11 +64,12 @@ void main() // a fragment depth of "1" means the fragment wasn't drawn to, // we only want to apply SSAO to LODs, not to the sky outside the LODs if (fragmentDepth < 1) { - #ifdef ENABLE_SSAO_BLUR + if (gBlurRadius > 0) { float fragmentDepthLinear = linearizeDepth(fragmentDepth); fragColor.a = BilateralGaussianBlur(TexCoord, fragmentDepthLinear, 1.6); - #else - fragColor.a = textureLod(gSSAOMap, TexCoord, 0).r; - #endif + } + else { + fragColor.a = texelFetch(gSSAOMap, ivec2(gl_FragCoord.xy), 0).r; + } } }