tag:blogger.com,1999:blog-5181746871086541575.post7155019960351174201..comments2023-05-16T08:22:45.753+00:00Comments on chilliant: sRGB Approximations for HLSLIan Taylorhttp://www.blogger.com/profile/06869762490434824010noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-5181746871086541575.post-16352089852768723472023-01-08T14:57:12.624+00:002023-01-08T14:57:12.624+00:00I can't speak for its accuracy at every range,...I can't speak for its accuracy at every range, but can confirm that it does a nearly perfect job converting normals. I can't see any difference when comparing a screen shot to the original normals texture in Photoshop, which is pretty amazing. Thanks a lot for these useful tools!Coil Ninjahttps://www.blogger.com/profile/08977705803658258222noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-90815679694736784142023-01-08T14:56:06.275+00:002023-01-08T14:56:06.275+00:00This comment has been removed by the author.Coil Ninjahttps://www.blogger.com/profile/08977705803658258222noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-25894753033931566852016-12-11T14:51:01.290+00:002016-12-11T14:51:01.290+00:00Unless I'm missing something, I get negative v...Unless I'm missing something, I get negative values for the last approximation for linear to sRGB for small linear values:<br /><br />float3 sRGB = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.0225411470 * RGB;<br /><br />This occurs quite easily if you are trying to convert a small (1/255 .. 10/255) sRGB value to linear and then back using both approximations you present here.<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-47661956995928632022016-01-01T23:33:29.282+00:002016-01-01T23:33:29.282+00:00Dariusz,
The sRGB to linear RGB transformation is...Dariusz,<br /><br />The sRGB to linear RGB transformation is a little bit further up the page. For clarity, here's the code again:<br /><br />float3 RGB = sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);Ian Taylorhttps://www.blogger.com/profile/06869762490434824010noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-84958247217510446512015-12-26T13:53:28.705+00:002015-12-26T13:53:28.705+00:00Interesting stuff!
The example above show us how...Interesting stuff! <br /><br />The example above show us how to go from Linear to sRGB, How about going from sRGB back to Linear? How can I get that data? Or other way around ehh I'm getting confused already! :- )Dariuszhttps://www.blogger.com/profile/13445838753444686736noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-60421197795425142142015-12-26T13:52:53.069+00:002015-12-26T13:52:53.069+00:00Interesting stuff!
The example above show us how...Interesting stuff! <br /><br />The example above show us how to go from Linear to sRGB, How about going from sRGB back to Linear? How can I get that data? Or other way around ehh I'm getting confused already! :- )Dariuszhttps://www.blogger.com/profile/13445838753444686736noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-17231436975839054112015-11-05T23:48:53.821+00:002015-11-05T23:48:53.821+00:00Thanks Anonymous. That's an interesting puzzle...Thanks Anonymous. That's an interesting puzzle you've got there; I hadn't really wondered about a cache-friendly conversion for CPUs until you got me thinking... So, I've had a bit of fun having a stab at this problem in the last few days. See http://chilliant.blogspot.co.uk/2015/11/srgb-integer-conversions.html<br /><br />Thanks again.Ian Taylorhttps://www.blogger.com/profile/06869762490434824010noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-20417553659189506102015-10-30T08:23:13.566+00:002015-10-30T08:23:13.566+00:00Hi, Ian, really good work.
I ended just using loo...Hi, Ian, really good work.<br /><br />I ended just using lookup table with 16368 entries. Should easily fit in most L1 data caches on most CPUs (mine has 32K data + 32K instruction). Prefiling cache before bulk conversion, or generating lookup tables just before conversion is also good option. Good enough precision too. :)<br /><br />static ubyte gamma_full(const float c) pure {<br /> return c <= 0.0031308f<br /> ? cast(ubyte)(0.5f + 255.0f * 12.92f * c)<br /> : cast(ubyte)(0.5f + 255.0f * (1.055f * math.pow!(float, float)(c, 1.0f / 2.4f) - 0.055f)); // Could save one mul here.<br />}<br /> <br />ubyte[16384] gamma_t;<br /><br />static ubyte gamma(const float c) {<br /> const int i = cast(int)(16383.0f * c);<br /> return gamma_t[i & 0x3FFF];<br />}<br /><br />Bitwise OR is to avoid clamping using conditionals on x86, and just return random color instead, without crashing.<br /><br />Anyway, same results, but now it is 15 times faster than using pow + branching. And my compiler is stupid and do not inline pow too well, nor does it use sse for it. :(<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-75650394347771701292015-03-12T20:41:08.002+00:002015-03-12T20:41:08.002+00:00Sigh... Well spotted! I've just looked back at...Sigh... Well spotted! I've just looked back at my original spreadsheets and have corrected the code:<br /><br />"float3 sRGB = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.225411470 * RGB;"<br /><br />near the bottom of the article has been corrected to<br /><br />"float3 sRGB = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.0225411470 * RGB;"<br /><br />I've no idea what I was thinking when I copied the code to this posting, but I was obviously a bit preoccupied. Or just plain lax. As before, the graphs are correct, though.Ian Taylorhttps://www.blogger.com/profile/06869762490434824010noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-29450986134037159832015-03-12T05:03:46.519+00:002015-03-12T05:03:46.519+00:00Very useful article. but value of 0.225411470 is t...Very useful article. but value of 0.225411470 is the mistake of 0.0225411470?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-1261456413376379502015-02-22T21:39:54.701+00:002015-02-22T21:39:54.701+00:00PB, the curve fitting software is actually just Mi...PB, the curve fitting software is actually just Microsoft Excel. The functions are fairly well-behaved (no local minima/maxima), so just using Excel's vanilla "Solver" add-in works a treat. The graphs are straight out of Excel too. I generally find it useful to blame spreadsheets for "crazy magical" results.Ian Taylorhttps://www.blogger.com/profile/06869762490434824010noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-51765573680302739422015-02-11T18:29:43.849+00:002015-02-11T18:29:43.849+00:00Nice article. I'm curious about your process.
...Nice article. I'm curious about your process.<br /><br />I could imagine one could have insight enough to substitute a sqrt() for pow() on some platform, but those coefficients are crazy magical! C_srgb_3 for uses 0.585122381 for example...<br /><br />Do you use some curve fitting software or something that lets you investigate the effects of this stuff? How are you generating the graphs?Pinkelton Bobsledderhttps://www.blogger.com/profile/11874007129605086532noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-5614371075931390842014-01-25T16:49:13.249+00:002014-01-25T16:49:13.249+00:00Quite so, well spotted! Must be yet another typo: ...Quite so, well spotted! Must be yet another typo: the graphs and results seem to be okay. I've corrected the code snippet. Thanks!Ian Taylorhttps://www.blogger.com/profile/06869762490434824010noreply@blogger.comtag:blogger.com,1999:blog-5181746871086541575.post-50284063098733905942014-01-23T11:50:19.990+00:002014-01-23T11:50:19.990+00:00In the "official" transformation to line...In the "official" transformation to linear described at the top of the article, you have: <br /><br />C_lin = 1.055 * pow((C_srgb + 0.055) / 1.055, 2.4);<br /><br />I believe the extra 1.055 multiplier is incorrect! Shouldn't this just read:<br /><br />C_lin = pow((C_srgb + 0.055) / 1.055, 2.4);<br /><br />...?<br /><br />Anonymousnoreply@blogger.com