Blinn-Phong 模型
高光
接近镜面反射,即当观察方向与镜面反射方向接近时可以看到高光。
当观察方向接近镜面反射方向接近时,半程向量方向与法线方向接近。
半程向量
k_s:高光系数,一般为白色
指数的作用
当半程向量与法线离的稍微远一点,即不再是高光点
指数一般用 100~200
环境光
认为任何一个点接收到环境光的强度都是相同的,不与光源有关系,不与观测方向有关系。
环境光被认为是常数。
k_a:环境光系数
总结
Shading Frequencies
从左到右:着色应用于一个平面,着色应用于每个顶点,着色应用于每个像素。
Flat shading
每个三角形面有一个法线向量,通过叉积计算得到
缺点:表面不平滑
Gouraud shading
三角形每个顶点有一个法线向量,每个顶点进行一次着色
Phong shading
三角形每个顶点有一个法线向量,三角形内部每个像素根据插值得到一个法线向量
顶点数的影响
理论上 Phong shading 表现最好,复杂度最高,但实际上模型越复杂,一个三角形覆盖不了一个像素时,情况可能会变得不一样。
计算每个顶点的法线
对顶点周围每个面的法线向量求平均(或加权平均)
计算逐像素法线向量
需要重心插值的知识,后续补充
注意:法线向量只表示方向,为单位向量
Graphics(Real-time Rendering) Pipeline
概述
shading 操作发生在 Vertex Processing 和 Fragment Processing 两个阶段,对应于顶点着色和像素着色。
Shader Programs
每个 vertex 和 fragment 都会执行一次,不用写 for 循环;
对于 fragment shader(pixel shader),需要实现如何计算每个像素的颜色,并且输出。
GLSL fragment shader 程序的例子
uniform sampler2D myTexture;
uniform vec3 lightDir; // 光照方向
varying vec2 uv;
varying vec3 norm; // 法线
void diffuseShader()
{
vec3 kd;
kd = texture2d(myTexure, uv); // 漫发射系数
kd *= clamp(dot(-lightDir, norm), 0.0, 1.0);
gl_FragColor = vec4(kd, 1.0);
}
Shadertoy
https://www.shadertoy.com/
GPU
异构,多核的处理器
Texture Mapping
2D 表面
任何三维物体的表面都是 2D 的
例子
模型的每个三角形在 texture 上有对应的三角形
纹理坐标可视化
三角形顶点对应一个纹理坐标,通常称为 uv 坐标
uv 在 0~1 之间
纹理可以被多次使用
纹理重复的边界没有缝隙,说明纹理设计的比较好