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.

`ShaderMaterial` output Color Space behavior on main scene vs render target

See original GitHub issue

I’ve hit a confusing case where ShaderMaterial is behaving differently depending on if it was rendered in the main canvas or in a render target. The issue seems to be related to how color space is managed inside Threejs. I’ve consulted the Color Management’s section in the docs but couldn’t find information about how to handle output colors in a ShaderMaterial.

Here’s a link to reproduce the issue

https://jsfiddle.net/yelouafi/36h8eusp/57/

In the example we render 4 cubes, for that we prepare an input color that’s converted to linear space

  • The 2 on top are rendered into the main scene:

    • Top left is using a MeshBasicMaterial
    • Top right is using a ShaderMaterial
  • The 2 on the bottom are rendered inside a render target, the render target’s texture is then mapped on to a mesh

    • Bottom left is using a MeshBasicMaterial
    • Bottom right is using a ShaderMaterial

The basic material renders the same color in both situations, but the ShaderMaterial’s behavior is a little confusing. It seems to render different colors depending on where is was rendered (main scene or render target). Below is a screenshot of the result: Seems top one is rendering the wrong color

image

if you uncomment the line 74 // outputColor = LinearTosRGB(outputColor); in the material’s fragment shader the color is rendered correct on both the main scene and the render target.

Also seems render target’s encoding param doesn’t seem to have any impact on the outcome.

So my question are

  • how to handle color output in the ShaderMaterial’s fragment shader? should we always encode to sRGB or take into account the output encoding of the destination (a canvas or a render target)

  • In the case we’re rendering into a render target, should we take into account the render target’s encoding in the fragment shader: for example, if the render target’s enconding is linear, should the fragement shader output a linear color in this case?

  • One last question regarding the color supplied to renderer.setClearColor, the docs seems to suggest that all input colors should be converted to linear but in the case of setClearColor it seems the color needs to be sRGB, is this correct?

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:5

github_iconTop GitHub Comments

2reactions
Mugen87commented, May 30, 2022

But will the manual encode have an effect when I render the same shader code into a render target.

I suggest you do not directly use LinearTosRGB() but include the encodings_fragment shader chunk at the end of your fragment shader. When using ShaderMaterial, the renderer can inject the “correct” linearToOutputTexel() implementation. This should work for both rendering to screen or RTT.

2reactions
donmccurdycommented, May 30, 2022

I do feel like something is missing that could justify a GitHub issue thread being kept open here. The color management docs do not cover postprocessing, but should, and I’ve been hesitant to write that part up because the implementation in this repository seems to be out of date compared to alternatives like pmndrs/postprocessing. I’m not sure which implementation to recommend or document at this point, I’ve been using pmndrs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ShaderMaterial - Godot Docs
A material that uses a custom Shader program to render either items to screen or process particles. You can create multiple materials for...
Read more >
ShaderMaterial – three.js docs
A material rendered with custom shaders. A shader is a small program written in GLSL that runs on the GPU. You may want...
Read more >
Washed out color in ShaderMaterial - three.js - Stack Overflow
Rendering is done directly to the screen and not to a render-target. Here are relevant renderer settings: webGLRenderer.
Read more >
Albedo Color and Transparency - Unity - Manual
A Standard Shader material with default parameters and no values or textures assigned. The Albedo Color parameter is highlighted.
Read more >
pmndrs/drei: useful helpers for react-three-fiber - GitHub
The native route of the library does not export Html or Loader . ... You can use the PerspectiveCamera to film contents into...
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