【发布时间】:2020-04-04 04:32:57
【问题描述】:
关于 Phong 着色和 Goraud 着色的唯一实际区别是,如果片段颜色的计算是在顶点着色器中完成的,那么它就是 Goraud,否则就是 phong。我在下面有一点顶点着色器和片段着色器代码:
//vertexShader.vs
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
//FragmentShader.fs
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0),32);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
}
事实证明,Phong 在低多边形物体上看起来更平滑一些。因此,知识障碍基本上在于片段如何获得着色器。首先让我们看看wonderful resource learnopenGL 已经提供了什么。
总而言之,它告诉我们在顶点提供的颜色值是在由顶点构成的片段的边界内插值的。因此,这非常有意义,就像对构成顶点的颜色进行加权平均一样。
但是,就像 Phong 着色模型,计算直接在片段着色器中完成,会发生什么?片段像素如何着色?假设有三个顶点,那么片段是否完全用第一种颜色着色,完全用第二种颜色,然后用第三种颜色,是颜色的总中位数还是什么?在片段着色器中计算时片段是如何着色的?
【问题讨论】:
-
"片段像素是如何着色的?" 通过执行片段着色器。片段着色器是确定片段颜色的代码。你运行代码;这就是片段获得颜色的方式。
-
@NicolBolas,当然可以。但是,以什么输出颜色运行代码,请阅读我的最后一段。由于给出了每个像素的代码,因此没有插值的 3 个具有 3 种不同颜色的顶点。它需要哪种颜色?平均三个?三的总和?三种颜色的某种因素?
-
"3 种不同颜色的顶点" 什么颜色?我没有看到您的片段着色器给定颜色。我看到他们计算颜色,但这些颜色不是来自输入,对吗?
-
@NicolBolas ,是的,正是我的观点,没有给出颜色,输出颜色仅取决于顶点和法线的位置,但其中只有三个来自顶点着色器的常量,但表面在 phong 中是光滑的,而不是在 goroud 中。这就是为什么关于如何计算像素还有一些事情需要了解
-
顶点着色器对每个顶点执行一次。片段着色器对每个片段执行一次。顶点着色器的输出根据三角形基元上片段的Barycentric coordinate 进行插值,这是片段着色器的输入。