我想将顶点法线显示为始于顶点的线,并且基于指定的比例在与距离的法线相同的方向上延伸。
我能看到的最简单的方法是计算CPU上模型空间中每个法线的起点和终点,使用模型视图矩阵的逆转置将每个法线转换为视图空间,并绘制它们作为GPU上的线条。
有更好的方法吗?我想到将顶点位置和法线传递到着色器中以便它可以计算线位置,但这看起来更复杂,我相信在着色器中需要一个分支。
答案 0 :(得分:2)
如果您需要将法线可视化以用于测试目的,您可能需要将正常的 xyz 坐标设置为gl_FragColor
。不是很直观,但是当你看这些颜色时会给出法线正确性的整体印象。
我们已经使用这种技术来检查向VBO加载法线的正确性。
答案 1 :(得分:1)
在OpenGL ES 2.0中,如果没有CPU内部的额外计算,这绝对是不可能的。您不能只渲染所有顶点并为每个顶点神奇地创建一条线。因此,即使根据法线计算顶点着色器内的顶点坐标,您仍然必须为网格的每个原始顶点放置一条线(因此两个顶点)。所以这至少需要对顶点数据进行一些重组。
你也是正确的,这将要求你以某种方式在着色器内的一行的起始顶点和结束顶点之间消除歧义。但是你不一定需要一个分支,只需将起始顶点的法线设置为全0(假设在渲染线时你不需要其他任何东西的法线,但是线条通常都不会被点亮):
CPU:
for each original vertex:
generate two line vertices with attributes of original vertex
set normal attribute of first line vertex to 0-vector
...
render all lines using following shader
GPU:
attribute vec3 position;
attribute vec3 normal;
...
void main()
{
...
vec3 modelPos = position + normal;
gl_Position = projMat * modelviewMat * vec4(modelPos, 1.0);
}
但我不认为这会给你带来任何好处,因为你不得不告诉着色器两个线端点之间的区别,一旦你这样做,你需要为CPU上的每一行生成两个不同的顶点。一旦你这样做,你可以根据法线改变第二行顶点坐标,而不是在着色器中进行计算。那个小小的vec3-saxpy应该不会花太多钱。但也许着色器的方法更快,试试吧。
桌面GL 3+的情况会有所不同,您可以使用几何着色器。您只需将所有原始顶点渲染为点,并在几何体着色器中为每个点生成一条线,根据点的法线计算其坐标。然后真的不需要任何类型的CPU计算。但不幸的是,ES 2没有几何着色器(不过不知道ES 3)。