Lite Spectral Renderer(以下简称LSR)是一个用于个人学习与研究的轻量化光线追踪渲染器。它由精简的核心代码库和一系列模块组成。这些模块独立实现了光传输过程中的各个部分,如材质、采样器、积分器、相机等。渲染器首先解析场景文件,动态加载所需的各个模块,然后使用 CPU 并行渲染得到结果图像。目前,LSR 搭建了求解光传输方程的基本框架,并实现所需的基本模块。随着后续研究的深入,还将增加更多模块与功能实现。
LSR 依赖 CMake (3.1+)生成编译文件,并使用 GCC 12 编译器。在 Windows 平台上执行如下命令
cmake -G "MinGW Makefiles" -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=path/to/gcc.exe -DCMAKE_CXX_COMPILER=path/to/g++.exe生成的 Makefile 文件位于 build/ 内。进入该目录执行 make,将生成核心库程序(lsr.exe),并编译各个模块为动态库,存放于 bin/ 目录。
cd build
makeLSR 理论支持在 Linux 编译,但尚未经过测试。
渲染器程序通过命令行使用,其中第一个参数为场景文件路径;第二个为可选参数,指定渲染结果输出路径,未指定时将输出到场景文件相同文件夹下。
注:实际输出文件的后缀名,由场景文件中描述使用的相机底片模块决定。 例如,使用 hdr 模块时,默认输出 exr 格式的图片。
cd bin
lsr path/to/scene.xml path/to/output场景文件格式详见最后一节。
三个样例场景的描述文件位于 example 目录下。RGB 模式下,使用 path tracer 积分器,各采样数的渲染结果如下所示,渲染用时均在仅启用 8 个线程的 AMD R5 3600 上测得。
cornell-box, 1024*1024, 235K triangles
| 16 spp, 17.4s | 256 spp, 273s | 4096 spp, 4214s |
|---|---|---|
![]() |
![]() |
![]() |
为了验证 LSR path tracer 的无偏性,与 mitsuba3 的渲染结果进行了对比。误差集中于光源边缘采样部分,而性能差距主要在于 mitsuba3 使用了加速指令集。
mitsuba3, 4096 spp, 2187s (scalar mode) difference image 绝对误差直方图分布如下,平均值为0.004。
veach-mis, 1280*720, 2332 triangles
| 16 spp, 4.53s | 256 spp, 72.5s | 4096 spp, 1154s |
|---|---|---|
![]() |
![]() |
![]() |
staircase, 1280*720, 31.4K triangles
| 16 spp, 17.2s | 256 spp, 268s | 4096 spp, 4165s |
|---|---|---|
![]() |
![]() |
![]() |
LSR 在设计架构上等同于一个精简版的 mitsuba,主要实现了核心的模块化特性。每种模块负责渲染器中的一个特定部分,例如,采样器负责生成样本,相机模块负责生成光线,积分器模块负责在场景中生成完整的光路径,并计算其辐射度贡献。同类型的模块有统一的 API 接口,但实现各不相同,比如相机的实现就有透视相机和正交相机等。
场景描述文件指定了各模块使用何种具体实现,LSR 解析场景时,将动态加载所需的模块。这样做的好处是,后续研究新模块实现时,只需编译单个模块为动态库,无需重新编译整个渲染器。
LSR 已实现的模块有
- bsdf:散射模型
- dielectric:电介质(如玻璃)反射模型
- phong:Blinn-Phong 反射模型
- camera:相机
- perspective:透视针孔相机
- emitter:光源
- area:面光源
- film:相机底片
- hdr:高动态范围底片
- filter:像素重建模块
- box:盒滤波器
- gaussian:高斯滤波器
- integrator:积分器
- path:路径追踪
- sampler:采样器
- independenet:独立随机采样器
- lowdiscrep:低差异序列采样器
- shape:物体
- obj:Wavefront Obj 物体
- triangle:三角面片
- texture:纹理
- bitmap:图像纹理
- constant:常量纹理
- scale:数值缩放纹理
LSR 运行的基本流程为
- 读取场景描述文件(xml)并解析;
- 根据解析结果,动态加载所需模块(包括 obj 文件、材质);
- 建立场景加速结构(BVH);
- 使用加载的积分器渲染场景:
- 将所需渲染图像划分为 16*16 的像素块,分别对应一个渲染线程;
- 每个线程中,由采样器生成像素块上的采样点,相机模块生成对应光线,随后积分器求得样本光线值;
- 相机底片模块计算样本光线对采样点周围像素的重建贡献。
- 相机底片模块将重建像素值保存为对应格式的图片。
此外,LSR 在架构上支持 RGB 和光谱渲染。后者需要在编译时开启 SPECTRUM_RENDERING 选项。LSR 在底层实现了一个 Spectrum 类,用于控制选择 RGB 或光谱表示辐射度量与材质参数等信息,其内部的实现细节对于各个模块是透明的。
对于光谱渲染模式,作业提交的版本缺少从RGB到光谱的上采样实现,因此暂时无法使用RGB贴图。后续将进行完善。
为了方便模块化系统处理,场景文件格式有所修改,与 mitsuba 类似,以下为例:
<integrator type="path">
<sampler type="lowdiscrep" spp="256"/>
</integrator>
<camera type="perspective">
<film type="hdr" width="512" height="512"/>
<eye x="1" y="0" z="0"/>
<lookat x="0" y="0" z="0"/>
</camera>
<scene>
<shape type="obj" filepath="path/to/obj">
<light mtlname="topLight" radiance="0.5,0.5,0.5"/>
<light mtlname="bottomLight" radiance="0.5,0.5,0.5"/>
</shape>
</scene>每个模块由一个 xml 标签描述,标签名描述模块实现了渲染器中的哪一部分,如反射模型、光源、采样器等;type 属性表示要使用的具体实现类型,例如 phong 反射模型,dielectric 反射模型等。
模块之间存在相互嵌套关系,如采样器(sampler)在积分器(integrator)内描述,相机底片(film)在相机(camera)标签内描述。
在场景文件中,相机与底片必须指定,积分器无指定时默认使用路径追踪(path),采样器默认使用独立采样。最后,物体与光源必须在场景标签(scene)内描述。
对于面光源(area),LSR 的设计思路是是在光源模块内嵌套物体,以描述实际发光的几何形状,例如:
<emitter type="area" radiance="0.5,0.5,0.5">
<shape type="triangle"/>
</emitter>而作业给定的场景将多个光源放在同一个 obj 文件中,并利用 mtlname 属性指定光源所属 mesh。LSR 同样兼容这种物体内嵌光源的描述方式,但为了避免无穷嵌套,关闭了在光源模块内嵌套 obj 物体的功能,即
<emitter type="area" radiance="0.5,0.5,0.5">
<shape type="obj" filepath="path/to/obj"/>
</emitter>是不被允许的。后续,为了个人学研需要与维护代码简洁性,LSR 将不兼容物体内嵌光源的描述方式,并恢复光源内嵌 obj 物体的支持。











