Add fast sRGB conversion.
This commit is contained in:
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…
Reference in New Issue
Block a user