question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New MeshStandardMaterial in r112 has banding artifacts on some GPUs

See original GitHub issue

As of r112 the default MeshStandardMaterial (in this case specifically as it’s used when loading glTF files, but probably in other scenarios as well) is exhibiting banding artifacts on some GPUs. Specifically, I have see this issue on a Pixelbook and every generation of Pixel phones. The issue does not occur on the Nvidia desktop GPUs I have tried, nor on an Oculus Go or Oculus Quest.

It should also be noted that I’ve observed the material’s new shader incurred a noticable performance hit relative to r111 for my particular application on various mobile devices, including ones that don’t exhibit the rendering artifacts.

The artifacts look like this (Rendered with Three.js r112 on a Pixelbook)

Screenshot 2019-12-29 at 9 15 19 PM

The expected output looks like this (Rendered with Three.js r111 on the same Pixelbook)

Screenshot 2019-12-29 at 9 24 31 PM

Live link, currently using r112: https://xrdinosaurs.com

All of the dinosaurs on that page exhibit the issue, but ones with large areas of flat or smooth colors (like the TRex’s belly) tend to stand out more.

The material in the screenshot (pasted in full below) uses the glTF extension “KHR_materials_pbrSpecularGlossiness”, and has a diffuse, normal, and specular/glossiness textures.

    {
      "doubleSided": true,
      "emissiveFactor": [
        0,
        0,
        0
      ],
      "extensions": {
        "KHR_materials_pbrSpecularGlossiness": {
          "diffuseFactor": [
            0.46512957319999998,
            0.46512957319999998,
            0.46512957319999998,
            1
          ],
          "diffuseTexture": {
            "index": 4,
            "texCoord": 0
          },
          "glossinessFactor": 0.27610518290000002,
          "specularFactor": [
            0.92244664629999995,
            0.92244664629999995,
            0.92244664629999995
          ],
          "specularGlossinessTexture": {
            "index": 6,
            "texCoord": 0
          }
        }
      },
      "name": "TRex",
      "normalTexture": {
        "index": 5,
        "scale": 1,
        "texCoord": 0
      }
    }

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:18 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
sciecodecommented, Jan 7, 2020

@elalish after running some tests on multiple examples, I was able to pinpoint the actual cause of these artifacts. Contrary to what I said on my previous post, the root cause of the problem is not related with incorrect coordinates sampling, but with the way PMREMGenerator is handling devicePixelRatio.

On devices with nominal floating point pixelRatio we are getting “bad” mipmap coordinates on the generated texture. So there are small gaps and overlapping regions. I also discovered that my machine has different devicePixelRatios depending if I’m viewing the example locally (0.899…) or online (1) and that’s why I was only experiencing these artifacts locally.

I’ve setup a simple test by disabling setPixelRatio and it seems to solve the problem, if that’s the case for others, then it would be best to refactor the way PMREMGenerator is handling it.

@toji @plut0nist mind checking the following examples on the devices that presented these artifacts?

DEV Example TEST Example

2reactions
tojicommented, Jan 7, 2020

@sciecode: Verified on my devices. The DEV Example test exhibits a very obvious black line in the environment map while the TEST Example does not. Awesome debugging, thanks!

I’m was extremely curious why PMREMGenerator needed to account for devicePixelRatio at all, so I went digging. It turns out it’s because renderer.setViewport() automatically factors the DPR into any values you send it, which feels like it’s clearly the wrong behavior for render targets other than the default framebuffer, which are allocated with exact pixel values that don’t account for the pixel ratio at all. I’d suggest the “right” behavior here is that internally rendere.setViewport() should be using getTargetPixelRatio(), which returns 1 when the active render target is anything other than the default. I can definitely see how that could introduce backwards compat issues, though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

MeshStandardMaterial – three.js docs
A standard physically based material, using Metallic-Roughness workflow. Physically based rendering (PBR) has recently become the standard in many 3D ...
Read more >
Can you FIX a Graphics card that puts LINES on ... - YouTube
Another instalment of CAN YES FIX IT, where you guys send in your broken parts and I attempt to do my best via...
Read more >
Is your graphics card dead? Signs your gpu is dying (updated)
If you're experience monitor disruption of any kind and unsure if it is a graphics card issue then you need to watch this...
Read more >
How to determine what is causing visual artifacts
So I recently built my first gaming PC just over a month ago after some extensive research online. Everything has been running smoothly...
Read more >
What Is a GPU? Graphics Processing Units Defined - Intel
Graphics processing technology has evolved to deliver unique benefits in the world of computing. The latest graphics processing units (GPUs) unlock new ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found