2011-08-01 23 views
6

Actualmente estoy ocupado con el sombreado diferido en webgl y necesito decodificar 3 valores enteros (en el rango [0..256] = 256^3) a un Flotador simple de 32 bits y codifíquelo más tarde. porque esto es para WebGL, tiene que hacerse sin operaciones bit a bit. la precisión no es importante para mí (pero se puede lograr, creo).decodificar valor de rgb para un solo flotante sin desplazamiento de bits en glsl

esto es lo que tengo pero creo que esto es incorrecto debido a la precisión de la textura donde almaceno el valor codificado.

float packColor(vec3 color) { return (color.r + (color.g*256.) + (color.b*256.*256.))/(256.*256.*256.); } 

vec3 decodeColor(float f) { 
float b = floor(f * 256.0); 
float g = floor(f * 65536.0) - (b*256.); 
float r = (floor(f * 16777216.0) - (b*65536.)) - (g*256.); 
return vec3(r, g, b)/ 256.0;//vec3(r, g, b)/256.0; } 

gracias ..

+0

creo que usted mezcló los significados de las palabras "codificar" y "Decode" ... – Tara

Respuesta

18

sé que esto es una cuestión de edad, pero que tenía el mismo problema, y ​​voy a publicar la solución en caso de que alguien lo necesita en el futuro

float packColor(vec3 color) { 
    return color.r + color.g * 256.0 + color.b * 256.0 * 256.0; 
} 

vec3 unpackColor(float f) { 
    vec3 color; 
    color.b = floor(f/256.0/256.0); 
    color.g = floor((f - color.b * 256.0 * 256.0)/256.0); 
    color.r = floor(f - color.b * 256.0 * 256.0 - color.g * 256.0); 
    // now we have a vec3 with the 3 components in range [0..255]. Let's normalize it! 
    return color/255.0; 
} 

Mientras el flotador lleno de packColor no está en el rango [0, 1] pero en el rango [0, 16777215], no debería tener ningún problema con la precisión. Pero si normalizas el flotador en el rango [0,1], ¡tendrás problemas de precisión!

Tenga en cuenta que tampoco puede almacenar alfa (de esta forma), ya que los flip highp tienen una longitud de 24 bits y no 32 como los que normalmente se usan. En vertex shader puede usar este código sin problemas (la precisión predeterminada es highp), pero en el sombreador de fragmentos debe asegurarse de usar solo alta precisión.

+0

Gracias por ese comentario sobre el rango, ¡estaba teniendo esos problemas de precisión! – Griffork

2

gusta esta?

function pack(color) { return color.r + color.g * 256 + color.b * 256 * 256; } 

function unpack(f) { 
    var b = Math.floor(f/(256 * 256)); 
    var g = Math.floor((f - b * 256 * 256)/256); 
    var r = Math.floor(f % 256); 
    return vec3(r, g, b); 
} 
+3

que parece que funcionaría de forma algorítmica, pero Creo que el interlocutor lo quería en GLSL. – andrewmu

0

@Makers_F: Gracias por el código de GLSL función unpackColor, pero parece que azul y rojo componentes se invierten.

Para mí, el siguiente código funciona como un encanto:

vec3 unpackColor(float f) 
{ 
    vec3 color; 

    color.r = floor(f/256.0/256.0); 
    color.g = floor((f - color.r * 256.0 * 256.0)/256.0); 
    color.b = floor(f - color.r * 256.0 * 256.0 - color.g * 256.0); 

    // now we have a vec3 with the 3 components in range [0..256]. Let's normalize it! 
    return color/256.0; 
} 
+0

Tenga en cuenta que esto no funcionará para el código packColor de OP: se supone que ha empaquetado R y B de la manera opuesta también. – meetar

Cuestiones relacionadas