6

我是一个 android 应用程序,我想计算一个曲面的法线依赖于该曲面的其他顶点。我不想在“主”程序中这样做,因为它需要很多时间。实际上,对于每个顶点,我为每个顶点传递 4 个浮点数组:

attribute vec3 a_bottom;
attribute vec3 a_left;
attribute vec3 a_right;
attribute vec3 a_top;

vec3 calculNormal( ) {
    return normalize( cross( (a_left - a_right) , ( a_bottom - a_top ) ) );
}

我知道这是非常非常脏的代码,所以我不想传递 4 个数组,而是这样做:

vec3 calculNormal( ) {
    vec3 a_left = CURRENT_FLOATBUFFER[ CURRENT_FLOAT_BUFFER_POSITION - 1 ];
    vec3 a_bottom = CURRENT_FLOATBUFFER[ CURRENT_FLOAT_BUFFER_POSITION - X ];
    ...
    return normalize( cross( (a_left - a_right) , ( a_bottom - a_top ) ) );
}

那么在顶点着色器程序中是否可以访问当前的浮动缓冲区?有没有像 currentFloat 这样的特殊关键字?还是我想念另一种可能性?

4

2 回答 2

9

这确实是不可能的。顶点着色器只能访问当前处理的顶点及其属性。而且由于 OpenGL ES 没有texture_buffer_object扩展,因此您无法在着色器中访问 VBO 的数据。因此,访问顶点邻居的唯一方法是明确地将它们作为顶点属性放入,就像在您的第一个示例中一样。

但是由于看起来您的几何图形是矩形图案,您也可以将其存储在纹理中(或将其复制到一个纹理中pixel_buffer_object,如果 ES 支持,扩展可能会有所帮助)。在这种情况下,您可以只使用经典的 GPGPU 片段着色器,它根据它的邻居(通过简单的纹理访问访问)。

但我想第一个和第二个都不会对你有任何影响,考虑到额外的编程开销和/或内存复制操作,因为计算顶点法线已经非常快了。无论如何,您不必每帧都这样做,如果您真的这样做,那是因为您也在更新顶点位置,在这种情况下,您可以对普通数据使用相同的更新例程(无论是 CPU 还是GPGPU)。

于 2012-01-31T14:13:19.127 回答
4

我想计算一个曲面的法线依赖于该曲面的其他顶点。

错误的做法。计算法线并将它们与顶点一起存储。

我不想在“主”程序中这样做,因为它需要很多时间。

您不应为每个渲染通道重新计算法线。只需计算它们一个并存储它们。顶点着色器中的计算不是免费的。在 VS 中计算法线只是浪费处理能力。

计算它们,存储它们。

于 2012-01-31T15:43:37.203 回答