Open vorg opened 6 years ago
Discussion in AFrame repo https://github.com/aframevr/aframe/pull/3757
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
Babylon js has useScalarInLinearSpace but can't find any docs on it.
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?
Filament is most clear in the docs 👍
baseColor
- Pre-multiplied 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.
Filament materials expect colors to use pre-multiplied alpha. See the Pre-multiplied alpha section for more information.
What about vertex colors?
They should be linear https://github.com/KhronosGroup/glTF/issues/1638
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.
Alternatively we simply add color.toLinear(oldSRGBColor, newLinearColor)
and you keep track of the color space via variable name.
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.
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
Another reason to deprecate WebGL1 in v4
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