【问题标题】:How to encode and send float data to GLSL from Javascript/THREE.js and decode results如何从 Javascript/THREE.js 对浮点数据进行编码和发送到 GLSL 并解码结果
【发布时间】:2016-09-20 21:25:39
【问题描述】:

我想对对象位置 (x,y,z) 进行编码并发送到 GLSL 着色器,解码数据,执行一些计算并将结果发送回 CPU。我研究过这个问题,找到了像decode rgb value to single float without bit-shift in glsl这样的部分答案,但是我对结果的编码和解码都没有成功。

这是我的代码的一部分。`...

function init() {
  ...
  buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
      -1.0, 1.0,
      -1.0, -1.0,
      1.0, -1.0,
      1.0, 1.0
    ]),
    gl.STATIC_DRAW
  );

  texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);

  vec1 = new THREE.Vector3(2.6, 3.3, 100.80); //example position vector

  data = new Uint8Array([float2Color(vec1.x).r, float2Color(vec1.x).g, float2Color(vec1.x).b, 255, //x
    float2Color(vec1.y).r, float2Color(vec1.y).g, float2Color(vec1.y).b, 255, //y
    float2Color(vec1.z).r, float2Color(vec1.z).g, float2Color(vec1.z).b, 255 //z
  ]);
   // This encodes to give me int8Array [ 2, 0, 0, 255, 3, 0, 0, 255, 100, 0, 2 more… ]
  
  gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
}

//render function

function render() {
  ...
  gl.drawArrays(gl.POINTS, 0, 2);
  var pixels = new Uint8Array(WIDTH * HEIGHT * 4);
  gl.readPixels(0, 0, WIDTH, HEIGHT, gl.RGBA, gl.FLOAT, pixels);
  pixels = new Uint8Array(pixels.buffer);
  
  //After getting the results from GLSL, pixels now look like this
  //Uint8Array [ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, … ]
 


  var color = {
    r: pixels[0],
    g: pixels[1],
    b: pixels[2]
  };
  float1 = decodeVec3ToFloat(color); // I would like to decode and use the data after the position is updated in GLSL
}

function float2Color( f ) {
        b = Math.floor(f / 255.0 / 255.0);
        g = Math.floor((f - (b * 255.0 * 255.0) ) / 255.0);
        // r = Math.floor(f - (b * 255.0 * 255.0) - (g * 255.0) );
        r = Math.floor(f % 255);
        return {r:r, g:g, b:b};
    }

function decodeVec3ToFloat(color) {
        var result;
        result = color.r * 255.0;
        result += color.g * 255.0 * 255.0;
        result += color.b * 255.0 * 255.0 * 255.0;
        return result;
    }

【问题讨论】:

  • encode 是一个非常笼统的术语。为什么你网站的问题没有回答你的问题?
  • @gaitat。我说编码是因为着色器纹理主要使用 RGBA 值。在那个问题中,他们讨论了在着色器中编码浮点数,但没有将其从 JavaScript 作为纹理/缓冲区发送到着色器。我想将大量浮动位置 (x,y,z) 发送到着色器。
  • 一种简单的方法是将您拥有的 (x,y,z) 值编码为纹理的 (r,g,b) 值。将纹理分配给平面并使用着色器材质对其进行渲染。您的纹理将被发送到硬件。处理它,完成后使用 gl readPixels 将其从 GPU 获取到 CPU。

标签: javascript three.js glsl


【解决方案1】:

我自己一直在处理这种事情。您可以使用 DataTextures 来实现这一点,并将它们作为由模拟着色器操作的缓冲区传入和传出。到目前为止,我发现的 best example 使用了 Three.js (v58) 的过时版本,但可以轻松更新。我发现更新脚本然后玩弄它是很有帮助的,直到我对我的用例有足够的理解为止。请注意,在示例中,甚至在模拟着色器中传递了固定值,以及在缓冲区中渲染进出的不断变化的 x、y、z 值。祝你好运!

更新:

我发现我上面使用的旧 THREE.FBOUtils 脚本已经更新和重新设计,现在称为THREE.GPUComputationRenderer——效果很好! (v80)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    相关资源
    最近更新 更多