|
|
|
@ -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;
|
|
|
|
|