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

发布于 2024-09-24 00:50:23 字数 485 浏览 4 评论 0 原文

http://www.lighthouse3d.com/opengl/glsl/index.php? ogldir2 报告说 OpenGL 上下文中的半向量是“眼睛位置 - 灯光位置”,但接着又说“幸运的是 OpenGL 为我们计算了它”[现已弃用]。

实际上如何计算(一个简单的例子将不胜感激)[主要是,它让我困惑什么是“眼睛”以及如何导出它]。

目前,我设法使镜面反射计算工作(具有良好的视觉结果),半矢量等于光,其中光

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

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

[如果至少我知道“眼睛”是什么以及它如何实际衍生出来就好了。]

http://www.lighthouse3d.com/opengl/glsl/index.php?ogldir2
reports that half vector in OpenGL context is 'Eye position - Light position' but then it goes on to say 'luckily OpenGL calculates it for us' [which is now deprecated].

How can, practically be calculated (a simple example would be greatly appreciated) [mainly, it puzzles me what "Eye" is and how it can be derived].

At the moment I managed to make specular calculations work (with good visual result) with half vector being equal to Light where Light is

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

Now, I've no idea why that worked.

[If at least I knew what "Eye" is and how it can be derived practically.]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋意浓 2024-10-01 00:50:23

半矢量用于镜面照明,代表表面微缺陷处的法线,这会导致入射光反射向观察者。当半矢量更接近表面法线时,更多缺陷与实际表面法线对齐。与较粗糙的表面相比,较光滑的表面远离表面法线的缺陷较少,并且当半矢量远离实际法线时,会产生更锐利的高光和更显着的光衰减。下降量由镜面反射项控制,镜面反射项是取半矢量和法线矢量之间的余弦的幂,因此更平滑的表面具有更高的幂。

我们称其为半矢量 (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);

The half-vector is used in specular lighting and represents the normal at micro-imperfections in the surface which would cause incoming light to reflect toward the viewer. When the half-vector is closer to the surface normal, more imperfections align with the actual surface normal. Smoother surfaces will have fewer imperfections pointing away from the surface normal and result in a sharper highlight with a more significant drop off of light as the half-vector moves away from the actual normal than a rougher surface. The amount of drop off is controlled by the specular term, which is the power to which the cosine between the half-vector and normal vector is taken, so smoother surfaces have a higher power.

We call it the half-vector (H) because it is half-way between the vector point to the light (light vector, L) and the vector pointing to the viewer (which is the eye position (0,0,0) minus the vertex position in eye space; view vector, V). Before you calculate H, make sure the vector to the light and the eye are in the same coordinate space (legacy OpenGL used eye-space).

H = normalize( L + V )

You did the correct calculation, but your variables could be named more appropriately.
The term light_position here isn't entirely correct, since the tutorial you cited is the Directional light tutorial, which by definition, directional lights don't have position. The light vector for directional lights is independent of the vertex, so here, you have combined a few equations. Keep in mind, the light vector is toward the light, so opposite of the flow of photons from the light.

// 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);
静水深流 2024-10-01 00:50:23

在片段着色器中,顶点坐标可以看作是从相机(或观看者的“眼睛”)到当前片段的向量,因此通过反转该向量的方向,我们就得到了“眼睛”向量正在寻找。在计算半矢量时,您还需要了解光位置矢量的方向,在您链接的网页上,它们在 http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model 它指向远离表面的方向。

In the fragment shader the vertex coordinates can be seen as a vector that goes from the camera (or the "eye" of the viewer) to the current fragment so by reversing the direction of this vector we then have the "Eye"-vector you are looking for. When calculating the Half-vector you also need to be aware of the direction of the Light-position vector, on the webpage you link they have that on pointing towards the surface, on http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model its pointing away from the surface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文