Skip to content

Repository files navigation

计算机图形学 实验四:Phong与Blinn-Phong光照模型实现

课程名称 计算机图形学
学生姓名 王若涵
专业班级 2024级计算机科学与技术
实验环境 Taichi (v1.7.4, Metal), Python 3.12

🌟 实验核心亮点与进阶工作说明

本次实验不仅完成了基础的隐式几何体光线求交与标准Phong模型,还主动探索并实现了多项进阶技术:

  1. 系统级模块化重构:规避了单文件面条式代码,设计了config.py(参数栈)、geometry.py(数学引擎)和main.py(渲染主循环)的清晰工程架构。
  2. 算法拓展 (选做项100%达成):完整实现了基于半程向量的Blinn-Phong优化模型 与处理自遮挡的硬阴影(Hard Shadow) 技术。
  3. 空间逻辑与物理正确性修正:针对默认坐标系下“阴影投射入虚空”导致遮挡关系缺失的问题,自主推导并增加了一个隐式地平面(Ground Plane),构建了完整的局部光照物理闭环。

1. 实验背景与目标

局部光照模型(Local Illumination)是计算机图形学中实现真实感渲染的基石。相较于全局光照,局部光照通过经验公式极大地简化了光子弹射的计算复杂度。本次实验的核心目标包括:

  1. 构建三维视界:熟练掌握光线投射(Ray Casting)技术,利用纯解析几何方程在三维空间中定义隐式表面。
  2. 驾驭光照算法:深入剖析并实现Phong 光照模型,理解环境光、漫反射、镜面高光的物理意义及其向量运算。
  3. 并行计算实践:基于Taichi编译器在GPU端实现每像素级的高并发渲染,并打通前端UI与底层Shader参数的实时交互链路。

2. 核心数学模型与算法推导

2.1 光线投射与隐式表面求交

在不依赖多边形网格(Mesh)的情况下,场景几何通过解析方程定义。设摄像机发出的射线方程为 $P(t) = O + t\mathbf{D}$(其中 $O$ 为原点, $\mathbf{D}$ 为归一化方向向量)。

  • 球体求交推导: 球体表面方程为 $(P - C) \cdot (P - C) = R^2$。代入射线方程,展开得到关于 $t$ 的一元二次方程: $$(\mathbf{D} \cdot \mathbf{D})t^2 + 2\mathbf{D} \cdot (O - C)t + (O - C) \cdot (O - C) - R^2 = 0$$ 计算判别式 $\Delta = b^2 - 4ac$,若 $\Delta \ge 0$,则取最小正根作为交点距离。
  • 圆锥面求交与裁剪: 圆锥顶点为 $V(x_v, y_v, z_v)$,基于相似三角形原理,其侧面隐式方程为 $(x-x_v)^2 + (z-z_v)^2 = (y-y_v)^2 \tan^2\alpha$。求解出 $t_1, t_2$ 后,由于圆锥在垂直方向并非无限延伸,必须在 $y \in [y_{min}, y_v]$ 范围内对根进行高度裁剪(Clipping),剔除无效解。

2.2 深度测试 (Z-buffer) 与遮挡处理

为保证物体间正确的空间前后遮挡关系,在render核函数中维护了一个局部的min_t变量。当一根射线先后与球体、圆锥及地平面均产生正数交点时,算法仅保留$t$值最小(距离摄像机最近)的材质属性与法向量进入着色阶段。

2.3 局部光照经验模型对比

最终像素颜色由环境光、漫反射、镜面高光线性叠加:$I = I_a + I_d + I_s$。

  • 标准Phong模型:高光强度依赖于理想反射向量 $\mathbf{R} = 2(\mathbf{N} \cdot \mathbf{L})\mathbf{N} - \mathbf{L}$ 与视线向量 $\mathbf{V}$ 的夹角: $$I_{s} = K_s \cdot \max(0, \mathbf{R} \cdot \mathbf{V})^{shininess} \cdot C_{light}$$
  • 【选做】Blinn-Phong 改进模型: 由于计算反射向量 $\mathbf{R}$ 计算开销较大,且在大入射角(掠射角)时 $\mathbf{R} \cdot \mathbf{V} < 0$ 会导致高光突兀截断。Blinn-Phong 引入了光源 $\mathbf{L}$ 和视线 $\mathbf{V}$ 的半程向量 $\mathbf{H}$$$\mathbf{H} = \frac{\mathbf{L} + \mathbf{V}}{|\mathbf{L} + \mathbf{V}|}, \quad I_{s(Blinn)} = K_s \cdot \max(0, \mathbf{N} \cdot \mathbf{H})^{shininess} \cdot C_{light}$$ 该优化不仅提升了计算效率,更使高光边缘的滚降(Falloff)更加平滑自然。

