计算动态网格的表面法线(没有几何着色器)
Calculating surface normals of dynamic mesh (without geometry shader)
我有一个网格,其顶点位置由顶点着色器动态生成。我一直在使用 https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal 计算几何着色器中每个图元的表面法线,这似乎工作正常。
不幸的是,我打算切换到无法使用几何着色器的环境。我正在寻找计算表面法线的替代方法。我考虑过:
- 分两次使用计算着色器。一个生成顶点位置,另一个(使用生成的顶点位置)计算表面法线,然后将该数据传递到着色器管道。
- 使用ARB_shader_image_load_store(或相关)将顶点位置写入纹理(在顶点着色器中),然后可以从片段着色器中读取。片段着色器应该能够安全地访问顶点位置(因为它只会访问用于调用片段的顶点),然后可以计算每个片段的表面法线。
我相信这两种方法都应该有效,但我想知道是否有更简单的方法来执行此操作,尤其是考虑到这似乎是一项相当常见的任务.我还想知道我提出的任何一个想法是否有任何问题,因为我对计算着色器和 image_load_store.
都没有什么经验
参见 . If you just want the face normals, you can use the partial derivative dFdx
, dFdy
。在与 position
:
相同的 space 中计算法向量 (N
) 的基本片段着色器
in vec3 position;
void main()
{
vec3 dx = dFdx(position);
vec3 dy = dFdy(position);
vec3 N = normalize(cross(dx, dy));
// [...]
}
我有一个网格,其顶点位置由顶点着色器动态生成。我一直在使用 https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal 计算几何着色器中每个图元的表面法线,这似乎工作正常。
不幸的是,我打算切换到无法使用几何着色器的环境。我正在寻找计算表面法线的替代方法。我考虑过:
- 分两次使用计算着色器。一个生成顶点位置,另一个(使用生成的顶点位置)计算表面法线,然后将该数据传递到着色器管道。
- 使用ARB_shader_image_load_store(或相关)将顶点位置写入纹理(在顶点着色器中),然后可以从片段着色器中读取。片段着色器应该能够安全地访问顶点位置(因为它只会访问用于调用片段的顶点),然后可以计算每个片段的表面法线。
我相信这两种方法都应该有效,但我想知道是否有更简单的方法来执行此操作,尤其是考虑到这似乎是一项相当常见的任务.我还想知道我提出的任何一个想法是否有任何问题,因为我对计算着色器和 image_load_store.
都没有什么经验参见 dFdx
, dFdy
。在与 position
:
N
) 的基本片段着色器
in vec3 position;
void main()
{
vec3 dx = dFdx(position);
vec3 dy = dFdy(position);
vec3 N = normalize(cross(dx, dy));
// [...]
}