Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add depth-of-field (Blurring rendering options) #1662

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 55 additions & 5 deletions avogadro/rendering/solid_first_fs.glsl
Expand Up @@ -25,6 +25,8 @@ uniform sampler2D inRGBTex;
uniform sampler2D inDepthTex;
// 1.0 if enabled, 0.0 if disabled
uniform float inAoEnabled;
// 1.0 if enabled, 0.0 if disabled
uniform float inDofEnabled;
// Shadow strength for SSAO
uniform float inAoStrength;
// 1.0 if enabled, 0.0 if disabled
Expand Down Expand Up @@ -66,6 +68,47 @@ float lerp(float a, float b, float f)
return a + f * (b - a);
}

float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233)) + cos(dot(co.xy, vec2(93.9898,50.233)))) * 43758.5453);
}
//more complex pattern produced which helps in reducing the noise. @ghutchis your insights ?


float depthToZ(float depth) {
float eyeZ = ((height * 0.57735) /2.0);
float near = 5.0;
float far = 600.0;
float depthNormalized = 2.0 * depth - 1.0;
return 2.0 * near * far / (far + near - depthNormalized * (far - near));
}

float calcBlur(float z, float pixelScale) {
return clamp(abs(z - 39.0), 0.0, 0.5*pixelScale);
}

vec4 applyBlur(vec2 texCoord) {
float pixelScale = max(width, height);
float origZ = depthToZ(texture2D(inDepthTex, texCoord).x);
float blurAmt = calcBlur(origZ, pixelScale);

float total = 1.0;
vec4 color = texture2D(inRGBTex, texCoord);
// number of samples can be optimized.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int numSamples = int(clamp(blurAmt * 64.0, 16.0, 64.0));
// dynamically reduce number of samples based on blur amount

for (int i = 0; i < numSamples; i++) {
// Remaining loop code of blur application...
}
@ghutchis your reviews for the changes proposed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review. I'll definitely make time to address the suggestions. However, regarding this issue, the loop index can't be compared with a non-constant expression. Therefore, adding numSamples to the for loop won't function since its value isn't constant. Could also leads to error. Are you sure about this one??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, and I appreciate your careful consideration. While GLSL 1.2 does support dynamic looping, the behavior can indeed vary based on the GPU and driver support. Sticking with your current approach to ensure compatibility and stability is wise. Thank you for pointing this out, @guthichs, and your reviews and help are greatly appreciated!

for (int i = 0; i < 64; i++) {
float t = (float(i) / float(64));
float angle = (t * 4.0) * 6.28319;
float radius = (t * 2. - 1.);
angle += 1.0 * rand(gl_FragCoord.xy);
vec2 offset = (vec2(cos(angle), sin(angle)) * radius * 0.05 * blurAmt) / pixelScale;
float z = depthToZ(texture2D(inDepthTex, texCoord + offset).x);
float sampleBlur = calcBlur(z, pixelScale);
float weight = float((z >= origZ) || (sampleBlur >= blurAmt * radius + 0.));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

float weight = 1.0 - smoothstep(0.0, 1.0, abs(z - origZ) / blurAmt);
// using smoothstep to soften weight transitions
This modification uses smoothstep to create a more gradual transition in weights applied to sampled colors, potentially reducing artifacts like banding. Reviews @ghutchis

// weight *= 1.0 / radius; // multiplying weight by inverse of sample distribution
vec4 sample = texture2D(inRGBTex, texCoord + offset);
color += weight * sample;
total += weight;
}
return color / total;
}

const vec2 SSAOkernel[16] = vec2[16](
vec2(0.072170, 0.081556),
vec2(-0.035126, 0.056701),
Expand Down Expand Up @@ -113,13 +156,20 @@ float computeEdgeLuminosity(vec3 normal)
return max(0.0, pow(normal.z - 0.1, 1.0 / 3.0));
}

void main()
{
void main() {
// Some cleanups required.
float luminosity = 1.0;
luminosity *= max(1.2 * (1.0 - inAoEnabled), computeSSAOLuminosity(getNormalNear(UV)));
luminosity *= max(1.0 - inEdStrength, computeEdgeLuminosity(getNormalAt(UV)));

vec4 color = texture2D(inRGBTex, UV);
gl_FragColor = vec4(color.xyz * luminosity, color.w);
if(inDofEnabled == 0.0){
gl_FragColor = vec4(color.xyz * luminosity, color.w);
}
else {
// Apply blur to the color texture
vec4 blurredColor = applyBlur(UV);
vec4 blurColor = vec4(luminosity * blurredColor.xyz, blurredColor.w);
gl_FragColor = blurColor;
}
gl_FragDepth = texture2D(inDepthTex, UV).x;
}
}
3 changes: 2 additions & 1 deletion avogadro/rendering/solidpipeline.cpp
Expand Up @@ -85,7 +85,7 @@ void initializeFramebuffer(GLuint* outFBO, GLuint* texRGB, GLuint* texDepth)
}

SolidPipeline::SolidPipeline()
: m_pixelRatio(1.0f), m_aoEnabled(true), m_aoStrength(1.0f),
: m_pixelRatio(1.0f), m_aoEnabled(true), m_dofEnabled(true), m_aoStrength(1.0f),
m_edEnabled(true), m_edStrength(1.0f), m_width(0), m_height(0),
d(new Private)
{
Expand Down Expand Up @@ -156,6 +156,7 @@ void SolidPipeline::end()
d->attachStage(d->firstStageShaders, "inRGBTex", d->renderTexture, "inDepthTex",
d->depthTexture, m_width, m_height);
d->firstStageShaders.setUniformValue("inAoEnabled", m_aoEnabled ? 1.0f : 0.0f);
d->firstStageShaders.setUniformValue("inDofEnabled", m_dofEnabled ? 1.0f : 0.0f);
d->firstStageShaders.setUniformValue("inAoStrength", m_aoStrength);
d->firstStageShaders.setUniformValue("inEdStrength", m_edStrength);
glDrawArrays(GL_TRIANGLES, 0, 6);
Expand Down
7 changes: 7 additions & 0 deletions avogadro/rendering/solidpipeline.h
Expand Up @@ -52,6 +52,12 @@ class SolidPipeline
bool getAoEnabled() { return m_aoEnabled; }
void setAoEnabled(bool enabled) { m_aoEnabled = enabled; }

/**
* @brief Get or set whether Depth-of-feild is enabled.
*/
bool getDofEnabled() { return m_dofEnabled; }
void setDofEnabled(bool enabled) { m_dofEnabled = enabled; }

/**
* @brief Get or set shadow strength for Ambient Occlusion.
*/
Expand All @@ -77,6 +83,7 @@ class SolidPipeline
private:
float m_pixelRatio;
bool m_aoEnabled;
bool m_dofEnabled;
float m_aoStrength;
bool m_edEnabled;
float m_edStrength;
Expand Down