vulkan-playground/conversion.glsl

138 lines
3.4 KiB
GLSL

#include "glsl_shared.h"
#define CONV_MODE CONV_888S
#define LCONVERT(cmul, x) (log(cmul*x+1.0)/log(cmul+1.0))
#define LCONVERT2(cmul,mul,off,x) (LCONVERT(cmul,abs(x))*sign(x)*(mul) + off)
#define LICONVERT(cmul,x) ((exp(x*log(cmul+1.0))-1.0)/cmul)
#define LICONVERT2(cmul,mul,off,x) LICONVERT(cmul,abs(x-off)/(mul))*sign(x-off)
#define MAKE_CONV(cnv,cmul,mul,off)float inv##cnv(float x){return LICONVERT2(cmul,mul,off,x);} float cnv(float x){return LCONVERT2(cmul,mul,off,x);}
#if CONV_MODE == CONV_SLINEAR
vec4 conv_store(vec3 vals)
{
return vec4(vals,1);
}
vec3 conv_load(vec3 color)
{
return color;
}
#elif CONV_MODE == CONV_ULINEAR
float uconv(float color)
{
return abs(color - 0.5)*2*sign(color-0.5)
}
float invuconv(float color)
{
return abs(color - 0.5)/2*sign(color-0.5);
}
vec3 conv_load(vec3 color)
{
return vec3(invuconv(color.x),invuconv(color.z),invuconv(color.y));
}
vec4 conv_store(vec3 vals)
{
return vec4(uconv(vals.x),uconv(vals.z),uconv(vals.y),1);
}
#elif CONV_MODE == CONV_565
MAKE_CONV(uconv2,0.5, 15.75/31.0,15.0/31.0)
MAKE_CONV(uconv,2.0, 31.75/63.0,31.0/63.0)
vec4 conv_store(vec3 vals)
{
return vec4(uconv2(vals.x),uconv(vals.y),uconv2(vals.z),1);
}
vec3 conv_load(vec3 color)
{
return vec3(invuconv2(color.x),invuconv(color.y),invuconv2(color.z));
}
#elif CONV_MODE == CONV_565L
float uconv(float x)
{
return LCONVERT(0.125,(clamp(abs(x),0.1,0.9)-0.1)/0.8)*sign(x)*31.75/63.0 + 31.0/63.0;
}
float uconv2(float x)
{
return LCONVERT(0.25,(clamp(abs(x),0.1,0.7)-0.1)/0.6)*sign(x)*15.75/31.0 + 15.0/31.0;
}
float invuconv(float x)
{
if(abs(x - 31.0/63.0) < 0.01 )
return 0;
return (LICONVERT(0.125,abs(x-31.0/63.0)/(31.75/63.0))*0.8+0.1)*sign(x-31.0/63.0);
}
float invuconv2(float x)
{
if(abs(x - 15.0/31.0) < 0.01 )
return 0;
return (LICONVERT(0.25,abs(x-15.0/31.0)/(15.75/31.0))*0.6+0.1)*sign(x-15.0/31.0);
}
vec4 conv_store(vec3 vals)
{
return vec4(uconv2(vals.x),uconv(vals.y),uconv2(vals.z),1);
}
vec3 conv_load(vec3 color)
{
return vec3(invuconv2(color.x),invuconv(color.y),invuconv2(color.z));
}
#elif CONV_MODE == CONV_888S
float uconv(float x)
{
float cv = LCONVERT(32,(clamp(abs(x),0.1,0.9)-0.1)/0.9)*sign(x);
return (cv / 2 + float(cv < 0.0));
}
float invuconv(float x)
{
float s1 = x;//x;//(x - 0.5) / 1.1 + 0.5;
float icv = (float(s1 > 0.5)*(s1 - 1) + float(s1 <= 0.5) * s1)*2;
return (LICONVERT(32,abs(icv))*0.8+0.1)*sign(icv);
}
vec4 conv_store(vec3 vals)
{
return vec4(uconv(vals.x),uconv(vals.y),uconv(vals.z),1);
}
vec3 conv_load(vec3 color)
{
return vec3(invuconv(color.x),invuconv(color.y),invuconv(color.z));
}
#elif CONV_MODE == CONV_332
// todo: tune this better. Maybe use table instead of log/exp
MAKE_CONV(uconv2,96.0, 0.6,1.0/3)
MAKE_CONV(uconv,32.0, 0.55,3.0/7)
uvec4 conv_store(vec3 vals)
{
return uvec4(uint(uconv(vals.x) * 7) | uint(uconv(vals.y) * 7) << 3 | (uint(uconv2(vals.z)* 3)) << 6,0,0,0);
}
vec3 conv_load(uvec3 color)
{
return vec3(invuconv(float((color >> 0) & 7)/7),
invuconv(float((color >> 3) & 7)/7),
invuconv2(float((color >> 6) & 3)/3));
}
#else
#if CONV_MODE == CONV_4444
// todo: use last 4 bits for 8bit video improvement?
MAKE_CONV(uconv,128.0, 7.75/15,7.0/15.0)
#elif CONV_MODE == CONV_888
MAKE_CONV(uconv,4, 127.75/255,127.0/255.0)
#endif
vec4 conv_store(vec3 vals)
{
return vec4(uconv(vals.x),uconv(vals.y),uconv(vals.z),1);
}
vec3 conv_load(vec3 color)
{
return vec3(invuconv(color.x),invuconv(color.y),invuconv(color.z));
}
#endif