Skip to content
RayTracing and Progressive Photon Mapping
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
configures
core
display
eigen @ 7cf1c01
glog @ abce788
jsoncpp @ c4103ab
materials
objects
render
results
samples
.DS_Store
.gitignore
.gitmodules
.ycm_extra_conf.py
CMakeLists.txt
README.md
README.pdf
linux.toolchain.cmake
main.cpp
serial.cpp

README.md

图形学大作业实验报告

计62 毛晗扬 2016011275

结果图

工程介绍

工程信息

github地址:RayTracing-ProgressivePhotonMaping

详细教程地址:教程地址

编译命令

cmake -DCMAKE_CXX_COMPILER=/usr/local/bin/clang-omp++ -DCMAKE_C_COMPILER=/usr/local/bin/clang-omp ..

*/usr/local/bin/clang-omp 是一个支持-fopenmp的g++编译器

文件目录

./core 核心结构,如颜色类,向量类,物体基类等 ./objects 自定义物体 ./render 自定义渲染算法 ./display 实时渲染进度输出 ./materials 贴图材质目录 ./result 所有结果目录

得分点

  • 光线追踪算法(RayTracing)[render/raytracing.cpp]
  • 基于路径hash的抗锯齿算法[render/raytracing.cpp:123]
  • 渐进式光子映射算法(ProgressivePhotonMapping)[render/progressive_photon_mapping.cpp]
  • OpenMP性能加速[render/progressive_photon_mapping.cpp:57]
  • 包围盒加速[objects/bazier_curve.cpp:36]
  • KD树加速[render/progressive_photon_mapping.cpp:78]
  • 分段贝塞尔曲线[objects/bazier_curve.cpp]
  • 物体贴图[core/texture.cpp]
  • 景深[core/camera.cpp:23]

性能加速

在程序中使用了openmp加速,如并行多行渲染:

算法加速

包围盒

在贝塞尔曲线求交期间,通过圆柱体包围盒,优先判断光线是否与包围盒有交点。

KD树

在光线追踪部分,我使用KD树寻找距离小于R的碰撞点。KD树本身使用基于轮换分割维度建树的方式。

光线追踪

普通的光线追踪算法支持反射折射等基本情形。

通过路径hash可以有效减少边缘锯齿效应。

贝塞尔曲线求交

由于本身希望做一个类似于沙漏、水杯这类东西,这是一个一维贝塞尔曲线绕指定轴旋转而成的,我们需要得到光线与曲面的交点信息。

四维贝塞尔曲线$P(u)$通过4个控制点定义,坐落于2维平面上

$$ P(u) = \left[ \matrix{P_x(u) \ P_y(u)} \right] = \left[ \matrix{ \sum _{i=0}^n P_i^{(x)} (1-u)^{n-i}u^i \ \sum _{i=0}^n P_i^{(y)} (1-u)^{n-i}u^i } \right] $$

$$ \frac{dP}{du} = n \sum_{i=0}^{n-1} P_i (B_{i-1,n-1}(u) - B_{i,n-2}(u)) $$

设光线为$C(t)$,曲面为$S(u,\theta)$

$$ C(t) = \left[ \matrix{ O_x + t D_x \ O_y + t D_y \ O_z + t D_z \ } \right] $$

$$ S(u,\theta) = \left[ \matrix{ Q_x + sin\theta P_x(u) \ Q_y + cos\theta P_x(u) \ Q_z + P_y(u) } \right] $$

分别对于$C(t)$,$S(u,\theta)$求导

$$ \frac{dC}{dt} = \left[ \matrix{D_x \ D_y \ D_z}\right] $$

$$ \frac{\partial S}{\partial u} = \left[ \matrix{ sin\theta \frac{d{P_x}}{d{u}} \ cos\theta \frac{d{P_x}}{d{u}} \ \frac{\partial{P_y}}{\partial{u}} } \right] $$ $$ \frac{\partial S}{\partial \theta} = \left[ \matrix{ cos\theta P_x(u) \ -sin\theta P_x(u) \ 0 } \right] $$

最小化$F(u,\theta,t) = C(t) - S(u,\theta)$

显然 $$ \frac{\partial F}{\partial t} = \left[ \matrix{ \frac{\partial F_1}{\partial t} & \frac{\partial F_1}{\partial u} & \frac{\partial F_1}{\partial \theta} \ \frac{\partial F_2}{\partial t} & \frac{\partial F_2}{\partial u} & \frac{\partial F_2}{\partial \theta} \ \frac{\partial F_3}{\partial t} & \frac{\partial F_3}{\partial u} & \frac{\partial F_3}{\partial \theta} \ } \right] $$

$$ \frac{\partial F}{\partial t} = \left[ \matrix{ D_x & sin\theta \frac{dP_x}{du} & cos\theta P_x(u)\ D_y & cos\theta \frac{dP_x}{du} & -sin\theta P_x(u)\ D_z & \frac{dP_y}{du} & 0\ } \right] $$ 其中

$$ \frac{dP}{du} = n \sum_{i=0}^{n-1} P_i (B_{i-1,n-1}(u) - B_{i,n-2}(u)) $$

将通过牛顿迭代,我们可以计算出F函数的零点,其中有两点需要注意的地方

  • 牛顿迭代需要保证答案中$u \in [0,1]$,而牛顿迭代本身无法附加条件,因此需要在答案的邻域中查找合适的$u$,$t$,$\theta$,我用到的方法是,对于给定曲线,生成一个圆柱体包含框,随机该圆柱体里面高度$h$的一个圆形面片,将光线与该面片的交点的$u$,$t$,$\theta$作为迭代的初值。随机$h$约30次即可得解。

  • 由于牛顿迭代不太精确,可能是的结果产生微小偏移,这种偏移会对判断点在平面哪一侧产生影响,我们可以通过调整eps的取值,不同部分赋予不同的eps,使得这些误差不至于相互影响。

曲线控制点为

纹理贴图

所有贴图可以在./materials里面找到。

景深

在场景中设置了一个对焦错误的球体供参考,核心思路为修改相机类,使得非聚焦位置的物体接收到的光线有较大的随机误差偏移,进而产生景深的模糊效果。

You can’t perform that action at this time.