用Java画光
在知乎上关注了图形学大佬叶劲峰 (Milo Yip),他的博客是
https://www.cnblogs.com/miloyip/ 。前一段时间我尝试使用Java开发一个软光栅渲染器,核心思路就是他早期在知乎上的一个回复:Milo Yip:如何开始用 C++ 写一个光栅化渲染器?。
这位大佬最近在知乎专栏发布了一个系列教程:《用C语言画光》,在2D空间中阐释了光线追踪算法的原理。
- 用 C 语言画光(一):基础
- 用 C 语言画光(二):构造实体几何
- 用 C 语言画光(三):形状
- 用 C 语言画光(四):反射
- 用 C 语言画光(五):折射
- 用 C 语言画光(六):菲涅耳方程
- 用C语言画光(七):比尔-朗伯定律
我一口气读完了七篇文章,感觉收获很大。跟着他的脚步用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
应用比尔-朗伯定律模拟光在电在传播过程中被介质吸收。
如果用去噪算法来对生成的图像滤波,渲染质量应该会更高。
期待大佬接下来的教程。