Skip to content

Fix bloom artifacts appearing due to bad specular data #7605

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

Merged
merged 1 commit into from
Apr 28, 2025

Conversation

Christopher-Hayes
Copy link
Contributor

@Christopher-Hayes Christopher-Hayes commented Apr 25, 2025

Description

Fixes black square artifacts appearing on screen when the Bloom or Dof effects were used with the CameraFrame script. This bug was only reproduced on Ubuntu with an nvidia GPU.

image

Solution

This patch adds a clamp to the fresnelSchlick.js functions, getFresnel() and getFresnelCC(), to avoid bad specular values.

Explanation

I still don't think I'm 100% sure why it was happening, but from what I can tell:

  1. When the angle of light and the camera were exactly parallel it would cause this dot product calculation to be -1.
    dReflection.rgb *= getFresnel(
    dot(dViewDirW, litArgs_worldNormal),
    litArgs_gloss,
    litArgs_specularity
    #if defined(LIT_IRIDESCENCE)
    , iridescenceFresnel,
    litArgs_iridescence_intensity
    #endif
    );
  2. With the current implementation, a cosTheta of -1 should not break anything. max() would set it to 0.0 and the function should work okay.
    export default /* glsl */`
    // Schlick's approximation
    vec3 getFresnel(
    float cosTheta,
    float gloss,
    vec3 specularity
    #if defined(LIT_IRIDESCENCE)
    , vec3 iridescenceFresnel,
    float iridescenceIntensity
    #endif
    ) {
    float fresnel = pow(1.0 - max(cosTheta, 0.0), 5.0);
    float glossSq = gloss * gloss;
    vec3 ret = specularity + (max(vec3(glossSq), specularity) - specularity) * fresnel;
    #if defined(LIT_IRIDESCENCE)
    return mix(ret, iridescenceFresnel, iridescenceIntensity);
    #else
    return ret;
    #endif
    }
  3. But, for whatever reason on certain devices it was causing getFresnel() to return a bad specular value.
  4. This seems limited to only a pixel or two, but bloom upscaling makes these artifacts a lot more noticeable.

Before vs After

(Note that the flashing is more visible in-person, the low-FPS recording hides it somewhat)

Screencast.From.2025-04-25.03-26-28.mp4

Testing

Project for testing: https://playcanvas.com/editor/scene/2210459

Fixes #7492

I confirm I have read the contributing guidelines and signed the Contributor License Agreement.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

A patch to fix bloom artifacts by clamping specular values in shader functions.

  • Modified getFresnel() to use clamp instead of max for cosTheta
  • Modified getFresnelCC() in a similar fashion to ensure values remain within [0, 1]

@willeastcott willeastcott added bug area: graphics Graphics related issue labels Apr 25, 2025
Copy link
Contributor

@mvaligursky mvaligursky left a comment

Choose a reason for hiding this comment

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

Looks great, thanks!

@mvaligursky mvaligursky merged commit f162339 into playcanvas:main Apr 28, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Black square artifacts when using CameraFrame Bloom or DoF Post-Processing
3 participants