Open lexaknyazev opened 3 months ago
I believe we should specifiy that:
ieee math happens
Inf and NaN included?
Int formats: clamping happens
sint8
: (-128, 0, 0, -1) => (+127, 0, 0, -1)?sint8
: (-128, 0, 0, +2) => (-128, 0, 0, +2)?uint8
: (127, 0, 0, 127) => (127, 0, 0, 127)?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.
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.
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.
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.
Additional information from WebGL WG meeting of 2024-09-19:
One remaining problem is uploading canvases to RGBA8UI textures with premultiplied alpha: https://registry.khronos.org/webgl/specs/latest/2.0/#3.7.6 . That's the only problematic format in the table. The WG resolved to test this, and if browsers behave differently, carve it out from the rest of the spec update.
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:
RGBA
andLUMINANCE_ALPHA
formats withFLOAT
andHALF_FLOAT
types. Specifically, how floating-point overflow/underflow is handled.RGBA_INTEGER
format. Specifically, how signed/unsigned integer overflow is handled.RGBA
format withBYTE
andSHORT
(fromEXT_texture_norm16
) types.