[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] The Newly Expanded Color Space Issue



On Tue, Sep 7, 2010 at 7:19 PM, Steve Baker <steve@sjbaker.org> wrote:
> 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:

OK, as I indicated before, 50% perceptual blend and 50% physical blend
are two different things, so the question is malformed.  But I think I
know what you mean, so I can rephrase the question and give an answer.

I'm going to rephrase your question as, "how would you generate 50%
physical light intensity via an sRGB framebuffer by blending black and
white using a factor of 0.5?"

Here we go:

var black = vec3(0, 0, 0);
var white = vec3(1, 1, 1);
var linear_result = mix(black, white, 0.5);
var srgb_result = pow(blend_linear, 1 / 2.2);
// srgb_result ~= 0.73, ...

-T

>
>
> QUESTION 1:
>
>    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.
>
> QUESTION 2:
>
>    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?

glEnable(GL_FRAMEBUFFER_SRGB_EXT);
// Then draw your poly.

> QUESTION 3:
>
>    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?

See this diagram; ramp is done in both sRGB (perceptually linear) and
Linear (physically linear).

http://tulrich.com/webgl/rgb/luminance_perception.html

(View Source if you want to see the code.)

> I await your replies with great excitement.

I await your interpretation of this exercise with great excitement.

-T

-----------------------------------------------------------
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: