Add fast sRGB conversion.
This commit is contained in:
parent
bc60e8c154
commit
a1c54bc7f7
@ -1499,24 +1499,47 @@ static float toSrgb(float f) {
|
|||||||
return 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;
|
if (isNull()) return;
|
||||||
|
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
|
|
||||||
const uint count = img->pixelCount();
|
const uint count = 3 * img->pixelCount();
|
||||||
for (uint c = 0; c < 3; c++) {
|
float * channel = img->channel(0);
|
||||||
float * channel = img->channel(c);
|
for (uint i = 0; i < count; i++) {
|
||||||
for (uint i = 0; i < count; i++) {
|
channel[i] = ::toSrgb(channel[i]);
|
||||||
//parallel_for(count, 128, [=](int 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) {
|
static float fromSrgb(float f) {
|
||||||
if (f < 0.0f) f = 0.0f;
|
if (f < 0.0f) f = 0.0f;
|
||||||
else if (f < 0.04045f) f = f / 12.92f;
|
else if (f < 0.04045f) f = f / 12.92f;
|
||||||
@ -1525,24 +1548,48 @@ static float fromSrgb(float f) {
|
|||||||
return 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;
|
if (isNull()) return;
|
||||||
|
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
FloatImage * img = m->image;
|
FloatImage * img = m->image;
|
||||||
|
|
||||||
const uint count = img->pixelCount();
|
const uint count = 3 *img->pixelCount();
|
||||||
for (uint c = 0; c < 3; c++) {
|
float * channel = img->channel(0);
|
||||||
float * channel = img->channel(c);
|
for (uint i = 0; i < count; i++) {
|
||||||
for (uint i = 0; i < count; i++) {
|
channel[i] = ::fromSrgb(channel[i]);
|
||||||
//parallel_for(count, 128, [=](int 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) {
|
static float toXenonSrgb(float f) {
|
||||||
if (f < 0) f = 0;
|
if (f < 0) f = 0;
|
||||||
else if (f < (1.0f/16.0f)) f = 4.0f * f;
|
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 toLinear(int channel, float gamma);
|
||||||
NVTT_API void toGamma(int channel, float gamma);
|
NVTT_API void toGamma(int channel, float gamma);
|
||||||
NVTT_API void toSrgb();
|
NVTT_API void toSrgb();
|
||||||
|
NVTT_API void toSrgbFast();
|
||||||
NVTT_API void toLinearFromSrgb();
|
NVTT_API void toLinearFromSrgb();
|
||||||
|
NVTT_API void toLinearFromSrgbFast();
|
||||||
NVTT_API void toXenonSrgb();
|
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 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);
|
NVTT_API void swizzle(int r, int g, int b, int a);
|
||||||
|
Loading…
Reference in New Issue
Block a user