[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Public WebGL] The Newly Expanded Color Space Issue
I think we have to take this one teeny-tiny step at a time. First, let
us establish once and for all what color space GLSL shaders operate in.
Those of us who think that the color space of WebGL shaders can be
anything other than linear...please convince me that you are right by
clearly answering the following three blindingly simple and eminently
If you are right, then the answers should be easy, clear, intuitive and
(above all) correct.
Suppose I want a 50% blend between two images, or to make it
super-simple: a 50% blend between a black texel and a white texel.
That's a good choice of example since (0,0,0) and (1,1,1) are black
and white, respectively, in both linear and sRGB space - so we don't
have to concern ourselves with the thorny question of what the input
texture color space is. Here are three ways I could get 50/50
blend of two colors:
In a linear space GLSL, I could write:
x.rgb = mix ( vec3(0,0,0), vec3(1,1,1), 0.5 ) ;
(Just to save you looking it up, the OrangeBook says that mix(x,y,a)
returns "(x*(1-a)+y*a), ie the linear blend of x and y" - those are
the exact words at the very top of page 124 of my early edition -
and that is what every single GPU on the entire planet actually does).
In my world, x.rgb will be (0.5,0.5,0.5) - which (with what I'm
proposing) will automatically become pow(vec3(0.5,0.5,0.5),1.0/2.2)
when it's composited into the frame buffer to produce the
perceptually (and mathematically) correct result: (0.73,0.73,0.73).
Here is the question: How do you get a perceptually correct 50% mix
of any two colors in your sRGB-space shader such that a 50/50 blend
of black and white produces (0.73,0.73,0.73) in the final composited
image? Please answer in the form of actual GLSL code.
If I now wish to produce the same 50% mix result by alpha-blending a
(white) RGBA polygon onto a (black) background.
In linear space I'll be using *gl.blendFunc ( gl.SRC_ALPHA,
gl.ONE_MINUS_SRC_ALPHA )* and a 50% alpha value, and again, the
result (after compositing) should be (0.73,0.73,0.73) - which is
again, perceptually and mathematically correct.
What code (blend modes, shader code, etc) would I have to use in
sRGB-space to get the same result on-screen?
If I make a 200 pixel x 200 pixel quadrilateral (on-screen) and in
the vertex shader, I assign the two leftmost vertices the per-vertex
color (0,0,0) and the two rightmost the color (1,1,1). The final
color of the pixel in the center of the polygon (after compositing,
etc) should be the perceptually correct value (0.73,0.73,0.73).
In linear space, that's what I get if the fragment shader simply
passes the interpolated color to the output with no additional
processing - the interpolation across the polygon produces
(0.5,0.5,0.5) in the middle and the compositing gamma correction
turns that into (0.73,0.73,0.73).
How does this work in your sRGB color space world? If the answer
isn't (0.73,0.73,0.73) then how do you propose I fix it so that
simple per-vertex lighting will work correctly? Bonus: What should
dFdx(color) return at the center pixel of the polygon?
I await your replies with great excitement.
You are currently subscribed to firstname.lastname@example.org.
To unsubscribe, send an email to email@example.com with
the following command in the body of your email: