gpt4 book ai didi

opengl - 为什么此Phong着色器起作用?

转载 作者:行者123 更新时间:2023-12-04 04:05:28 26 4
gpt4 key购买 nike

我最近在GLSL中编写了Phong着色器,作为学校作业的一部分。我从教程开始,然后玩弄代码,直到我开始工作。据我所知,它工作得很好,但是我写的特别是一行,我不明白为什么可以使发挥作用。

顶点着色器:

#version 330

layout (location = 0) in vec3 Position; // Vertex position
layout (location = 1) in vec3 Normal; // Vertex normal

out vec3 Norm;
out vec3 Pos;
out vec3 LightDir;

uniform mat3 NormalMatrix; // ModelView matrix without the translation component, and inverted
uniform mat4 MVP; // ModelViewProjection Matrix
uniform mat4 ModelView; // ModelView matrix
uniform vec3 light_pos; // Position of the light

void main()
{
Norm = normalize(NormalMatrix * Normal);
Pos = Position;
LightDir = NormalMatrix * (light_pos - Position);

gl_Position = MVP * vec4(Position, 1.0);
}

片段着色器:
#version 330

in vec3 Norm;
in vec3 Pos;
in vec3 LightDir;

layout (location = 0) out vec4 FragColor;

uniform mat3 NormalMatrix;
uniform mat4 ModelView;

void main()
{
vec3 normalDirCameraCoords = normalize(Norm);
vec3 vertexPosLocalCoords = normalize(Pos);
vec3 lightDirCameraCoords = normalize(LightDir);

float dist = max(length(LightDir), 1.0);

float intensity = max(dot(normalDirCameraCoords, lightDirCameraCoords), 0.0) / pow(dist, 1.001);

vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);
float intSpec = max(dot(h, normalDirCameraCoords), 0.0);
vec4 spec = vec4(0.9, 0.9, 0.9, 1.0) * (pow(intSpec, 100) / pow(dist, 1.2));

FragColor = max((intensity * vec4(0.7, 0.7, 0.7, 1.0)) + spec, vec4(0.07, 0.07, 0.07, 1.0));
}

因此,我正在执行一种方法,其中您计算光矢量和相机矢量之间的半矢量,然后用法线将其点起来。很好但是,我做的两件事很奇怪。
  • 通常,一切都在眼坐标中完成。但是,位置(我从顶点着色器传递到片段着色器)位于局部坐标中。
  • 这是令我困惑的部分。在vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);行上,我将相机坐标中的光矢量与本地坐标中的顶点位置相减。这似乎是完全错误的。

  • 简而言之,我了解了此代码应该做什么以及phong着色的半向量方法是如何工作的。

    但是为什么此代码有效?

    编辑:我们提供的入门代码是开源的,因此您可以 download the completed project并直接查看。该项目适用于Windows上的VS 2012(您需要设置GLEW,GLM和freeGLUT),并且应该在GCC上工作且无需更改代码(可能对Makefile库路径进行了一两次更改)。

    请注意,在源文件中,“light_pos”称为“gem_pos”,因为我们的光源是您随WSADXC一起移动的小 gem 。按M键可让Phong带有多个指示灯。

    最佳答案

    起作用的原因是偶然的,但是有趣的是为什么它仍然起作用。

    Phong着色是中的三种技术

    使用phong阴影时,我们有三个术语:“镜面反射”,“漫反射”和“环境”;这三个术语代表在phong着色中使用的三种技术。

    这些术语都不严格要求向量空间。只要您保持一致,就可以在世界,本地或摄影机空间中使用phong着色。眼部空间通常用于照明,因为它更易于使用且转换也很简单。

    但是,如果您是原籍怎么办?现在您乘以零;很容易看出,原点的任何向量空间之间都没有差异。碰巧的是,从根本上讲,您位于哪个向量空间都无关紧要;会的。

    vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);

    请注意,它基本上是减去0。这是唯一一次使用本地方法,并且在可能造成最小损害的地方使用它。由于对象位于原点,因此其所有顶点也应位于原点或非常接近原点。在原点,近似值是精确的;所有向量空间都收敛。非常接近原点,非常接近精确;即使我们使用精确实数,也会有很小的差异,但是我们不使用精确实数,而是使用浮点数,这使问题更加复杂。

    基本上,您很幸运;如果对象不是原点,这将不起作用。尝试移动它看看!

    另外,您没有使用 Phong shading;您正在使用 Blinn-Phong shading(这是用半个向量替换reflect()的名称,仅供引用)。

    关于opengl - 为什么此Phong着色器起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22411998/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com