计算机图形学 – Flat Shading、Gouraud Shading、Phong Shading的区别
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:计算机图形学 – Flat Shading、Gouraud Shading、Phong Shading的区别
原文链接:https://www.stubbornhuang.com/2149/
发布于:2022年06月01日 11:11:39
修改于:2022年06月02日 10:09:52
1 Flat Shading、Gouraud Shading、Phong Shading的区别
从下图可以看出Flat Shading、Gouraud Shading、Phong Shading三种着色模型的区别,其中a为Flat Shading,b为Gouraud Shading,c为Phong Shading。
1.1 三种Shading Model的比较
1.1.1 算法的提出
Flat Shading >> Gouraud Shading >> Phong Shading
1.1.2 从简单到复杂
Flat Shading >> Gouraud Shading >> Phong Shading
1.1.3 原理上
- Flat Shading:constant surface shading,三角形的顶点没有法向量,三角形的整个面才有法向量,打光时整个三角形只呈现一种颜色;
- Gouraud Shading:color interpolation shading,三角形的各个顶点都有法向量,打光时三个顶点都有各自的颜色,然后通过双线性内插(bilinear interpolation)插值整个三角面片的颜色,这导致整个三角形会存在渐变的颜色效果;
- Phong Shading:vertex normal interpolation shading,三角形的各个顶点都有各自的法向量,先对三角形整个面做法向量的双线性内插,然后打光求整个三角形的颜色;
1.1.4 复杂度
假设三角形面积为A,三角形个数为N,打一次光需要6次乘法和2次加法和1次查表的计算量(疑惑),将打一次光的运算量设定为L,做一次双线性内插的运算设定为B,则
- Flat Shading:N * L
- Gouraud Shading:N * (3 * L+ b * A)
- Phong Shading:(B + L) * N * A
所以计算复杂度是:Flading Shading < Gouraud Shading < Phong Shading
1.1.5 三者的着色示意图如下
1.1.6 三者的GLSL shader
1.1.6.1 Gouraud Shader
vertex shader
#version 420 core
// Per-vertex inputs
layout (location = 0) in vec4 position;
layout (location = 1) in vec3 normal;
// Matrices we'll need
layout (std140) uniform constants
{
mat4 mv_matrix;
mat4 view_matrix;
mat4 proj_matrix;
};
// Light and material properties
uniform vec3 light_pos = vec3(100.0, 100.0, 100.0);
uniform vec3 diffuse_albedo = vec3(0.5, 0.2, 0.7);
uniform vec3 specular_albedo = vec3(0.7);
uniform float specular_power = 128.0;
uniform vec3 ambient = vec3(0.1, 0.1, 0.1);
// Outputs to the fragment shader
out VS_OUT
{
vec3 color;
} vs_out;
void main(void) {
// Calculate view-space coordinate
vec4 P = mv_matrix * position;
// Calculate normal in view space
vec3 N = mat3(mv_matrix) * normal;
// Calculate view-space light vector
vec3 L = light_pos - P.xyz;
// Calculate view vector (simply the negative of the
// view-space position)
vec3 V = -P.xyz;
// Normalize all three vectors
N = normalize(N);
L = normalize(L);
V = normalize(V);
// Calculate R by reflecting -L around the plane defined by N
vec3 R = reflect(-L, N);
// Calculate the diffuse and specular contributions
vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo;
vec3 specular = pow(max(dot(R, V), 0.0), specular_power) *
specular_albedo;
// Send the color output to the fragment shader
vs_out.color = ambient + diffuse + specular;
// Calculate the clip-space position of each vertex
gl_Position = proj_matrix * P;
}
fragment shader
#version 420 core
// Output
layout (location = 0) out vec4 color;
// Input from vertex shader
in VS_OUT
{
vec3 color;
} fs_in;
void main(void)
{
// Write incoming color to the framebuffer
color = vec4(fs_in.color, 1.0);
}
1.1.6.2 Phong Shader
vertex shader
#version 420 core
// Per-vertex inputs
layout (location = 0) in vec4 position;
layout (location = 1) in vec3 normal;
// Matrices we'll need
layout (std140) uniform constants
{
mat4 mv_matrix;
mat4 view_matrix;
mat4 proj_matrix;
};
// Inputs from vertex shader
out VS_OUT
{
vec3 N;
vec3 L;
vec3 V;
} vs_out;
// Position of light
uniform vec3 light_pos = vec3(100.0, 100.0, 100.0);
void main(void) {
// Calculate view-space coordinate
vec4 P = mv_matrix * position;
// Calculate normal in view-space
vs_out.N = mat3(mv_matrix) * normal;
// Calculate light vector
vs_out.L = light_pos - P.xyz;
// Calculate view vector
vs_out.V = -P.xyz;
// Calculate the clip-space position of each vertex
gl_Position = proj_matrix * P;
}
fragment shader
#version 420 core
// Output
layout (location = 0) out vec4 color;
// Input from vertex shader
in VS_OUT
{
vec3 N;
vec3 L;
vec3 V;
} fs_in;
// Material properties
uniform vec3 diffuse_albedo = vec3(0.5, 0.2, 0.7);
uniform vec3 specular_albedo = vec3(0.7);
uniform float specular_power = 128.0;
void main(void)
{
// Normalize the incoming N, L, and V vectors
vec3 N = normalize(fs_in.N);
vec3 L = normalize(fs_in.L);
vec3 V = normalize(fs_in.V);
// Calculate R locally
vec3 R = reflect(-L, N);
// Compute the diffuse and specular components for each
// fragment
vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo;
vec3 specular = pow(max(dot(R, V), 0.0), specular_power) *
specular_albedo;
// Write final color to the framebuffer
color = vec4(diffuse + specular, 1.0);
}
参考链接
当前分类随机文章推荐
- 常用的三维图形库以及软件所使用的坐标系以及旋转正方向 阅读3427次,点赞0次
- 默认的左手坐标系与右手坐标系的比较 阅读4152次,点赞2次
- 书籍翻译 - Cloth Simulation for Computer Graphics,Abstract中文翻译 阅读573次,点赞0次
- 书籍翻译 – Fundamentals of Computer Graphics, Fourth Edition,第6章 Transformation Matrices中文翻译 阅读1742次,点赞7次
- 计算机图形学 - 三维空间中的左、右手坐标系旋转矩阵与旋转变换 阅读8373次,点赞4次
- 左手坐标系与右手坐标系 阅读3221次,点赞0次
- 计算机图形学 - Flat Shading、Gouraud Shading、Phong Shading的区别 阅读973次,点赞0次
- 书籍翻译 - Fundamentals of Computer Graphics, Fourth Edition,第1章 Introduction中文翻译 阅读4825次,点赞17次
- 计算机图形学 - 常用的3D数学知识备忘,如三角函数、向量运算、矩阵运算、图形学常用的平移缩放旋转矩阵,视图矩阵,投影矩阵 阅读1347次,点赞4次
- 矩阵 - 行主序矩阵与列主序矩阵 阅读4044次,点赞0次
全站随机文章推荐
- 多进程之间常用的通信方式 阅读131次,点赞0次
- Python - 使用scikit-video库获取视频的旋转角度并使用opencv_python根据旋转角度对视频进行旋转复原 阅读3139次,点赞1次
- 资源分享 - 深度学习之PyTorch实战计算机视觉 (唐进民著) 高清PDF下载 阅读2080次,点赞0次
- C++11 - std::string - stod/stof/stoi/stol/stold/stoll/stoul/stoull,由std::string转换为int/long/float/double等其他类型 阅读3555次,点赞0次
- Pytorch - torch.optim优化器 阅读691次,点赞0次
- 计算机图形学 - 如何选择合适的图形API 阅读1485次,点赞0次
- 资源分享 - Game AI Pro 360 - Guide to Character Behavior 英文高清PDF下载 阅读1658次,点赞0次
- Python - 普通函数/lambda匿名函数/类成员函数作为回调函数的用法 阅读2064次,点赞0次
- TensorRT - 使用trtexec工具转换模型、运行模型、测试网络性能 阅读3816次,点赞2次
- 并发与并行的概念和区别 阅读237次,点赞0次
评论
169