Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 如何将字节解压为vec3?_Opengl_Glsl - Fatal编程技术网

Opengl 如何将字节解压为vec3?

Opengl 如何将字节解压为vec3?,opengl,glsl,Opengl,Glsl,我需要轴对齐法线,所以我想保护内存,并将其作为字节发送,而不是带有位置的alpha通道。缓冲区对象由4个字节组成:glvertexattributepointer(0,4,GL_无符号字节,GL_假,4*sizeof(GLubyte),(void*)0)编码应该是这样的 //byte in buffer object | unpacked vector x+ 0010 1011 == vec3( 1, 0, 0) x- 0010 1001 == vec3(-1, 0, 0) y+ 001

我需要轴对齐法线,所以我想保护内存,并将其作为字节发送,而不是带有位置的alpha通道。缓冲区对象由4个字节组成:
glvertexattributepointer(0,4,GL_无符号字节,GL_假,4*sizeof(GLubyte),(void*)0)编码应该是这样的

//byte in buffer object | unpacked vector
x+ 0010 1011 == vec3( 1,  0,  0)
x- 0010 1001 == vec3(-1,  0,  0)
y+ 0010 1110
y- 0010 0110
z+ 0011 1010
z- 0001 1010

//Lets take vec3(-1, 0, 1) encoded velue looks like 0011 1001
//               ,(operation) -> (result),
//Z = >>4 -> 0000 0011, &mask -> 0000 0011, -2 -> 0000 0001
//Y = >>2 -> 0000 1110, &mask -> 0000 0010, -2 -> 0000 0000
//X = >>0 -> 0011 1001, &mask -> 0000 0001, -2 -> 1111 1111
我检查了gDEBuggerGL中的编码,它是正确的。问题出现在顶点着色器中,因为解压缩相当笨拙

layout(location = 0) in vec4 vertex_position;
//...
int byte = int(vertex_position.w);

const int mask = 0x00000003; 
vec3 v_normal;
v_normal.x = float(((byte >> 0) & mask) - 2);
v_normal.y = float(((byte >> 2) & mask) - 2);
v_normal.z = float(((byte >> 4) & mask) - 2);
首先:有没有更好的方法来实现这一点

其次:我将这个法向量渲染成float纹理,发现一些值是错误的。它们中的许多不是{1,0,-1},而是接近于此。我认为这段代码不应该引入任何精度错误,那么为什么会发生这种情况呢

更新: 从顶点着色器过渡到片段着色器时会引入精度错误,可以通过添加
flat
关键字来解决。(感谢克里斯·多德)


0xFFFFFF
不是
-1
,因为您使用的是
GL\u无符号字节
,因此这不是2的补码表示。

8*sizeof(GLubyte)
看起来有点可疑?对不起,我应该更改它。有两个缓冲区,均为4*字节。但是另一个问题与这个问题无关。您确实意识到,在顶点着色器和片段着色器之间,
v_normal
将被插值,除非您采取其他步骤……不,我已经忘记了。谢谢你指出这一点
flat
关键字解决了精度错误。这仍然是错误的,因为您首先将其强制转换为
int
。我会一直想;实际上,你能试着用
GL\u字节
吗?这使用2的补码表示,这与您的逻辑一致。没有任何变化
Vertex\u position.w实际上是浮点型的,因为它是在vec4中出现的,因为gpu没有字节向量或字节。但随后它被转换成整数,剩下的魔术就在整数上完成了,整数有2的补码表示。如果你把符号位分离出来,乘以负1,然后乘以相应坐标位的值,会怎么样?这是一个效率要低得多的解决方案,但它至少应该能够为您提供一致的数据,并排除其他可能性。精度问题分布在所有维度,两个符号只有零值不受影响。这不是特定于负迁移的问题。我只是不能提供一个在所有维度上同时具有正法线和负法线的示例图片。
//Lets take vec3(-1, 0, 1) encoded velue looks like 0011 1001    
//X = >> 0 -> 0011 1001, &mask -> 0000 0001, -2 -> ffff ffff