Games101 Homework7 优化

【GAMES101】作业7(提高)多线程、Microfacet(全镜面反射)、抗锯齿 立即下载

本次作业其实就是在 whitted-style 的 ray tracing 上进行改进,实现更常见的 path tracing,原理部分闫老师的课程和作业文档中已经讲地十分清楚,不再赘述(如有一些细节上的疑惑,可以参考官网的论坛作业7发布公告 – 计算机图形学与混合现实在线平台 (games-cn.org) 或者这篇文章Games 101 | 作业7 + 路径追踪 Path Tracing + 多线程 - 知乎 (zhihu.com)),这里主要分享几个可以优化的点。

优化一:多线程加速

对于屏幕上的每个像素,因为不考虑光线之间的碰撞,从每个像素发出的追踪光线其实是相互独立的,故而可以给每个像素使用一个线程用于光线追踪。

在实际中,由于硬件限制,可以考虑在一个线程中绘制多行像素,达到多线程加速的目的。

具体做法是,使用一个绘制函数,新开线程给函数传参,告诉它要绘制那几行像素,使用隐函数会比较方便,参考代码如下:

int num_threads = 64;
std::thread th[num_threads];
int thread_height = scene.height/num_threads;

auto renderRows = [&](uint32_t start_height, uint32_t end_height) {
    for (uint32_t j = start_height; j < end_height; ++j) {
        for (uint32_t i = 0; i < scene.width; ++i) {
            // generate primary ray direction
            // random SSAA
            for (int k = 0; k < spp; k++){
                // trace light
            }
         }
         progressMtx.lock();
         progress++;
         UpdateProgress(progress / (float)scene.height);
         progressMtx.unlock();
     }};
    
for (int t = 0; t < num_threads; ++t) {
    th[t] = std::thread(renderRows, t*thread_height, (t+1)*thread_height);
}
for (int t = 0; t < num_threads; ++t) {
    th[t].join();
}

其中,加锁是为了 progress 的正常显示,不影响最终结果。

优化二:随机超采样

原来的代码中使用的超采样全都是从像素中心发出光线做平均,光线没有分散开来,这样并不能真正体现超采样的优点,也无法达到抗锯齿的效果。可以考虑使用 0~1 之间的均匀随机位置发出光线,然后再平均,当然也可以采用更好的平均算法,如高斯加权平均等。

// generate primary ray direction
// random SSAA
for (int k = 0; k < spp; k++){
    float x = (2 * (i + get_random_float()) / (float)scene.width - 1) * imageAspectRatio * scale;
    float y = (1 - 2 * (j + get_random_float()) / (float)scene.height) * scale;
    Vector3f dir = normalize(Vector3f(-x, y, 1));
    framebuffer[(int)(j*scene.width+i)] += scene.castRay(Ray(eye_pos, dir), 0) / spp;  
}

 优化三:光线遮挡判断

在判断光线是否被遮挡时,需要从当前点往采样的光源方向发出一个射线,然后判断射线所交的物体是否为光源。很多人的做法是通过距离进行判断,但这样的判断往往存在浮点数误差问题,需要引入一个 EPSILON 放宽限制。

在这里,其实可以直接判断光线所交物体是否为采样的光源,只需要改一个地方:

在三角形求交时需要存储 Object 指针;

inline Intersection Triangle::getIntersection(Ray ray)
{
    // ...

    // TODO find ray triangle intersection
    if(t_tmp <= 0) {
        return inter;
    }
    inter.happened = true;
    inter.coords = ray(t_tmp);
    inter.normal = normal;
    inter.distance = t_tmp;
    inter.m = m;
    inter.obj = this;
    return inter;
}

然后就行可以直接判断,所交物体是否为采样的光源;

Intersection lightDirBlock = intersect(Ray(p, lightDir));
Vector3f L_dir;
//if(lightDirBlock.distance - (p-lightPos).norm() > -10 * EPSILON) {
if(lightInter.obj == lightDirBlock.obj) {
    L_dir = lightEmit * pInter.m->eval(ray.direction, lightDir, pNormal) *
        dotProduct(lightDir, pNormal) * dotProduct(-lightDir, lightNormal) /
        pow((p-lightPos).norm(), 2) / lightPdf;
}

