-
Notifications
You must be signed in to change notification settings - Fork 20
将渲染计时和正确性测试纳入自动测试范围 #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
1.“为渲染模块编写单元测试”是指写一个类似test目录下的cpp文件那样的基于catch2框架的TEST_CASE宏吗,那这些文件的运行逻辑大概是什么样的,比如TESTCASE在什么时候被调用、在TEST_CASE中如何获取主程序的变量值(?) |
现在先只考虑写正确性测试,性能测试之后再说。 参考:
|
最近感觉大致了解了CATCH2框架,但关于TEST_CASE的运行时机我还是有些困惑,想来确认一下理解。问题主要在于假设以为同学写完了渲染实验之后,TEST_CASE如何通过这位同学编写的渲染代码得到结果。 |
所谓单元测试,就是每个测试点独立性很强,大多数时候你可以理解为每个 当你需要在单元测试代码中执行渲染时,应该自己创建 |
话说test.exe如何编译得到,是在test文件夹下单独cmake编译吗 |
是的,test 目录下有独立的 CMakeLists 文件,编译产物就是单元测试程序。具体说明可以参考实验手册基础部分的第三章。 |
这周在调试代码,遇到一个bug,报错信息为bad allocation。 TEST_CASE("Cow Rendering Test", "[rendering]")
{
INFO(fmt::format("Cow Rendering Test begins."));
Scene scene;
scene.load("../input/rendering/cow.dae");
scene.camera = Camera(camera_position, camera_target);
scene.lights.push_back(Light(light_position, light_intensity));
RenderEngine render_engine;
INFO(fmt::format("Begin rendering"));
render_engine.render(scene, RendererType::RASTERIZER);
INFO(fmt::format("Finish rendering"));
...
} 我已经用 |
目前有两个地方是能马上看出问题的:
另外需要补充一下,我以前写代码的时候考虑不周,导致默认的渲染图像尺寸会随屏幕分辨率变化。你可能也注意到我给你的渲染图尺寸有点奇怪,这是因为默认宽度是 480/屏幕缩放倍率 ,本来固定成 480 更合适。你可以用 PS 之类的工具把我发给你的参考图像宽度都缩小到 480 px,然后在测试时也统一按 480 宽度渲染。主体部分我之后会修改。 |
好的!我想问一下description中的diffuse和specular两个值如何赋值,看起来这两个值应该是物体组 |
不可以直接把 16 进制颜色赋值给 Vector3f color(RGB(0x5f, 0x32, 0x1e)); |
抱歉之前可能没有描述清楚,我的意思是 |
加载的时候确实会试图加载文件中的材质参数,不过加载之后也可以随时修改。材质不是 |
抱歉,这几天发布新版本忙得有些累,回复晚了。
从你发来的对比图上,我目前能猜到的原因是: 我会发给你正确的 MVP 变换实现,填入上面所说的三个函数后应该能解决问题,请妥善保管。 |
起因
1.0 版本下,要创建
Scene
/Group
/Object
对象,就要使用与 OpenGL Buffer 绑定的ArrayBuffer
/ElementArrayBuffer
对象存储顶点和索引数据,所以自动测试代码中想要管理场景数据非常不便。在 2.0 版本中,新的VertexAttribute
/VertexIndices
对象不再必须绑定某个 OpenGL Buffer ,因此整个场景都可以脱离 OpenGL Context 存在,也就可以在无屏幕的环境下进行自动测试了。Catch2 测试框架提供了完善的计时和统计功能,完全自动化的性能测试便于我们在修改代码后快速测试对性能的影响,并且不需要向渲染管辖代码中插入计时代码。所以,是时候实现离屏 (headless) 的自动化渲染测试了!
实现方案
对于 CPU 离线渲染而言,所有数据都在内存中,因此没有加载数据的过程,执行渲染就是调用
RenderEngine::render
函数。自动测试渲染的过程,就是在测试环境下离屏创建场景和RenderEngine
,然后进行渲染、获取图像、检查结果。所有关于渲染的测试逻辑都写在 test/rendering_tests.cpp 中。
离屏场景加载和渲染参数设置
在有 GUI 的情况下,加载文件是通过调用
Scene::load
函数完成的。这个函数会新建一个Group
对象,然后调用Group::load
函数执行加载过程。Group::load
函数会创建Object
、新的顶点和索引数据,并为它们创建 OpenGL Buffer Object 。离屏运行与有屏幕运行时的不同在于:
Controller
对象管理的Scene
现在需要在测试时手动创建VertexAttribute
/VertexIndices
对象的buffer
成员直接置为nullptr
添加光源、设置材质和相机参数的过程可以参考
UI::Toolbar
的layout_mode
和render_mode
两个方法,直接修改场景数据即可。不过,当前Scene
的构造函数会创建用于渲染 3D UI 元素的 OpenGL Buffer ,我们需要为它添加一个参数来控制是否创建 OpenGL Buffer ,并保证默认行为是创建(与原先相同)。加载完成后,再像UI::Toolbar::render_mode
中那样创建一个RenderEngine
对象并执行渲染。要加载的模型文件不属于代码仓库,所以文件路径(即包含模型文件的 dandelion-testset 目录)暂定在运行时指定。如果没有指定测试文件路径,默认到源代码目录的父目录下寻找。
性能测试
性能测试应当考虑场景复杂度和渲染线程数两个正交的参数:
渲染性能测试应当实现为两个单元测试,分别测试单线程与多线程的情况。多线程的单元测试除了输出渲染时长以外,还需要输出相较于单线程的加速比。
另外,目前的渲染计时代码是写在
RenderEngine
中的,实现自动性能测试之前应当首先将这些代码移除。正确性测试
如果一位同学正确地实现了渲染管线,那么他输出的图像应该和参考实现(即 dandelion-dev 的实现)差不多。不过由于光栅化、着色计算等实现细节上的差异,有少数像素的颜色不同是正常现象,因此比较渲染图时不能要求严格相同,而是要利用 PSNR(峰值信噪比)度量程序输出与参考图像间的差异。在 2023-2024 学年,我们因不确定使用何种度量方法而延后了实现渲染自动测试的计划,加上时间紧张,最终就没有实现。
为了实现它,我们需要准备测试数据并对 Dandelion 作一点修改。
RenderEngine
输出的 .ppm 图像文件体积太大,不利于放在 dandelion-testset 中作为教学资料发放。所以我们要调用 stb_image API ,输出 PNG 图像作为参考答案。The text was updated successfully, but these errors were encountered: