2011-07-13 6 views
1

Я делаю некоторые вещи GPGPU на платформе GLES2, которая поддерживает максимальные цели рендеринга RGBA8 (iOS). Мне нужно вывести vec2 в диапазоне +/- 2.0 с такой же точностью, как я могу получить, поэтому я пытаюсь упаковать каждый компонент в два компонента 8-битного вывода.Высокоточный выход из шейдера GLES2

Важным требованием является то, что декодирование + кодирование в обратном направлении сохраняет закодированное значение. Мое текущее решение не имеют это свойство, и в результате мои ценности дрейфуют повсюду.

Это то, что я сейчас (это немного многословным, потому что я все еще думаю мой путь через него):

const float fixed_scale = 4.0; 

lowp vec4 encode_fixed(highp vec2 v) { 
    vec2 scaled = 0.5 + v/fixed_scale;  // map to range 0..1 
    vec2 low = fract(scaled * 255.0);  // extract low order part 
    vec2 high = scaled - low/255.0;   // subtract low from high order part 

    return vec4(low.x,high.x,low.y,high.y); // pack into rgba8 
} 

vec2 decode_fixed(highp vec4 v) { 
    vec2 scaled = v.yw + v.xz/255.0;   // recombine low and high parts 
    return (scaled - 0.5) * fixed_scale;  // map back to original range 
} 

EDIT: простой код, но до сих пор дрейфует

ответ

1

Хорошо, я Я отвечу на свой вопрос. Это, похоже, работает - оно не дрейфует, но визуальные результаты выглядят немного неточными для меня. Обратите внимание на округление в декодере, что необходимо.

const float fixed_scale = 4.0; 

lowp vec4 encode_fixed(highp vec2 v) { 
    vec2 scaled = 0.5 + v/fixed_scale; 
    vec2 big = scaled * 65535.0/256.0; 
    vec2 high = floor(big)/255.0; 
    vec2 low = fract(big); 

    return vec4(low.x,high.x,low.y,high.y); 
} 

vec2 decode_fixed(highp vec4 v) { 
    v = floor(v * 255.0 + 0.5); 
    vec2 scaled = vec2(v.yw * 256.0 + v.xz)/65535.0; 
    return (scaled - 0.5) * fixed_scale; 
} 
2

я думаю, что поможет вам:

vec4 PackFloat8bitRGBA(float val) { 
    vec4 pack = vec4(1.0, 255.0, 65025.0, 16581375.0) * val; 
    pack = fract(pack); 
    pack -= vec4(pack.yzw/255.0, 0.0); 
    return pack; 
} 

float UnpackFloat8bitRGBA(vec4 pack) { 
    return dot(pack, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); 
} 

vec3 PackFloat8bitRGB(float val) { 
    vec3 pack = vec3(1.0, 255.0, 65025.0) * val; 
    pack = fract(pack); 
    pack -= vec3(pack.yz/255.0, 0.0); 
    return pack; 
} 

float UnpackFloat8bitRGB(vec3 pack) { 
    return dot(pack, vec3(1.0, 1.0/255.0, 1.0/65025.0)); 
} 

vec2 PackFloat8bitRG(float val) { 
    vec2 pack = vec2(1.0, 255.0) * val; 
    pack = fract(pack); 
    pack -= vec2(pack.y/255.0, 0.0); 
    return pack; 
} 

float UnpackFloat8bitRG(vec2 pack) { 
    return dot(pack, vec2(1.0, 1.0/255.0)); 
} 

Обратите внимание на elemination аппаратного смещения: pack -= vec4(pack.yzw/255.0, 0.0) - большое спасибо Aras Pranckevičius для этого