优化四:随机数生成

在提供的随机数生成函数中,使用局部变量来存储随机分布的相关变量,这样会使得每次生成都需要重新初始化变量,会带来一些性能瓶颈。

可以直接把所需要的变量设为静态,这样就只会进行一次初始化。

inline float get_random_float()
{
    static std::random_device dev;
    static std::mt19937 rng(dev());
    static std::uniform_real_distribution<float> dist(0.f, 1.f); // distribution in range [0, 1]

    return dist(rng);
}

优化结果

最后,使用SPP=256,64线程,在8G内存8核CPU的条件下,共运行了23分钟,效果如下:

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月14日-Clamshell 拆卸与安装 Clamshell 拆卸与安装。 阅读详情

相关推荐

论文记录:Affine Formation Maneuver Control of Multiagent Systems

多智能体编队控制仿真记录 实现功能:平移/旋转/尺寸缩放/shear,见截图 注意:本仿真图只是起到了演示效果,中间过程速度产生突变,实际中是不允许的。需要进行速度规划,这一点论文中仿真图更为贴合实际。 参考论文:Zhao, S. (2018). Affine Formation Maneuver Control of Multiagent Systems. IEEE Transactions on Automatic Control, 63(12), 4140–4155. 突然发现有个博主写得很好,参考:

W1H1J1的博客 2108

GAMES101作业7及课程总结(重点实现多线程加速,微表面模型材质)

从这篇文章开始,转知乎了,感觉知乎的社区氛围更好,emmm,哈哈哈主要还是想接触一下知乎的图形学大佬们。知乎账号链接:https://www.zhihu.com/people/xuu-27-24

Xuuuuuuuuuuu的博客 2569

Supervisor 安装与使用

一、Supervisor 介绍 Supervisor 是一个用 Python 编写的进程管理工具,它可以用于监控和控制类 UNIX 操作系统上的多个进程。它是一个客户端/服务器系统,其中 Supervisor 的服务器端称为 supervisord,负责启动管理的子进程、响应客户端命令、重启崩溃或退出的子进程、记录子进程的 stdout 和 stderr 输出,以及处理子进程生命周期中的事件。客...

疯子丶pony的博客 3863

GAMES101:作业7

做出来图片有横条的原因在这里:这个数字不能过于接近0。 由于本人电脑虚拟机不太稳定,日常闪退,因此我渲染了474秒,取SPP=30,结果如下: 可以看到,不到七分钟的渲染结果还是非常不错的 并且注意检查 t_enter = t_exit 的时候的判断是否正确。 这句提示其实非常关键!老师上课的时候经常提到,图形学很少关心相等的时候的条件,但是这里确实会影响到输出的结果。假如 t_enter = t_exit 时返回的是false,那么作业6并不会出任何问题,但作业7中会导致只能渲染出左侧的盒子和墙体。因此,

qq_41765657的博客 5727

【NTN 卫星通信】使用地面网络和卫星网络接入的终端应用场景

卫星接入有广覆盖的特点, 可以改善地面接入网覆盖或无线条件差的地区(例如多径干扰)的服务可用性。对于高速移动中需要实时业务的终端,如IMS语音/视频会议,可以通过地面接入和卫星接入同时实现与5G系统的双连接,在地面接入网不可用的情况下获得连续可靠的业务。

weixin_43603524的博客 2558

二、ROS2完成Docker容器和宿主机通信,使用ros2 topic list看到,但是无法echo

如果容器和主机权限不一致,则会导致无法通信(我的代码中,docker容器是root,宿主机是普通用户),虽然可以查询到相关话题,但是订阅后没有消息输出。比如,docker容器创建了一个共享内存,其所有者为docker容器用户root,当宿主机去访问的时候,由于用户不同,没有权限访问,也就无法进行信息传递。该方法只是临时修改共享内存的权限,每次运行完,需要重新运行上述命令,才可以进行通信。在运行的过程中,ROS2使用了共享内存机制,会共享内存。运行之后,宿主机和容器可能用户名不同,这是因为。

qq_43280851的博客 1265

games101——作业7

games101作业7,主要关于代码部分与进阶代码的解析

hhhcbw的博客,欢迎各位来访 3951

