0 我们已经学了什么 What We’ve Covered So Far
- 空间中定义了一个摄像机,通过某些变换使模型摆好姿势(Model)
- 通过观测变换让摄像机放在原点,得到标准的 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3立方体空间(View)
- 通过视口变换将三维模型投影到二维的屏幕上(Projection)
- 通过采样对屏幕空间中结果进行光栅化(Rasterization)
1 着色的定义 Shading:Definition
- 字典中的定义:通过平行线或色块在插画、图像上加深或上色 The darkening or coloring of an illustration or diagram with parallel lines or a block of color
- 在本课程中的定义:对不同的物体应用不同的材质 The process of applying a material to an object
2 一种简单的模型:Blinn-Phong反射模型 A Simple Shading Model (Blinn-Phong Reflectance Model)
Blinn-Phong模型是经验模型,与现实相比仍有很多不足
2.1 感性观察 Perceptual Observations
- 高光(Specular highlights):光滑表面镜面反射处附近形成高光
- 漫反射(Diffuse reflection):在整个杯子上变化比较柔和,粗糙表面形成漫反射
- 环境光(Ambient lighting):上图中背光处仍然有颜色,因为其接受了周围环境的间接光照,为了简化模型,我们会使用一个环境光常量来表示环境光对物体的影响
2.2 着色具有局部性 Shading is Local
-
着色点(Shading point)在局部上是一个平面,在这个平面上定义:
- 观看方向v(Viewer direction)
- 法线方向n(Surface normal)
- 光照方向l(Light direction)
- 表面参数颜色、光泽度等(Surface parameters color, shininess, …)
-
着色过程不包括阴影的生成 No shadows will be generated! (shading ≠ shadow)
2.3 漫反射 Diffuse Reflection
-
定义:光线打到某一点后,光线均匀的向各个方向散射,表面的颜色在各个观察方向都相同 Light is scattered uniformly in all directions, surface color is the same for all viewing directi
-
多少光被接受与面和光线的夹角有关,根据兰伯特余弦定理(Lambert’s cosine law),单位面积上接收到的光的能量的能量等于光线与法线夹角的余弦
- 太阳能板在板面垂直于光照接受光能最大
- 地理上冬夏之分与光线照射方向与地面夹角有关(太阳高度角)
-
从光在传播中的衰减 Light Falloff
- 从能量守恒的角度来看,单位面积上光的强度与距离的平方成反比
- 从能量守恒的角度来看,单位面积上光的强度与距离的平方成反比
-
兰伯特(漫反射)着色 Lambertian (Diffuse) Shading
2.4 镜面反射 Specular Term (Blinn-Phong)
- 高光的强度取决于观察方向,观察方向与镜面反射方向接近时能看见高光 Intensity depends on view direction, b right near mirror reflection direction
- 观察方向v与镜面反射方向接近说明半程向量h与法线n接近(这样计算更加高效) V close to mirror direction ⇔ half vector near normal
- 在Blinn-Phong模型中镜面反射忽略了计算着色点吸收能量的比例
- 使用观察方向和镜面反射方向判断是否接近是Phong模型
- 增加p的值来限制高光范围(小高光p大约在100到200)
2.5 环境光 Ambient Term
- 环境光会照亮每一点,与直接光照方向,观察方向都无关,是一个常数 Shading that does not depend on anything, add constant color to account for disregarded illumination and fill in black shadows
- 这是一个非常大胆的简化 This is approximate / fake!
2.6 Blinn-Phong反射模型 Blinn-Phong Reflection Model
L = L a + L d + L s = k a I a + k d ( I / r 2 ) m a x ( 0 , n ⋅ l ) + k s ( I / r 2 ) m a x ( 0 , n ⋅ h ) p L =L_a+L_d+L_s =k_aI_a+k_d(I/r^2)max(0, n·l)+k_s(I/r^2)max(0, n·h)^p L=La+Ld+Ls=kaIa+kd(I/r2)max(0,n⋅l)+ks(I/r2)max(0,n⋅h)p
3 着色频率 Shading Frequencies
3.1 逐三角形着色 Shade each triangle (flat shading)
- 每个三角形内部着色没有变化,一个平面一个法向量 Triangle face is flat — one normal vector
- 对于平滑的表面表现不是很理想 Not good for smooth surfaces
3.2 逐顶点着色 Shade each vertex (Gouraud shading)
- 从三角形的顶点插入颜色 Interpolate colors from vertices across triangle
- 每个顶点都有一个法线向量 Each vertex has a normal vector
- 定点外其余部分的颜色通过插值计算出来
3.3 逐像素着色 Shade each pixel (Phong shading)
- 在每个三角形上插入法线向量 Interpolate normal vectors across each triangle
- 在三角形内部每个像素都插值出一个法线方向,计算每个像素的完整着色模型 Compute full shading model at each pixel
- 不是Blinn-Phong反射模型(只是名字上撞了,不是一回事) Not the Blinn-Phong Reflectance Model
3.4 几种着色频率的对比 Shading Frequenciesy: Face, Vertex or Pixel
- 在模型几何较为复杂时,用简单的逐像素模型也能得到不错的效果,并且开销小
- 在模型几何较为简单时,逐像素效果更好,但性能要求高一些
3.5 定义逐顶点的法线 Defining Per-Vertex Normal Vectors
-
如果知道具体表示的几何体是什么样的,例如用多个顶点表示球体,则每个顶点的法线方向即为球心向顶点连线的方向 Best to get vertex normals from the underlying geometry, e.g. consider a sphere
-
否则必须从相邻三角形面推断出顶点法线,一个简单的方法是求相邻面法线的平均法线
-
根据相邻面的面积使用加权平均会得到更好的效果
3.6 定义逐像素的法线 Defining Per-Pixel Normal Vectors
- 使用顶点法线的重心插值 Barycentric interpolation of vertex normals
- 不要忘记对插值方向进行归一化 Don’t forget to normalize the interpolated directions
4 图形(实时渲染)管线 Graphics (Real-time Rendering) Pipeline
4.1 图形(实时渲染)管线 Graphics (Real-time Rendering) Pipeline
- 模型、观测、投影变换(Model, View, Projection transforms):Vertex Processing
- 采样三角区的覆盖范围(Sampling triangle coverage):Rasterization
- 深度缓冲可见性测试(Z-Buffer Visibility Tests):Fragment Processing
- 着色和纹理贴图(Shading, Texture mapping):Vertex Processing & Fragment Processing
4.2 着色器程序 Shader Programs
- 描述了顶点和片元处理过程的操作 Program vertex and fragment processing stages
- 着色器会对每个顶点或片元执行一次,只写出单次操作即可 Shader function executes
once per fragment. - 例如,以下是一段GLSL语言的片元着色器 Example GLSL fragment shader program
uniform sampler2D myTexture; //全局变量 固定的纹理
uniform vec3 lightDir; //全局变量 固定的光照方向
varying vec2 uv; //每个片元插值得到的uv坐标
varying vec3 norm; //每个片元插值得到的法线方向
void diffuseShader()
{
vec3 kd; //Eigen库定义三维向量kd
kd = texture2d(myTexture, uv); //进行纹理查找以获取此时表面材质颜色
kd *= clamp(dot(–lightDir, norm), 0.0, 1.0); //漫反射系数、光照都为常数的最简单的漫反射
gl_FragColor = vec4(kd, 1.0); //将得到的值返回到gl_GragColor
}
- 练习shader:https://www.shadertoy.com
5 当下实时渲染的发展
5.1 目标:实时高度复杂的 3D 场景 Goal: Highly Complex 3D Scenes in Realtime
- 一个场景中有数百到数百万个三角形 100’s of thousands to millions of triangles in a scene
- 复杂的顶点和片段着色器计算 Complex vertex and fragment shader computations
- 高分辨率(200-400万像素+超采样)High resolution (2-4 megapixel + supersampling)
- 每秒 30-60 帧(VR 甚至更高)30-60 frames per second (even higher for VR)
5.2 用于执行图形管线的硬件:GPU Graphics Pipeline Implementation: GPUs
- GPU分为独立显卡(Discrete GPU Card)与集成显卡(Integrated GPU)
- 学过高性能计算的话,会知道GPU的并行度高,适合处理图形学的相关计算
6 纹理映射 Texture Mapping
6.1 纹理是二维的图像 Surfaces are 2D
- 纹理映射的根本作用是定义物体表面任何一点的不同属性
- 每个三维物体表面上的一个点在2D图像中对应一个位置 Every 3D surface point also has a place
where it goes in the 2D image (texture)
6.2 纹理映射 Texture Applied to Surface
-
定义纹理坐标uv(u, v约定俗成范围0~1)、将纹理映射到表面的过程
-
纹理可以被重复使用多次,当纹理是四方连续时可以无缝衔接(tiled),其中一种算法是Wang Tiling
7 重心坐标插值 Interpolation Across Triangles: Barycentric Coordinates
7.1 为什么要进行插值 Why do we want to interpolate?
- 为了在三角形内部得到平滑的过渡 Obtain smoothly varying values across triangles
- 纹理坐标、颜色、向量的插值等属性都可以插值 Texture coordinates, colors, normal vector
7.2 重心坐标 Barycentric Coordinates
7.2.1 什么是重心坐标 What’s the barycentric coordinate of A?
- 三角形所在平面上任意一点都可以用三个顶点坐标的线性组合来表示
- 任意一点可以通过重心坐标表示为 ( α , β , γ ) (\alpha,\beta,\gamma) (α,β,γ)
- 如果 α , β , γ \alpha,\beta,\gamma α,β,γ都是非负的,则该点在三角形内 Inside the triangle if all three coordinates are non-negative
- 例如,A点的坐标为(1, 0, 0)
( x , y ) = α A + β B + γ C , α + β + γ = 1 (x,y)=\alpha A+\beta B+\gamma C,\quad\alpha+\beta+\gamma=1 (x,y)=αA+βB+γC,α+β+γ=1
7.2.2 利用面积确定系数 Geometric viewpoint — proportional areas
α = A A A A + A B + A C , β = A A A A + A B + A C , γ = A A A A + A B + A C \alpha = \frac { A _ { A } } { A _ { A } + A _ { B } + A _ { C } },\quad \beta = \frac { A _ { A } } { A _ { A } + A _ { B } + A _ { C } },\quad \gamma = \frac { A _ { A } } { A _ { A } + A _ { B } + A _ { C } }