【问题标题】:Encode axis aligned unit vector in a single float value将轴对齐的单位向量编码为单个浮点值
【发布时间】:2019-04-25 21:37:53
【问题描述】:

我想将轴对齐的单位向量编码为单个浮点值。像这样:

0: vec3(0, 0 ,0)

1: vec3(1, 0, 0)

2: vec3(0, 1, 0)

3: vec3(0, 0, 1)

根据表格将浮点数转换为向量我可以编写一个简单的代码

in float axisIndex
...
vec3 axis = vec3(0.0, 0.0, 0.0);
if (axisIndex > 0.5) {
  axis = vec3(1.0, 0.0, 0.0);
}
if (axisIndex > 1.5) {
  axis = vec3(0.0, 1.0, 0.0);
}
if (axisIndex > 2.5) {
  axis = vec3(0.0, 0.0, 1.0);
}

但是如果分支很慢。有没有一种快速的方法可以将浮点数转换为向量,而不使用 if 分支和外部缓冲区,只使用数学?

【问题讨论】:

  • 为什么?为什么不只使用有符号字节。这将为您提供每个正常的 3 个字节,这比每个正常的 1 个浮点数少一个。如果你只想要轴对齐的法线,你应该可以用一个字节来完成。
  • 感谢您的建议和 twgl 库!

标签: opengl glsl webgl


【解决方案1】:

如果你必须这样做,那么最好的方法是使用简单的数组索引:

in uint axisIndex;

const vec3[4] table = {
  vec3(0, 0 ,0), 
  vec3(1, 0, 0),
  vec3(0, 1, 0),
  vec3(0, 0, 1)
};

然后只需使用table[axisIndex] 来获取值。您可以使用glVertexAttribIPointer 为着色器提供整数值。虽然您可以为您提供的类型使用无符号字节,但最好只使用无符号整数; OpenGL 实现不喜欢不是 4 字节对齐的顶点属性。

话虽如此,这确实是不必要的。您可以只传递 3 normalized, signed bytes 作为属性,而不是单个索引。它不会在您的顶点数据中占用更多空间(同样,实现不喜欢未对齐的属性),并且处理速度可能不会变慢。

【讨论】:

    【解决方案2】:

    一个快速的方法是

    axis = vec3(float(axisIndex == 1.0), float(axisIndex == 2.0), float(axisIndex == 3.0))
    

    请注意,axisIndex 可能是uint 而不是float,在这种情况下,如果您将其作为GL_UNSIGNED_BYTE 传递,您只需将每个顶点1 个字节传递给GPU。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2013-04-09
      • 1970-01-01
      相关资源
      最近更新 更多