第10章 shellcode实战:18 神级开源shellcode工具:donut

Donut是一款shellcode生成器,可将C/C++、C#生成的PE文件转换为shellcode文件,同时支持JS、XSL、VBS脚本转换为shellcode。以下“原生”EXE/DLL指非托管PE文件(包括并不限于C/C++、delphie等编写生成的可执行文件),可以直接由系统加载运行,区别于.Net生成的托管文件。被处理exe/dll为32位程序,则需要用32为的shellcode加载器启用,exe/dll为64位的就用64位shellcode加载器启用。

李小咖·网安技术库 2796

GAMES101 作业 5:光线与三角形相交(附源码)

1.光线投射对成像平面的每一个像素,从摄影机连一条线穿过这个像素,就可以打出一根光线,它会打到场景中的某个位置,或者和场景中什么东西都不相交。如果它和某一个物体发生相交,知道它就是沿着这个方向看到了哪儿,然后再把这个点和光源做一个连线。这是要干嘛?这是要判定这个点是否会光源也可见(即判定他是不是也在阴影里)。如果它不在阴影里,即光源可以照着它,就形成了一条有效的光路,从光源到这个点再到我的眼睛,那么就可以计算这条光路上的能量,自然就可以把这个最后看到的颜色算出来,这一步就是着色。

m0_55913730的博客 978

YOLOv8源码解析与复现:ShuffleAttention:高效的混合注意力机制 实现通道和空间混合注意力

随着深度学习在计算机视觉领域的飞速发展,卷积神经网络(CNNs)已经成为图像分类、目标检测、语义分割等任务的核心。为了进一步提升模型的性能,研究者们引入了“注意力机制”,旨在让网络能够动态地关注输入数据中最具信息量的部分。经典的注意力模块,如SE-Net(Squeeze-and-Excitation Networks)和CBAM(Convolutional Block Attention Module),通过通道注意力或结合通道与空间注意力,显著增强了模型的特征表达能力。

FJN110的博客 554

abapGit 安装与初始化完整指南:从 on-premise 到 SAP BTP ABAP environment 的一条龙实践

本文为ABAP开发者提供abapGit从安装到团队协作的完整指南。内容涵盖社区版ZABAPGIT的on-premise安装、Eclipse ADT插件配置、BTP环境使用及常见网络问题处理。重点包括:获取最新构建的安装步骤、EN语言环境的重要性、ADT插件安装方法、以及如何实现on-premise与BTP间的代码迁移。文中特别强调企业环境下代理设置、证书配置等注意事项,并提供实际操作案例,如将RAP业务对象迁移到BTP环境。文末附有可复用的实施清单,帮助开发者快速落地abapGit。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 413

GAMES101-计算机图形学-作业7

2 调通框架 2.1 修改的内容 相比上一次实验,本次实验对框架的修改较大,主要在以下几方面: • 修改了main.cpp,以适应本次实验的测试模型CornellBox • 修改了Render,以适应CornellBox 并且支持Path Tracing 需要的同一Pixel多次Sample • 修改了Object,Sphere,Triangle,TriangleMesh,BVH,添加了area 属性与Sample 方法,以实现对光源按面积采样,并在Scene 中添加了采样光源的接口sampleLight

qq_40297109的博客 436

Autosar PWM模块的配置和使用

在上面的代码中,我们首先配置了PWM的初始化参数,包括频率和分辨率。GPIO Driver:由于PWM信号需要输出到特定的引脚上,因此我们还需要使用GPIO驱动程序来控制引脚的状态。通过合理配置和应用PWM模块,我们可以实现对汽车电子系统中各种功能的精确控制,从而提高汽车性能和用户体验。在实际应用中,我们可以根据需要进行更多的配置和调整,以实现灵活的PWM控制。PWM Driver:这是主要的PWM驱动程序,负责产生PWM信号并输出到相应的引脚上。接下来,我们需要配置PWM模块的参数。

TcData的博客 682

GAMES101:现代计算机图形学入门(Chapter5 光栅化1(三角形遍历))迅猛式学习笔记(附Homework 0+Windows环境下vscode第三方库Eigen3配置教程)