2.4 【选做】二次射线检测与硬阴影

当光线击中物体表面点 $P$ 后,向光源方向 $\mathbf{L}$ 发射阴影探测射线(Shadow Ray)。若该射线在到达光源之前与其他几何体相交,则 $P$ 处于本影区。 浮点精度修正:为避免射线在发射瞬间因浮点误差与自身表面相交而产生满屏的“阴影痤疮(Shadow Acne)”,沿法向引入了微小偏移量 $\epsilon = 1e^{-4}$$$Ray_{shadow} = P + \epsilon \cdot \mathbf{N} + t \cdot \mathbf{L}$$

3. 实验重难点与工程踩坑记录

  1. Taichi 编译器动态作用域限制: 在编写圆锥求交时,曾尝试使用 for t in [t1, t2]: 遍历求根结果,触发了 TaichiCompilationError。查阅底层文档发现,Taichi 的 GPU JIT 编译器在 @ti.func 装饰器内不支持原生 Python 列表的动态遍历。最终通过显式展开分支逻辑(Manual Loop Unrolling)成功解决,同时消除了分支预测的开销。
  2. 空间视觉错觉与阴影接收面的重构: 在初步实现硬阴影后,画面并未出现遮挡效果。经空间三维推演,光源位于 $(2, 3, 4)$,导致圆锥产生的投影全部射向了背景虚空。为严谨验证阴影算法,我重写了场景布局,引入了一个 $y = -1.4$ 的无穷大地平面作为阴影接收器。这一改动让光、遮挡物、投影面形成了完整的物理闭环,完美呈现了多物体的交互光影。

4. 实验结果与视觉分析

(注:以下为实验渲染截图,参数均为实时 UI 调整所得)

4.1 UI 控制与材质特性分析

必做调参demo

分析:通过滑动 UI 参数发现,环境光系数(Ka)直接决定了场景暗部的基调亮度;漫反射系数(Kd)决定了物体表面的哑光质感;而高光指数(Shininess)越大,光斑越聚焦,材质越显得光滑锐利。

4.2 Phong 与 Blinn-Phong 高光形态对比

选做Blinn-Phong demo

分析:在相同的 Shininess=32 参数下,Blinn-Phong 模型的高光光晕比标准 Phong 模型更圆润,特别是在球体边缘处,Blinn-Phong 保持了更加连贯的物理拖影,未出现突兀的割裂感。

4.3 物理场景渲染(硬阴影与地平面)

选做shadow demo

分析:引入二次光线求交与地面接收平面后,场景的空间纵深感大幅增强。阴影边缘清晰,且自遮挡 Bias 处理得当,未出现表面伪影。

5. 延伸与体会

1、本次实验从零推导并实现了基于光线投射的局部光照流水线。在纯代码层面构建隐式曲面、处理深度竞争、计算法向与光强叠加的过程中,我深刻体会到了将抽象代数公式转化为具象像素视觉的魅力。

2、这次底层图形渲染逻辑的实践具有很强的知识迁移价值。光线投射中的射线求交与深度测试思想,与处理 RGB-D 传感器的空间深度映射、点云剔除算法在本质上是同构的;而利用 Taichi 构建高并发渲染循环和状态同步引擎,也为我后续在设计、搭建支持多用户协同的虚拟空间(如高保真的虚拟物理实验室)时,提供了极其坚实的数学直觉与底层系统开发经验。图形学不仅是“画图”,更是对多维数据进行高能效计算的系统工程。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages