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);
}
Run Code Online (Sandbox Code Playgroud)
事实证明,Phong 在低多边形物体上看起来更平滑一些。因此,知识障碍基本上在于片段如何获得着色器。首先让我们看看learnopenGL已经提供了哪些精彩资源。
总之,它告诉我们在顶点处提供的颜色值是在由顶点构成的片段的边界内插值的。因此,这非常有意义,就像对构成顶点的颜色采取加权平均值之类的方法一样。
但是,就像Phong 着色模型一样,计算是在片段着色器中完成的,会发生什么?片段像素如何着色?假设有三个顶点,那么片段是否用第一种颜色完全着色,用第二个颜色完全着色,然后用第三个颜色完全着色,并且是所取颜色的总中位数还是什么?在片段着色器中计算时片段是如何着色的?
Phong an Gouraud 着色之间的区别在于:
在高多边形网格上,两者都给出非常接近的结果,因为每个三角形颜色的色散变得更小。
在低多边形网格上,在Gouraud中平均阴影颜色会产生更差的视觉效果,因为平均颜色几乎没有物理意义。
Phong着色中的平均法线可模拟平滑的表面属性,因此它们的平均可能接近甚至匹配原始分析表面定义,从而产生更加合理和平滑的视觉结果。
平均不是由着色器程序本身完成的,而是由顶点和片段着色器阶段之间的固定硬件功能完成的。因此,当您在“顶点着色器”中计算颜色或传递法线/UV 坐标等时,这些值将由硬件根据片段重心坐标在三角形内所有片段的 3 个顶点之间进行插值。
片段着色器中计算的颜色是最终颜色(在应用混合或模板测试之前,这也是由固定硬件功能完成的)。因此,将光照计算放入片段着色器的顶点中定义了将插值的内容以及直接计算的内容。
| 归档时间: |
|
| 查看次数: |
3148 次 |
| 最近记录: |