pex-gl / pex-renderer

Physically based renderer (PBR) and scene graph for PEX.
https://pex-gl.github.io/pex-renderer/examples/index.html
MIT License
235 stars 16 forks source link

Linear material colors #36

Open vorg opened 6 years ago

vorg commented 6 years ago

Compare with gltf as I think we have gamma colors and gltf has linear https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material

vorg commented 5 years ago

Discussion in AFrame repo https://github.com/aframevr/aframe/pull/3757

vorg commented 5 years ago

ThreeJS has this still unsolved as of March 2019

Editor: all colors/textures washed out in r102

I'd like to see this eventually be implicitly part of THREE.Color, perhaps with some colorManagement flag to disable it. When the user provides a hex code, it's implicitly sRGB, whereas fromArray() etc. would implicitly be linear.

Suggestion: add a bufferAttribute.convertGammaToLinear method

Adding convertSRGBToLinear utility for vertex color

We Need to Properly Handle Gamma Correction

THREE.Color: added sRGB conversion methods

vorg commented 5 years ago

Babylon js has useScalarInLinearSpace but can't find any docs on it.

vorg commented 5 years ago

Current thinking.

Assume float rgba array colors [r, g, b, a] are linear. Assume html hex colors #FFDD33 are gamma Assume byte 0.255 rgba array colors [rByte, gByte, bByte, aByte] from gui and are gamma (?)

Add gamma correction to pex-color.fromHex and pex-color.fromRGBBytes

What about vertex colors?

vorg commented 5 years ago

Filament is most clear in the docs 👍

baseColor - Pre-multiplied linear RGB

About linear RGB

Several material model properties expect RGB colors. Filament materials use RGB colors in linear space and you must take proper care of supplying colors in that space. See the Linear colors section for more information.

About pre-multiplied RGB

Filament materials expect colors to use pre-multiplied alpha. See the Pre-multiplied alpha section for more information.

vorg commented 5 years ago

What about vertex colors?

They should be linear https://github.com/KhronosGroup/glTF/issues/1638

vorg commented 5 years ago
color.fromHEX("#FF000") -> [1, 0, 0, 1]
color.toLinear(color.fromBytes([255, 0, 0])) -> [1, 0, 0, 1]

var red = color.fromBytes([255, 0, 0])
var red = [r / 255, g / 255, b / 255, 1] // floating point sRGB/gamma color

var linearRed = color.toLinear(red)
var linearishRed = [
   Math.pow(r / 255, 2.2),
   Math.pow(r / 255, 2.2),
   Math.pow(r / 255, 2.2),
   1
] // floating point sRGB/gamma color

var linearColorValue = [0, 0, 0, 0]
var colorValueLinear = [0, 0, 0, 0]
ctx.submit(myCommand, {
   uniforms: {
     uColor: color.convertToLinear(color.set(linearColorValue, colorIn.value)),
     uColor: color.fromGamma(linearColorValue),
     uColor: color.fromGammaToLinear(linearColorValue, colorIn.value),
     uColor: color.fromLinear(linearColorValue, colorIn.value)

      uColor: color.toLinear(colorIn.value),
      uColor: color.toLinear(colorIn.value, linearColorValue)
   }
})

color.getHex(color.toLinear(colorIn.value))

Can we assume all colors coming out of this library are linear? That would require 2.0 rewrite.

vorg commented 5 years ago

Alternatively we simply add color.toLinear(oldSRGBColor, newLinearColor) and you keep track of the color space via variable name.

vorg commented 1 year ago

EXT_sRGB is included in core in WebGL2 which allows you to autoconver all srgb textures before sampling and no more toLinear calling is needed. So changing all uniform colors to linear would make all our code linear.

Downsides: user need to do it's own bookkeeping to know which color is and which one isn't linear.

dmnsgn commented 7 months ago

EXT_sRGB would be WebGL2 only, as there are issues with mipmap generation in WebGL 1: https://github.com/mrdoob/three.js/issues/22483

PS: WebGPU has -srgb suffix

vorg commented 7 months ago

Another reason to deprecate WebGL1 in v4