For example, this part in ColorBurn:

std::min (1.0f, (1 - b/ba)*(aa/a))

where 'a' and 'b' are color values, 'aa' and 'ba' are alphas.

There are two divisions to handle. If a==0, that is handled
as different case. I am left to deal with ba==0.

If ba==0 then (1 - b/ba)*(aa/a) == NAN, and
std::min (1.0f, NAN) = 1. So there is no error, min saves the day
here, but 1 is definitely not what we want.

This is the whole formula for ColorBurn + Over:

return a*(1-ba) + b*(1-aa) +
           aa*ba * (1 - std::min (1.0f, (1 - b/ba)*(aa/a)));

The problem is I can't simplify this as we did Screen. Even
the SVG specification has it this way. If that std::min was not
there I could have simplified this. We can't simply throw away the
min though, since it catches bad values, and if we let go such a bad value
it will mess up the entire result.

The only thing I can think of is, when ba==0 treat it as a very small value
like 0.00000001, so we get:

(1 - b / ba) * (aa / a) =
(1 - b / 'very small positive value') * (aa / a) =
(1 - 'very big positive value') * (aa / a) =
'very big negative value' * (aa / a) =
'very big negative value'

and then we "clamp" that to 0. And now we have:

std::min (1.0f, 0.0f) = 0.0f and the operation can move on from there.
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to