现代GLSL中的半向量是什么?

5

http://www.lighthouse3d.com/opengl/glsl/index.php?ogldir2 报告称,在OpenGL上下文中,半向量的计算方法为'眼位置-光源位置',但随后它又说'幸运的是,OpenGL已经为我们计算好了'(这种方法现已废弃)。

如何实际计算半向量(提供一个简单的示例将非常有帮助)[主要是我不明白“眼睛”是什么以及它怎样被推导出来]。

目前我已成功使用半向量为光源的方法计算镜面反射(视觉效果良好)。

vec3 Light = normalize(light_position - vec3(out_Vertex));

现在,我不知道为什么它起作用了。

[如果我至少知道“Eye”是什么以及如何实际推导它。]

2个回答

7
半向量(half-vector)用于镜面反射光照,并代表着表面微小不完美处的法线。这些不完美会使得入射光线反射朝向观察者。当半向量越接近表面法线,更多的不完美会与实际表面法线对齐。平滑的表面会有较少指向远离表面法线的不完美,因此产生的高光更加锐利,随着半向量偏离实际法线越来越远,光线强度下降得也更明显。这种下降的量由镜面项控制,它是余弦值与半向量和法向量之间的幂次方,因此平滑的表面具有更高的幂次方。
我们称其为半向量(H),因为它位于指向光源的向量(光线向量L)和指向观察者的向量(视点位置(0,0,0)减去在眼空间中的顶点位置,视线向量V)的中间位置。在计算H之前,请确保指向光源的向量和视点位置在同一坐标空间内(旧版OpenGL使用眼空间)。
H = normalize( L + V )

你的计算是正确的,但你的变量名称可能更加准确。这里的“light_position”一词并不完全正确,因为你引用的教程是定向光教程,根据定义,定向光没有位置。 定向光的光矢量与顶点无关,所以在这里,你已经将几个方程组合在一起了。请记住,光矢量指向光源,与光子从光源流动的方向相反。

// i'm keeping your term here... I'm assuming
// you wanted to simulate a light coming from that position
// using a directional light, so the light direction would
// be -light_position, making
// L = -(-light_position) = light_position
vec3 L = light_position;
     // For a point light, you would need the direction from
     // the point to the light, so instead it would be
     // light_position - outVertex
vec3 V = -out_Vertex;
     // really it is (eye - vertexPosition), so (0,0,0) - out_Vertex
vec3 H = normalize(L + V);

5
在片段着色器中,顶点坐标可以被视为从相机(或观察者的“眼睛”)到当前片段的向量,因此通过反转该向量的方向,我们就得到了您要查找的“Eye”向量。在计算Half-vector时,您还需要注意光源位置向量的方向,在您提供的网页上,它指向表面,而在http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model中则指向远离表面的方向。

你的意思是 Eye 只有 1/out_Vertex.x、1/out_Vertex.y 和 1/out_Vertx.z 吗? - j riv
不好意思,我之前措辞有误。我的意思是Eye=(-out_Vertex.x, -out_Vertex.y, -out_Vertex.z)。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接