用Java画光

在知乎上关注了图形学大佬叶劲峰 (Milo Yip),他的博客是 https://www.cnblogs.com/miloyip/ 。前一段时间我尝试使用Java开发一个软光栅渲染器,核心思路就是他早期在知乎上的一个回复:Milo Yip:如何开始用 C++ 写一个光栅化渲染器?

这位大佬最近在知乎专栏发布了一个系列教程:《用C语言画光》,在2D空间中阐释了光线追踪算法的原理。

我一口气读完了七篇文章,感觉收获很大。跟着他的脚步用C语言实现了这些算法后,意犹未尽,又用Java重新做了一遍。

项目代码已经上传到了github:jmecn/JLight2D


用Java画光,根据“用C语言画光”项目翻译而来。miloyip/light2d

GUI

该项目本身是标准C语言控制台项目,我用Swing做了一个简单的界面,用来配置渲染参数。

基础

使用蒙特卡洛积分(Monte Carol integration)和基于带符号距离场(signed distance field, SDF)的光线渐进(Ray marching)算法,渲染一个发光的圆。

源代码:

标准(Uniform)采样 (每个像素采样64次):

分层(Stratified)采样 (每个像素采样64次):

抖动(Jittered )采样 (每个像素采样64次):

构造实体几何

源代码 : RayTracing1Csg.java

使用交、并、差等集合操作,构造多种几何模型:

反射

源代码 : RayTracing2Reflection.java

根据Csg表面的梯度计算法线方向,进而计算光的反射方向。假设物体表面的反射率是均匀的。

折射

源代码 : RayTracing3Refraction.java

应用斯涅耳定律计算光在不同介质中的折射方向。同时也处理了全反射。

菲涅耳反射

源代码 : RayTracing4Fresnel.java

应用菲涅耳公式计算光在电介质表面的反射方向。

未应用菲涅耳公式:

应用菲涅耳公式:

比尔-朗伯定律

源代码 : RayTracing5Absorption.java

应用比尔-朗伯定律模拟光在电在传播过程中被介质吸收。

如果用去噪算法来对生成的图像滤波,渲染质量应该会更高。

期待大佬接下来的教程。