本文介绍了GAMES101课程的作业0内容,主要包括Eigen库的使用和矩阵变换操作。通过C++代码示例展示了基本的向量运算(加减、数乘)、矩阵运算(加减、数乘、矩阵乘法)以及角度弧度转换等数学操作。文章还提供了环境配置说明(安装Eigen库)和CMake编译配置,并给出了一个将点(2,1)绕原点逆时针旋转45度的矩阵变换作业任务。通过代码截图和公式推导,演示了如何利用齐次坐标和旋转矩阵实现二维空间中的旋转变换。

Atticus的博客 822

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【课程设计】springboot中小学教学辅助平台-计算机毕业设计源码06743

(1)个人信息:管理员和用户点击“个人信息”按钮,可以对个人的头像、昵称、手机号码等信息进行更新。 (2)修改密码:管理员和员工点击“修改密码”按钮,可以对登录密码进行更改,首先输入原密码,然后再输入新密码和确认密码,当原密码正确,输入两次新密码一致, (3)作业中心管理,点击“作业中心”这个菜单,可以查看到所有作业详情进行查询,添加、删除等操作。 (4)作业批改管理,点击“作业批改”这个菜单,可以查看到所有学生上交的作业详情,进行批改、查询,添加、删除等操作。 (5)课程表管理,点击“课程表”这个菜单,可

Biye_Design的博客 1090

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 239

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

选型笔记:Type‑C 扩展坞方案评估|DP1.4 转 HDMI2.0 桥接芯片 GSV2201S@ACP

本文记录 GSV2201S 这款 DP1.4a 转 HDMI2.0 桥接芯片评估,梳理视频、HDCP、PD 集成能力,总结 Type‑C 转接 Dongle、扩展坞方案的适配边界,以及差分走线、PD 时序、HDCP 握手等高频调试问题,为 C 口视频转接方案选型提供参考。

ACP广源盛的博客 221

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 391

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 337

【C语言】字符与字符串函数

C语言中字符串为以\0结尾的字符数组,标准库函数基于此约定。本文解析字符串内存布局,详解ctype.h与string.h中字符分类、长度计算、拷贝、比较等函数的使用要点,强调长度判断与越界风险,最后通过命令行待办事项示例整合fgets、sscanf、strncpy、strcmp,展示实际应用中的关键细节。

记录在学习过程中学到的知识 346

C++ 多态详解:作用、原理与实战用法

多态是C++面向对象的核心特性,通过虚函数实现运行期动态绑定,使同一接口在不同对象上表现出不同行为。其核心作用包括统一接口、提升可扩展性、降低耦合、支持运行时分派与批量处理。实现依赖虚函数表(vtable)和虚指针(vptr),需注意虚析构函数、对象切片等陷阱。相比编译期多态(模板),运行期多态灵活性高但有调用开销。合理结合两者,可兼顾代码的灵活性与性能,是构建可扩展、低耦合系统的关键。

2402_85743155的博客 382

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 304

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 437

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 205

【C++】【STL】string_OJ题

本文总结了9道C++ STL中关于string的OJ题目,按操作类型分为三组:反转与就地修改(如917、541、151)、计数与查找(如387、125、58)、模拟与大数运算(如415、43、8)。核心技巧包括双指针收敛、字符分类处理、进位控制及边界值处理。所有题目使用同一套源码,在标准库std::string与自定义容器MyString间切换仅需宏定义,验证结果一致性。代码通过随机测试用例与Trace函数逐行比对,确保逻辑正确性,强调接口对齐的重要性。

这里是Cocatrice的博客,感谢大家一直以来的支持和鼓励,如果对C/C++方向感兴趣的话,可以通过主页的微信名片加Cocatrice的好友,也可以通过邮箱:Chen31980094@163.com 联系,一同加油! 4371

C 语言 malloc() 详解与实战 Demo

本文详解C语言malloc()函数,涵盖其语法、内存原理及实战应用。通过动态整数、数组、结构体与链表的Demo,演示如何安全申请、使用与释放内存,强调避免内存泄漏与空指针检查的重要性,帮助开发者掌握动态内存管理核心技能。

tangPHP的博客 371
上一篇: Ubuntu虚拟机交互失灵
下一篇: Games104作业四(含提高项)
要什么单车
博客等级 码龄8年 3粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值