Android 如何在opengl es 2中的顶点着色器程序中访问其他顶点?

Android 如何在opengl es 2中的顶点着色器程序中访问其他顶点?,android,opengl-es,shader,vertex-shader,Android,Opengl Es,Shader,Vertex Shader,我是一个android应用程序,我想计算一个曲面在该曲面其他顶点上的法线。我不想在“master”程序中这样做,因为它需要很多时间。实际上,对于每个顶点,我为每个vextex传递4个浮点数组: attribute vec3 a_bottom; attribute vec3 a_left; attribute vec3 a_right; attribute vec3 a_top; vec3 calculNormal( ) { return normalize( cross( (a_lef

我是一个android应用程序,我想计算一个曲面在该曲面其他顶点上的法线。我不想在“master”程序中这样做,因为它需要很多时间。实际上,对于每个顶点,我为每个vextex传递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这样的特殊关键字?还是我错过了另一种可能性?

这确实是不可能的。顶点着色器只能访问当前处理的顶点及其属性。而且,由于OpenGL ES没有
texture\u buffer\u object
扩展,因此无法访问着色器中VBO的数据。因此,访问顶点邻域的唯一方法是显式地将它们作为顶点属性放入,如第一个示例中所示

但是,由于您的几何体看起来是一个矩形图案,您也可以将其存储在纹理中(或者将其复制到一个纹理中,如果ES中支持,
pixel\u buffer\u对象
扩展可能会有所帮助)。在本例中,您可以只使用经典的GPGPU片段着色器,该着色器基于输出图像的每个“像素”(在本例中为顶点)的值(在本例中为矩形几何体的法线数据)(通过简单纹理访问访问)计算法线

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

我想计算一个曲面的法线,在这个曲面的另一个顶点上

错误的方法。计算法线并将其与顶点一起存储

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

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


计算并存储它们。

Hi datenwolf。如果我想在运行时创建对象后对高度贴图进行采样,该怎么办?我是否应该通过着色器对高度贴图进行采样,变换顶点,将其发送回,然后上载另一个VBO?我不认为在CPU上对纹理进行采样是一种真正的方式,首先,纹理是使用glTexImage上传的,而CPU并没有它。@TitoneMaurice:最初的问题是关于普通网格的。但是高度贴图是一种特殊情况,在这种情况下,可以使用右核(离散差分,也称梯度核)的卷积来计算曲面法线。使用
textureGather
(GLSL-4和更高版本)可以获取2×2的纹理网格,这正是您需要的。但是,我仍然建议预先计算法线,这样可以有效地为纹理提供法线贴图。@TitoneMaurice:应用想法:创建高分辨率的heightmap,从中生成法线贴图,使用全分辨率法线贴图(在片段着色器中)用于照明计算和顶点置换的下采样高度贴图。进一步的想法:您可以存储全分辨率高度法线贴图,并在顶点阶段访问低分辨率LoD,在片段着色器中,使用全分辨率和顶点高度值之间的差值作为视差贴图的输入,以提高视觉质量。