850 字
4 分钟
GAMES101 Lecture 07 Z-buffering(深度缓冲) Shading(着色)

画家算法#

先画最远的物体,逐渐画近的物体,让近的物体覆盖远的物体

看起来是没问题的

但不是总生效的

这张图三个三角形互相遮挡,没办法定义深度关系,就不能采用画家算法

Z-Buffer#

既然没办法判断三角形整体的深度,那么就判断每个像素的深度

像素内记录像素深度最浅的几何

对于深度来说,越小越近,越大越远

在渲染时不光要存渲染的图,也要存一张深度的图

算法如何进行?

对单个像素来说,逐步记录深度

如先画地板,先记录地板深度

物品来了后比对物品的深度和记录的深度

发现物品深度小于记录的地板深度,说明物品要遮挡住地板

for (每个三角形 T)
for(每个 像素(x, y, z) in T)
if(z < zbuffer[x, y]) //距离小于buffer内的记录
framebuffer[x, y] = rgb; //画图
zbuffer[x, y] = z;//更新深度
else

下图一目了然

暂时假设不存在深度相同的像素

在浮点数的表示中,两个浮点数完全相同的概率很小

(实际上会有相同深度的,但本课中暂不考虑)

(透明物体Z-Buffer也处理不了,暂不考虑)

着色#

物体产生的颜色和光照、材质有关

Blinn-Phong Reflectance Model(布林·冯反射模型)#

  • 高光
  • 漫反射
  • 环境光

局部着色

对着色的描述是一个点

v、l、n都是单位向量

shininess表明有多亮(对比石膏和陶瓷)

不考虑阴影 v——观察方向 n——法线方向 l——光源方向

漫反射#

同样的光,以不同角度照上去,明暗不一样

1.物体表面法向量n,和光源方向l,的夹角θ,决定了明暗强度 可以把光当成能量,吸收的越多越亮

能量守恒#

光的能量都集中在一个球壳上,一开始球壳的表面积很小,考虑到能量守恒的话,那么单位面积上光的能量就很多,光越向外扩散,单位面积的能量就越小

(这是一个球体切面)

2.通过球面公式可以计算出,距离光源为r的球壳上,单位面积上能量为I/r²(通过能量守恒,单位距离的能量的面积 = 距离r的能力的面积)

4𝜋II = 4𝜋IrI_rIrI_r = I/r2I/r^2

根据2.就知道有多少光从光源传播到shadingPoint处

再根据1.就知道有多少光被shadingPoint吸收

这样就能知道diffuse的公式

  • I/r² 表示有多少光到达了ShadingPoint(因为光会随着传播距离而衰减)
  • kdk_d表示了该点颜色的反射率

如果kd=0k_d=0,那么该点完全没有反射光出去,该点吸收了所有光,那么该点表现为黑色

如果kd=1k_d=1,那么该点反射了所有光,那么该点表现为白色

如果用RGB三个通道表示kdk_d,那么kdk_d就是Color

  • Max0nlMax(0,n·l)表示反射角度,nl都是单位向量,nl=cosθn·l = cosθ,当入射光从表面下面照入,θ>90°,cos<0,这种情况没有意义,因为我们只考虑反射光,不考虑折射等光线,所以需要和0比,取最大值

GAMES101 Lecture 07 Z-buffering(深度缓冲) Shading(着色)
https://dingfengbo.vercel.app/posts/games101/lecture-07--z-buffering深度缓冲-shading着色/
作者
Eureka
发布于
2026-03-27
许可协议
CC BY-NC-SA 4.0