KhronosGroup / WebGL

The Official Khronos WebGL Repository
Other
2.63k stars 668 forks source link

Clarify UNPACK_PREMULTIPLY_ALPHA for floating-point and integer pixel formats #3667

Open lexaknyazev opened 1 month ago

lexaknyazev commented 1 month ago

The UNPACK_PREMULTIPLY_ALPHA_WEBGL parameter is defined in WebGL 1.0 spec that on its own supports only unsigned normalized pixel formats.

The WebGL 2.0 and the related WebGL extension specs should define how this parameter works with:

kdashg commented 1 month ago

I believe we should specifiy that:

lexaknyazev commented 1 month ago

ieee math happens

Inf and NaN included?

Int formats: clamping happens

Normalized (incl signed) formats: clamping happens

Since the values are normalized, multiplication results cannot be outside of [0, 1] or [-1, +1] ranges. The only tricky edge case is that -128 and -32768 must be treated as -127 and -32767 for the purposes of normalization.

kenrussell commented 2 weeks ago

Notes from the WebGL concall:

Inf and NaN included?

Thinking: we do whatever the CPU hardware does.

Int formats: clamping happens

Let's say that the integer math's done with 32 bits of precision and then clamp back to the 8-bit range. Or, say that clamping isn't better than masking? Not sure what's better.

Meta-question, should we be premultiplying integer values at all? Consider ignoring the state for these non-normalized integer textures.

More discussion to come.

kdashg commented 6 days ago

I wish we had never applied this setting to ArrayBufferView data. It really only makes sense for images, where you're trying to ensure consistency. This should be viewed like unpackColorSpace, where it sets the destination alpha premultiplication state when we call e.g. texImage(img). Different sources have different alpha premult states: Canvases are generally alpha-premult:true, whereas PNG is stored alpha-premult:false. Setting UNPACK_PREMULTIPLY_ALPHA:true means that for canvases, we do no alpha-premult-conversion, whereas for PNG, we multiply color by alpha before the color conversions step. Likewise for UNPACK_PREMULTIPLY_ALPHA:false, we have to "unpremultiply" by dividing color by alpha in order to make the data alpha-premult:false, whereas for PNG, we do not change the data. It's important to view these as the destination setters, rather than operations. (This also applies to the y-flip setting)

I believe Firefox warns if you use these things (such as flip-y) on ArrayBufferView data.

kdashg commented 6 days ago

In WG, we decided that we would try to spec UNPACK_PREMULTIPLY_ALPHA as ignored for non-TexImageSources (thus excluding ArrayBufferViews). Next step is writing a test to go with the spec change, and seeing if that breaks any implementations.