Add fast sRGB conversion.

pull/289/head
Ignacio 6 years ago
parent bc60e8c154
commit a1c54bc7f7

@ -1499,24 +1499,47 @@ static float toSrgb(float f) {
return f;
}
void Surface::toSrgb()
{
// sRGB approximation from: http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
static float toSrgbFast(float f) {
f = saturate(f);
float s1 = sqrtf(f);
float s2 = sqrtf(s1);
float s3 = sqrtf(s2);
return 0.662002687f * s1 + 0.684122060f * s2 - 0.323583601f * s3 - 0.0225411470f * f;
}
void Surface::toSrgb() {
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
//parallel_for(count, 128, [=](int i) {
channel[i] = ::toSrgb(channel[i]);
}//);
const uint count = 3 * img->pixelCount();
float * channel = img->channel(0);
for (uint i = 0; i < count; i++) {
channel[i] = ::toSrgb(channel[i]);
}
}
void Surface::toSrgbFast() {
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = 3 * img->pixelCount();
float * channel = img->channel(0);
for (uint i = 0; i < count; i++) {
channel[i] = ::toSrgbFast(channel[i]);
}
//parallel_for(count, 128, [=](int i) {
// channel[i] = toSrgbFast(channel[i]);
//});
}
static float fromSrgb(float f) {
if (f < 0.0f) f = 0.0f;
else if (f < 0.04045f) f = f / 12.92f;
@ -1525,24 +1548,48 @@ static float fromSrgb(float f) {
return f;
}
void Surface::toLinearFromSrgb()
{
// sRGB approximation from: http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
static float fromSrgbFast(float f) {
f = saturate(f);
return f * (f * (f * 0.305306011f + 0.682171111f) + 0.012522878f);
}
void Surface::toLinearFromSrgb() {
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = img->pixelCount();
for (uint c = 0; c < 3; c++) {
float * channel = img->channel(c);
for (uint i = 0; i < count; i++) {
//parallel_for(count, 128, [=](int i) {
channel[i] = ::fromSrgb(channel[i]);
}//);
const uint count = 3 *img->pixelCount();
float * channel = img->channel(0);
for (uint i = 0; i < count; i++) {
channel[i] = ::fromSrgb(channel[i]);
}
//parallel_for(count, 128, [=](int i) {
// channel[i] = ::fromSrgb(channel[i]);
//});
}
void Surface::toLinearFromSrgbFast() {
if (isNull()) return;
detach();
FloatImage * img = m->image;
const uint count = 3 * img->pixelCount();
float * channel = img->channel(0);
for (uint i = 0; i < count; i++) {
channel[i] = ::fromSrgbFast(channel[i]);
}
//parallel_for(count, 128, [=](int i) {
// channel[i] = ::fromSrgbFast(channel[i]);
//});
}
static float toXenonSrgb(float f) {
if (f < 0) f = 0;
else if (f < (1.0f/16.0f)) f = 4.0f * f;

@ -529,7 +529,9 @@ namespace nvtt
NVTT_API void toLinear(int channel, float gamma);
NVTT_API void toGamma(int channel, float gamma);
NVTT_API void toSrgb();
NVTT_API void toSrgbFast();
NVTT_API void toLinearFromSrgb();
NVTT_API void toLinearFromSrgbFast();
NVTT_API void toXenonSrgb();
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]);
NVTT_API void swizzle(int r, int g, int b, int a);

Loading…
Cancel
Save