Blinn-Phong 模型

高光

接近镜面反射,即当观察方向与镜面反射方向接近时可以看到高光。

1-pzqo.webp

当观察方向接近镜面反射方向接近时,半程向量方向与法线方向接近。

半程向量

\vec{h} = bisector(\vec{v},\vec{l}) \\ = \frac{\vec{v}+\vec{l}}{||\vec{v} +\vec{l}||}
L_s = k_s(I/r^2)max(0, cos\alpha)^p \\ = k_s(I/r^2)max(0, \vec{n}\cdot\vec{h})^p

k_s:高光系数,一般为白色

2-arna.webp

指数的作用

3-wynu.webp

当半程向量与法线离的稍微远一点,即不再是高光点

指数一般用 100~200

4-irnk.webp

环境光

认为任何一个点接收到环境光的强度都是相同的,不与光源有关系,不与观测方向有关系。

环境光被认为是常数。

L_a = k_aI_a

k_a:环境光系数

5_1.webp

总结

6-fwey.webp

L = L_a + L_d + L_s \\ = k_aI_a+k_a(I/r^2)max(0,\vec{n}\cdot\vec{l})+k_s(I/r^2)max(0,\vec{n}\cdot\vec{h})^p

Shading Frequencies

7_1.webp

从左到右:着色应用于一个平面,着色应用于每个顶点,着色应用于每个像素。

Flat shading

8-xbqp.webp

每个三角形面有一个法线向量,通过叉积计算得到

缺点:表面不平滑

Gouraud shading

9-cxdc.webp

三角形每个顶点有一个法线向量,每个顶点进行一次着色

Phong shading

10-zpsy.webp

 三角形每个顶点有一个法线向量,三角形内部每个像素根据插值得到一个法线向量

顶点数的影响

11-bstv.webp

理论上 Phong shading 表现最好,复杂度最高,但实际上模型越复杂,一个三角形覆盖不了一个像素时,情况可能会变得不一样。

计算每个顶点的法线

12-fwur.webp

对顶点周围每个面的法线向量求平均(或加权平均)

\vec{N_v}=\frac{\sum_i\vec{N_i}}{||\sum_i\vec{N_i}||}

 计算逐像素法线向量

需要重心插值的知识,后续补充

13-jsgi.webp

注意:法线向量只表示方向,为单位向量

Graphics(Real-time Rendering) Pipeline

概述

14-oovg.webp

15-jexv.webp

16-kbnz.webp

17-uoih.webp

18-lxiy.webp

shading 操作发生在 Vertex Processing 和 Fragment Processing 两个阶段,对应于顶点着色和像素着色。

19-pfmm.webp

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

异构,多核的处理器

20-hgcx.webp

Texture Mapping

2D 表面

任何三维物体的表面都是 2D 的

21-sshm.webp

例子

22-ckxr.webp

模型的每个三角形在 texture 上有对应的三角形

纹理坐标可视化

23-bray.webp

三角形顶点对应一个纹理坐标,通常称为 uv 坐标

uv 在 0~1 之间

纹理可以被多次使用

24-oqze.webp

25-hqcr.webp

纹理重复的边界没有缝隙,说明纹理设计的比较好

26-cymk.webp