[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
practical questions.

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.

   -- Steve

You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: