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

Re: [Public WebGL] Gamma correction and texImage2D/texSubImage2D

On Fri, Sep 3, 2010 at 11:39 AM,  <steve@sjbaker.org> wrote:
>> El 3 de septiembre de 2010 08:47, Chris Marrin <cmarrin@apple.com>
>> escribió:
>>> I think it would be useful to have the unlit case behave the same as
>>> rendering to a 2D canvas, which would gamma correct. I believe the
>>> differences in the lit case would be subtle and it's only if authors are
>>> trying to be very precise that they will care. In that case, they can
>>> turn it off. But my opinion on this is not strong.
>> I agree that the unlit case should ideally behave the same as
>> rendering to a 2D canvas. However, as Steve points out, this would be
>> much better implemented as a context creation attribute that the
>> compositor could respect.  It could default to having gamma correction
>> turned on.
>> Additionally, if you need a packing flag for texture loads, I think
>> the most useful operation is the opposite of the one proposed--to
>> transform non-linear input textures into the appropriate linear space
>> for lighting.  Using non-linear textures as storage and input arguably
>> gives you more color resolution in the dark part of the spectrum, so
>> it might be useful to support that.  D3DSAMP_SRGBTEXTURE is an example
>> of this sort of texture load flag.
>> -enne
> Yes - the reverse operation (to turn a pre-gamma-corrected image into a
> linear color space texture) is much more useful - especially in an
> environment where JPEG images are common and we might wish to take as
> input other things that the browser has generated that might already be
> gamma corrected.
> At first sight, fixing pre-gamma'd images back to linear seems do-able in
> the shader.
> (Since the gamma operation is  Vout=pow(Vin,1.0/2.2) - the inverse of that
> is Vin = pow(Vout,2.2)...which you can approximate as pow(Vout,2.0) -
> which is Vin=Vout*Vout).
> However, you can only do that after texture-lookup - and because that
> entails a bunch of linear interpolations, you shouldn't really be doing
> that in gamma-space.  So there is certainly justification for reversing
> the gamma correction as the texture is loaded.  Moreover, many image file
> formats actually tell you what gamma they were stored with - so the loader
> could do a really excellent job by honoring that number.

Based on your above descriptions and the above discussion I'm well
convinced that the default behavior should not be to apply gamma
correction to images uploaded via tex{Sub}Image2D. I don't yet
understand what we'll need to do in order to support this though.

For RGB(A) PNGs, is the desired behavior to simply pass through the
pixel values in the file without regard to any gamma information in
the file or the screen gamma? Or is the conversion to a linear color
space more complex?

I don't know where all of the places are in WebKit code which may end
up modifying pixel values during image loading. Here's the code from
WebKit's PNGImageDecoder.cpp that sets up the gamma in the PNG reader.

    // Gamma constants.
    const double cMaxGamma = 21474.83;
    const double cDefaultGamma = 2.2;
    const double cInverseGamma = 0.45455;
    // Deal with gamma and keep it under our control.
    double gamma;
    if (png_get_gAMA(png, info, &gamma)) {
        if ((gamma <= 0.0) || (gamma > cMaxGamma)) {
            gamma = cInverseGamma;
            png_set_gAMA(png, info, gamma);
        png_set_gamma(png, cDefaultGamma, gamma);
    } else
        png_set_gamma(png, cDefaultGamma, cInverseGamma);

If we want to pass through the data unmodified, would we want to call
png_set_gamma(png, 1.0, 1.0)? Similarly, to convert to linear space,
would we want to pass 1.0 instead of cDefaultGamma?

I see nothing in the JPEGImageDecoder related to gamma. Is anything
needed for this file format? I suspect people will not use JPEGs for
anything they expect to be passed through verbatim to WebGL, such as
encoding non-color information in the color channels of a texture.

Do we need three values for this pixel storage attribute (pass through
data verbatim, convert to linear space, and perform gamma correction)?

Similarly, it sounds like we need another context creation attribute
to optionally gamma correct WebGL's rendering results before placing
them on the page?


P.S. Steve, your earlier email is my favorite ever.

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: