首页 > 解决方案 > 如何在 GLSL(WebGL GLSL ES 1.0)中浮动到 RGBA 并返回往返?

问题描述

我正在尝试使用 aFloat32Array作为浏览器中 GPGPU 计算的输入。

转换Float32ArrayUint8Array工作正常,我正在寻找一种方法

  1. 将 RGBA 转换为浮点数
  2. 执行一些计算
  3. 将浮点数转换为 RGBA

为了从 Javascript 中检索结果。

片段着色器如下所示:

vec4 getPointX(in sampler2D tex, in vec2 dimensions, in float index) {
  vec2 uv = (
         vec2(
          floor(mod(index, dimensions.x)),
          floor(index / dimensions.x)) + 0.5
         ) / dimensions;
  return texture2D(tex, uv).rgba;
}

const vec4 bitEnc = vec4(1.0, 255.0, 65025.0, 16581375.0);
const vec4 bitDec = 1.0 / bitEnc;

vec4 EncodeFloatRGBA (float v) {
    vec4 enc = bitEnc * v;
    enc = fract(enc);
    enc -= enc.yzww * vec2(1.0 / 255.0, 0.0).xxxy;
    return enc;
}

float DecodeFloatRGBA (vec4 v) {
    return dot(v, bitDec);
}

void main(void) { 
  vec4 a = getPointX(aValues, aDimensions, float(gl_FragCoord.x));

  float o = DecodeFloatRGBA(a);
  vec4  t = EncodeFloatRGBA(o);

  gl_FragColor = t;
}

根据这个答案进行编码/解码(问题是关于 int - 答案似乎是关于浮动到 RGBA 并返回)。

检索像素如下所示:

const pixels  = new Uint8Array(numOutputs * 4);
const results = new Float32Array(pixels.buffer);
gl.readPixels(0, 0, numOutputs, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

但是往返 RGBA => float => RGBA 似乎不起作用。

例如在输入

Uint8Array(64) [ 222, 146, 192, 61, 116, 74, 28, 63, 56, 51, … ]

我明白了

Uint8Array(64) [ 222, 146, 192, 0, 116, 74, 28, 128, 56, 51, … ]

每四个元素都不是我所期望的。

如果 - 在上面的代码中 - 我做

gl_FragColor = a

并跳过解码/编码往返工作干净,所以在我看来,事情发生在解码/编码步骤

那问题出在哪里?

标签: glslwebgl

解决方案


推荐阅读