Ios 来自GLES2着色器的高精度输出

Ios 来自GLES2着色器的高精度输出,ios,opengl-es,shader,opengl-es-2.0,gpgpu,Ios,Opengl Es,Shader,Opengl Es 2.0,Gpgpu,我在一个支持最大RGBA8渲染目标(iOS)的GLES2平台上做一些GPGPU的工作。我需要以尽可能高的精度输出+/-2.0范围内的vec2,因此我尝试将每个组件打包为8位输出的两个组件 一个重要的要求是解码+编码的往返过程保留编码值。我当前的解决方案没有此属性,因此我的值到处都在漂移 这就是我现在所拥有的(有点冗长,因为我还在想办法): 编辑:代码更简单,但仍然会漂移。好的,我来回答我自己的问题。这似乎有效——它不会漂移,但视觉效果在我看来有点不准确。注意解码器中的舍入,这是必要的 const

我在一个支持最大RGBA8渲染目标(iOS)的GLES2平台上做一些GPGPU的工作。我需要以尽可能高的精度输出+/-2.0范围内的vec2,因此我尝试将每个组件打包为8位输出的两个组件

一个重要的要求是解码+编码的往返过程保留编码值。我当前的解决方案没有此属性,因此我的值到处都在漂移

这就是我现在所拥有的(有点冗长,因为我还在想办法):


编辑:代码更简单,但仍然会漂移。好的,我来回答我自己的问题。这似乎有效——它不会漂移,但视觉效果在我看来有点不准确。注意解码器中的舍入,这是必要的

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;
}

我认为这将有助于你:

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));
}
注意硬件偏置的消除:
pack-=vec4(pack.yzw/255.0,0.0)
-非常感谢这一点

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));
}