WebGl 将 float 打包到 v4 中

问题描述 投票:0回答:2

我有来自 Threejs 示例的代码示例 [http://thirdjs.org/examples/#webgl_animation_cloth],其中浮点值转换为 vec4。我在其他几个论坛上看到过这种逻辑,但没有解释。

  1. 有人可以解释一下这个逻辑在做什么以及 256 的用途吗?我理解按位掩码和移位。

我也看过这个链接将 float 打包到 vec4 - 这段代码是如何工作的?

  1. 它表示vec4最终将存储在32位RGBA8缓冲区中。
    由于我们将深度值传递到颜色缓冲区中,opengl 如何知道如何处理它?

  2. 此外,由于 vec4 有 4 个组件,每个组件 4 个字节,使其成为 16 个字节,从而使其成为 16 * 8 位,这如何适合 32 位 RGBA8 ?

         vec4 pack_depth( const in float depth ) {
           const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 *   
           256.0,256.0,1.0);
           const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 /  
           256.0);
           vec4 res = fract( depth * bit_shift );
           res -= res.xxyz * bit_mask;
           return res;
           }
    
        void main() {
            vec4 pixel = texture2D( texture, vUV );
            if ( pixel.a < 0.5 ) discard;
            gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );
        }
    
opengl-es three.js webgl
2个回答
2
投票

连同 @WaclawJasper 的答案,此代码将“深度”(浮点值(32 位))打包为 4 个 8 位值。

gl_FragData[ 0 ]
表示纹理中的单个像素,在本例中是每个通道 8 位的纹理(总共 32 位)。 如果我写

gl_FragData[0] = vec4(0.25, 0.5, 0.75, 1.0);

正在写入的纹理(假设它是 8 位纹理)实际上会获取值

r = Math.floor(0.25 * 255) = 63;
g = Math.floor(0.5  * 255) = 127;
b = Math.floor(0.75 * 255) = 191;
a = Math.floor(1.0  * 255) = 255;

规范中的实际公式是有效的

unsignedIntValue = floor(clamp(floatValue, 0., 1.) * (pow(2., numberOfBits) - 1.));

因此,即使

pack_depth
返回一个浮点型 vec4,并且
gl_FragData
被定义为
vec4
,当写入到当前正在写入的任何 WebGL(画布、渲染缓冲区、纹理)时,它最终也会被转换。

如果写入浮点纹理

pack_depth
将是不必要的。由于
pack_depth
正在执行的操作,我们可以推断它正在写入 8 位 RGBA 纹理。

为什么有这个需求?因为在 WebGL 中,对浮点纹理的支持是可选的。因此,如果用户的机器不支持浮点纹理,并且您需要类似浮点的数据(如阴影贴图的深度缓冲区),那么将数据打包到 8 位纹理中是一种解决方案。


1
投票
  1. 256是8位数据可以表示的不同值的数量。让我们暂时停止使用二进制,转而使用熟悉的十进制。如果我们有 2 个通道,每个通道只能存储 1 位数字 (0-9),那么我们如何打包 45 这样的数字?显然,我们将 5 打包为一位数字,将 40/10 或 4 打包为另一位数字。然后在我们的 unpack 函数中,我们只需执行相反的操作:4*10 + 5 = 45。256 类似于十进制示例中的 10。

  2. OpenGL 没有,但您自己的应用程序代码可以理解它。

  3. 我不确定我是否正确理解这部分,但您显示的代码是将一个浮点数打包成8*4位RGBA。

© www.soinside.com 2019 - 2024. All rights reserved.