光之游戏

分数：200

提交次数限制：0/30

题面

提交

附件

背景

小 C 很喜欢玩游戏。他最近在玩一款名为《光》的游戏，这是一款非常真实的游戏，游戏中的光照效果非常逼真。小 C 一直想知道这款游戏是如何实现的，于是他找到了游戏的开发者，想要了解一下游戏的实现原理。

开发者说：

辐照度是一种用于计算光照的方法，它的基本思想是将光照分解为一系列的光子，每个光子都有一个辐照度，光子之间的相互作用可以通过辐照度的传递来计算。

下图展示的是一个典型的迭代过程，顶部的光源先照亮周围的墙壁和地面，地面和墙壁的散射再进一步照亮天花板和阴影。

图：一个典型的迭代过程

小 C 想要实现一个简单的辐照度计算器，他希望能够通过这个计算器来了解辐照度的计算过程。他希望你能够帮助他实现这个计算器。

任务

本题提供一个利用辐照度方法渲染场景样例程序，你需要以此为基础进行优化。程序接受一个场景的描述，进行细分，然后计算出每个点的辐照度。场景由一系列的面组成，每个面都有一个辐照度，每个面都可以反射光；每个面都可以被其他面照亮，每个面都可以照亮其他面。辐照度的计算过程如下：

顶部的光源照亮所有的面，每个面的辐照度为光源的辐照度。

每个面将自己的辐照度平均分配给所有照亮自己的面。

渲染场景，输出本轮迭代图像

重复步骤 2 若干次，直到所有面的辐照度都收敛。

输出最终图像。

本题提供 Baseline 和样例，请在“附件”选项卡中下载。

输入输出函数在样例中已经给出，不需要改动。

输入格式

输入文件 conf.data 为一个二进制文件，定义如下：

一个 64 位整数 NNN，表示平行四边形面的数量；

NNN 个面的数据，每个面的数据包含：

double3 pospospos，表示面的一个顶点；

double3 aaa，表示面的一条边；

double3 bbb，表示面的另一条边；

double3 emissionemissionemission，表示自发光；

double3 reflectancereflectancereflectance，表示反射率；

输出格式

输出文件为 6 个 BMP 图像。

评测方式

提交的代码会以最简单的方式编译并执行，编译选项为 -O3 -fopenmp -march=native -ffast-math -std=c++20。如果需要链接特定系统或编译器自带库，请联系工作人员并说明理由，编译条件的更改会对所有选手可见。程序运行在 Intel Xeon 8358 机器中的 8 个核心上。

样例程序大约需要 60 小时，优化到 2 分钟内能够拿到 5 分基本分，优化到 3.5 秒内能够拿到 100 分满分，分数随时间的对数线性变化。时间限制小于样例程序用时，意味着提交样例程序无法获得分数。允许程序输出与样例存在一定偏差，可以放心优化浮点计算过程。