Skip to content

Instantly share code, notes, and snippets.

@JayFoxRox
Last active August 29, 2015 14:27
Show Gist options
  • Save JayFoxRox/032e1f6ce9dc9606ee7b to your computer and use it in GitHub Desktop.
Save JayFoxRox/032e1f6ce9dc9606ee7b to your computer and use it in GitHub Desktop.
xqemu DotMapping code. RFC
// GLSL
uvec4 texUint8(vec4 tex) {
return uivec4(tex * 255.0);
}
uint texUint32(vec4 tex) {
uvec4 utex = texUint8(tex);
return utex.a << 24 | utex.r << 16 | utex.g << 8 | utex.b;
}
uvec2 texUint16(vec4 tex) {
uint utex = texUint32(tex);
return uvec2((utex >> 16) & 0xFFFF, utex & 0xFFFF);
}
vec3 dotMapZeroToOne(vec4 tex) {
// 0x00 = 0.0
// 0xFF = 1.0
return tex.rgb;
}
float mapMinusOneToOneD3D(uint x) {
// 0x00 = -128/127
// 0x01 = -1.0
// 0x80 = 0.0
// 0xFF = 1.0
return float(x - 128) / 127.0;
}
vec3 dotMapMinusOneToOneD3D(vec4 tex) {
uvec4 argb = texUint8();
return vec3(mapMinusOneToOneD3D(argb.r),
mapMinusOneToOneD3D(argb.g),
mapMinusOneToOneD3D(argb,b));
}
float mapMinusOneToOneGL(uint x) {
// [2 complement]
// 0x80 = -1.0
// 0x7F = 1.0
int sx = (~((x >> 7) - 1) << 8) | x;
return float(sx + 128) / 127.5 - 1.0;
}
vec3 dotMapMinusOneToOneGL(vec4 tex) {
uvec4 argb = texUint8();
return vec3(mapMinusOneToOneGL(argb.r),
mapMinusOneToOneGL(argb.g),
mapMinusOneToOneGL(argb,b));
}
float mapMinusOneToOne(uint x) {
// [2 complement]
// 0x80 = -128/127
// 0x7F = 1.0
int sx = (~((x >> 7) - 1) << 8) | x;
return float(sx) / 127.0;
}
vec3 dotMapMinusOneToOne(vec4 tex) {
uvec4 argb = texUint8();
return vec3(mapMinusOneToOne(argb.r),
mapMinusOneToOne(argb.g),
mapMinusOneToOne(argb,b));
}
vec3 dotMapHiLoOne(vec4 tex) {
uvec2 hl = texUint16(tex);
// 0x0000 = 0.0
// 0xFFFF = 1.0
return vec3(vec2(hl.xy) / 65535.0, 1.0);
}
float mapHiLoHemisphereD3D(uint x) {
// [2 complement]
// 0x8000 = -1.0
// 0x0000 = 0.0
// 0x7FFF = 32767/32768
int sx = (~((x >> 15) - 1) << 16) | x;
return float(sx) / 32768.0;
}
vec3 dotMapHiLoHemisphereD3D(vec4 tex) {
uvec2 hl = texUint16(tex);
return vec3(mapHiLoHemisphereD3D(hl.x),
mapHiLoHemisphereD3D(hl.y),
sqrt(1.0 - hl.x * hl.x - hl.y * hl.y));
}
float mapHiLoHemisphereGL(uint x) {
// [2 complement]
// 0x8000 = -1.0
// 0x7FFF = 1.0
int sx = (~((x >> 15) - 1) << 16) | x;
return float(sx + 32768) / 32767.5 - 1.0;
}
vec3 dotMapHiLoHemisphereGL(vec4 tex) {
uvec2 hl = texUint16(tex);
return vec3(mapHiLoHemisphereGL(hl.x),
mapHiLoHemisphereGL(hl.y),
sqrt(1.0 - hl.x * hl.x - hl.y * hl.y));
}
float mapHiLoHemisphere(uint x) {
// [2 complement]
// 0x8000 = -32768/32767
// 0x8001 = -1.0
// 0x0000 = 0.0
// 0x7FFF = 1.0
int sx = (~((x >> 15) - 1) << 16) | x;
return float(sx) / 32767.0;
}
vec3 dotMapHiLoHemisphere(vec4 tex) {
uvec2 hl = texUint16(tex);
return vec3(mapHiLoHemisphere(hl.x),
mapHiLoHemisphere(hl.y),
sqrt(1.0 - hl.x * hl.x - hl.y * hl.y));
}
// Map function name to string
const char* get_dotmap(struct PixelShader *ps, unsigned int stage) {
switch (ps->dotmapping[stage]) {
case PS_DOTMAPPING_ZERO_TO_ONE: return "dotMapZeroToOne";
case PS_DOTMAPPING_MINUS1_TO_1_D3D: return "dotMapMinusOneToOneD3D";
case PS_DOTMAPPING_MINUS1_TO_1_GL: return "dotMapMinusOneToOneGL";
case PS_DOTMAPPING_MINUS1_TO_1: return "dotMapMinusOneToOne";
case PS_DOTMAPPING_HILO_1: return "dotMapHiLoOne";
case PS_DOTMAPPING_HILO_HEMISPHERE_D3D: return "dotMapHiLoHemisphereD3D";
case PS_DOTMAPPING_HILO_HEMISPHERE_GL: return "dotMapHiLoHemisphereGL";
case PS_DOTMAPPING_HILO_HEMISPHERE: return "dotMapHiLoHemisphere";
default:
assert(false);
break
}
}
// Usage:
printf("vec4 t%d = ... dot(pT%d.rgb, %s(t%d)) ...\n",
i, i, get_dotmap(ps, i), ps->texInput[i]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment