光线追踪计算加速:包围盒

news2024/11/23 19:59:54

包围盒(Bounding box)是加速光线追踪(Ray Tracing)的最简单方法,不一定将其视为加速结构,但这无疑是减少渲染时间的最简单方法。

在这里插入图片描述

推荐:用 NSDT设计器 快速搭建可编程3D场景。

使用包围盒来加速光线追踪的想法已经很古老了。 很难确切地知道这个想法是由谁以及何时提出的。 在 1980 年题为“复杂场景快速渲染的 3 维表示”的论文中,作者 Ruben 和 Whitted 已经谈到了使用此类边界体积的层次结构进行“快速”渲染的可能性(请参阅末尾的参考资料部分) 本课的内容)。

茶壶中的每个栅格都可能有一百多个三角形:栅格有 8 个分区,包含 128 个三角形,这需要对投射到场景中的每条光线进行类似数量的相交测试。 相反,我们可以做的是光线追踪一个包含栅格所有顶点的盒子。 这样的盒子称为包围盒:它是围绕栅格的最紧密的可能体块(在这种情况下是一个盒子,但它也可以是一个球体)。 图 1 显示了构成茶壶模型的 32 个贝塞尔曲线块中每一个的边界框。

在这里插入图片描述

图 1:构成纽厄尔茶壶的贝塞尔曲线的边界框。
在这里插入图片描述

图 2:测试边界框与射线的相交。 可以安全地拒绝未与射线相交的包围体所包含的几何图形。

我们可以首先测试光线是否与该盒子相交,如果没有相交,我们就可以确定它无法与该包围盒中包含的几何体相交(图 2)。 如果我们可以忽略此边界框中的三角形,则可以节省 128 次光线-三角形相交测试。

考虑到场景中的许多边界框也可能无法通过此测试,总的来说,我们可以节省对光线三角形例程的大量调用。 如果射线与边界框相交,则必须测试体积中包含的所有三角形是否与该射线相交。 在图 2 中,我们可以看到一条射线与构成茶壶模型的贝塞尔曲面片的边界框相交。 只有彩色框才会与射线相交,并且只有这些框包含的网格才会被测试与射线的相交。 可以安全地拒绝包含在未相交的框中的补丁。

下面的伪代码说明了这个过程:

for (each object in scene) { 
    if (intersect(ray, object->boundingBox) == true) { 
        for (each triangle in object) { 
            if (intersect(ray, triangle) == true) { 
                // the ray intersects the triangle 
                ... 
            } 
        } 
    } 
} 

在这里插入图片描述

图 3:Ape 模型的边界框(由 Kenichi Nishida 提供)

计算对象的边界框非常简单。 我们可以循环组成网格的所有顶点,以找到每个点坐标(xyz 点位置)的最小值和最大值。 这些值形成了我们所说的对象的最小和最大范围,并定义了边界框的两个角(见图 3)。

对象的边界框通常在构建对象时计算(例如在多边形网格类的构造函数中)并存储在对象类的成员变量中(每个基元类型可能需要不同的方法来计算此边界框 . 例如,二次球体的包围体积可以根据其半径计算)。

光线追踪器中的以下代码片段显示了我们如何计算多边形对象的边界框(第 13 行)。 bbox 变量是 Object 基类的成员变量(代码可在本课最后一章中找到)。

class PolygonMesh : public Object 
{ 
public: 
    PolygonMesh( 
        const Matrix44f &o2w, 
        const uint32_t &np, const uint32_t *nv, const uint32_t *v, 
        const Vec3f *pts, const Vec3f *nors = NULL) : 
        Object(o2w), ntris(0), tris(NULL), P(NULL), N(NULL) 
    { 
        ... 
        for (uint32_t i = 0; i < maxVertIndex + 1; ++i) { 
            objectToWorld.multVecMatrix(pts[i], P[i]); 
            bbox.extendBy(P[i]); 
        } 
        ... 
    } 
}; 
 
template<typename T, uint32_t D> 
class Box 
{ 
public: 
    ... 
    void extendBy(const Vec<T, D>& pt) 
    { 
        for (size_t i = 0; i < D; ++i) { 
            if (pt[i] < bounds[0][i]) bounds[0][i] = pt[i]; 
            if (pt[i] > bounds[1][i]) bounds[1][i] = pt[i]; 
        } 
    } 
    ... 
}; 

其余的代码非常简单。 我们将使用我们在第 7 课(相交简单形状)中学习的射线盒相交例程:

uint64_t numRayBoxTests = 0;


template<typename T, uint32_t D>
bool Box<T, D>::intersect(const Ray<T>& r) const
{
    __sync_fetch_and_add(&numRayBoxTests, 1);
    ...
    return true;
}

我们使用与射线-三角形相交方法相同的方法来计算射线-盒相交方法被调用的次数。 每次调用 box intersect 方法时,都会使用原子添加操作来递增 box.cpp 文件中声明的全局变量 numRayBoxTests。 最终值与其他统计信息一起在渲染结束时打印出来。

我们还创建了一个 AccelerationStructure 基类,其行为与对象非常相似。 它拥有一个 intersect 方法,循环遍历场景中的所有对象(第 5 行)。 我们首先测试射线和当前对象的边界框之间的相交(第 7 行)。 如果测试成功,则将针对盒子中包含的对象测试射线(第 9 行)。 其余代码与第 11 课中的跟踪函数的实现非常相似。每次三角形相交时,我们都需要更新到相交点的最近距离(第 10-11 行)并保留指向相交点的指针 对象(第 12 行):

const Object* AccelerationStructure::intersect(const Ray<float>& ray, IsectData& isectData) const 
{
    float tClosest = ray.tmax;
    Object *hitObject = NULL;
    for (size_t i = 0; i < rc->objects.size(); ++i) {
        Ray<float> r(ray);
        if (rc->objects[i]->bbox.intersect(r)) {
            IsectData isectDataCurrent;
            if (rc->objects[i]->intersect(ray, isectDataCurrent)) {
                if (isectDataCurrent.t < tClosest && isectDataCurrent.t > ray.tmin) { 
                    isectData = isectDataCurrent; 
                    hitObject = rc->objects[i];
                    tClosest = isectDataCurrent.t;
                }
            }
        }
    }
 
    return (tClosest < ray.tmax) ? hitObject : NULL;
}

最后我们需要更新跟踪功能。 我们不需要循环场景中的所有对象,只需调用 AccelerationStructure 类中的 intersect 方法即可。 如果此方法返回指向场景中对象的有效指针,则发生相交,我们可以使用相交对象的颜色设置像素的颜色:

template<typename T>
void trace(const Ray<T> ray, const RenderContext *rc, Spectrum &s)
{
    IsectData isectData;
    const Object *hitObject = NULL;
    if ((hitObject = rc->accelStruct->intersect(ray, isectData)) != NULL)
        s.xyz = hitObject->color;
    else
        s.xyz = rc->backgroundColor;
}

如果我们渲染上一章中使用的场景,我们现在得到以下统计数据:

Render time                                 : 3.96 (sec)
Total number of triangles                   : 16384
Total number of primary rays                : 307200
Total number of ray-triangles tests         : 129335296
Total number of ray-triangles intersections : 111889
Total number of ray-box tests               : 9830400

渲染时间减少了约 34 倍。从逻辑上讲,使用和不使用此基本加速结构执行的光线三角形测试数量之间的比率大致相同:38。由于额外的时间,这两个数字并不完全相同 现在需要计算光线盒相交(983 万次)。 然而,我们从使用该方案中获得的好处很大程度上超过了这些测试所需的额外工作。

本章介绍的技术在茶壶的情况下效果很好,因为模型包含许多分辨率(就多边形数量而言)相当低的网格。 另一方面,猿模型非常复杂,并且由单个部件制成。 如果我们要渲染这个对象,只有当主光线不与其边界框相交时(也就是说,对于典型的帧,可能少于像素总数的三分之一),我们才会节省时间。 对于所有过度光线,我们仍然需要对构成模型的数十万个三角形执行相交测试。 在这种特殊情况下,与暴力方法相比,边界框方法只会带来很小的好处。 它实现起来简单且快速,但显然并不适合所有情况,因此它不被认为是一种非常好的加速方法。


原文链接:光线追踪加速机制- 包围盒 — BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/771268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

椒图——靶场模拟

先查看ip&#xff0c;10.12.13.232模拟的外网ip&#xff0c;其他的模拟内网ip&#xff0c;服务里面搭建好的漏洞环境。 #第一个测试项目&#xff0c;web风险发现 新建&#xff0c;下发任务&#xff0c;点威胁检测&#xff0c;webshell&#xff0c;点扫描任务&#xff0c;点新…

迅镭激光赋能工程机械,客户连续复购激光加工设备达双赢!

工程机械是装备制造业的重要组成部分&#xff0c;当前&#xff0c;我国已成为门类齐全、规模庞大、基础坚实、竞争力强的工程机械设备制造大国。 随着工程机械产业正在全面向智能化、绿色化转型&#xff0c;激光加工成为推动工程机械产业转型升级的重要工具&#xff0c;越来越多…

一道SQL题

有个搞数仓的朋友不知道从哪儿弄了个题。。。 做了做体验了一下。。。 记录记录。 分析 要保证每天都要做新题 5天必须都做题&#xff0c;不然GG 最后一天必须做新题&#xff0c;如果最后一天做新题了&#xff0c;前面那几天没做新题&#xff0c;做的是老题 最后一天&#…

初识mysql之理解索引

目录 一、 primary key对索引的影响 1. 主键数据有序问题 2. mysql中的page 3. 主键排序问题 二、理解多个page 1. 数据在page中的保存 2. 页目录 3. 单页情况 4. 多页情况 5. 为什么除了叶子节点外的其他节点不保存数据&#xff0c;只保存目录 6. 为什么叶子节点全…

创意网页模板免费下载,让你的网站与众不同!

今天给大家带来的网站模板素材&#xff0c;网站类型丰富&#xff0c;包含户外旅行、餐饮、个人网站等等&#xff0c;可以学习和参考其中的布局排版和配色。 ⬇⬇⬇点击获取更多设计资源 https://js.design/community?categorydesign&sourcecsdn&planbbqcsdn772 1、设…

域内信息收集

将网络中多台计算机逻辑上组织到一起进行集中管理&#xff0c;这种区别于工作组的逻辑环境叫 做域。域是由域控制器(Domain Controller)和成员计算机组成&#xff0c;域控制器就是安装了活动 目录(Active Directory)的计算机。活动目录提供了存储网络上对象信息并使用网络使用该…

图像处理之canny边缘检测(非极大值抑制和高低阈值)

Canny 边缘检测方法 Canny算子是John F.Canny 大佬在1986年在其发表的论文 《Canny J. A computational approach to edge detection [J]. IEEE Transactions on Pattern Analysis and Machine Intelligence, 1986 (6): 679-698.》提出来的。 检测目标&#xff1a; 低错误率…

2023年软件测试八股文(含答案+文档)

Part1 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自…

汽车新品研发用泛微事井然,全过程数字化、可视化

产品研发是汽车制造产业链的运营过程中的初始阶段&#xff0c;是提升汽车企业创新力、竞争力的重要一环&#xff0c;不仅要洞悉市场变化&#xff0c;还要有效协同企业内部的各类资源… 汽车新产品研发项目周期长、资源投入大&#xff0c;面临着诸多挑战&#xff1a; 1、市场需…

采集传感器的物联网网关怎么采集数据?

随着工业4.0和智能制造的快速发展&#xff0c;物联网&#xff08;IoT&#xff09;技术的应用越来越广泛&#xff0c;传感器在整个物联网系统中使用非常普遍&#xff0c;如温度传感器、湿度传感器、光照传感器等&#xff0c;对于大部分物联网应用来说&#xff0c;采集传感器都非…

02.MySQL——CURD

文章目录 表的增删改查Create单行数据全列插入多行数据指定列插入插入否则更新替换——REPLACE RetrieveSELECT 列WHERE 条件结果排序筛选分页结果 UpdateDelete删除数据截断表 插入查询结果聚合函数group bywhere和having SQL查询中关键字优先级函数日期函数字符串函数数学函数…

Spring 事务控制

1. 编程式事务控制相关对象 1.1 平台事务管理器 1.2 事务定义对象 1.3 事务状态对象 关系&#xff1a; PlatformTransactionManager TransactionManager TransactionStatus 2. 基于XML的声明式事务控制 切点&#xff1a;&#xff08;目标对象&#xff09;业务方法&#xff…

idea不小心push的文件夹怎么处理?

第一种方式&#xff0c;把不小心push上去的人解决掉。 第二种方式&#xff0c;以我自身为例&#xff0c;同事不小心push了.idea文件夹 首先打开git bash git rm --cached .idea/ -r 然后查看一下状态 git status 接着提交修改 git commit -m "cancel track .idea file&q…

从小白到大神之路之学习运维第62天--------Ansible自动化运维工具(playbook配置深入了解2.0)

第三阶段基础 时 间&#xff1a;2023年7月17日 参加人&#xff1a;全班人员 内 容&#xff1a; playbook配置深入了解2.0 目录 一、角色 实验案例&#xff1a;&#xff08;安装Mariadb&#xff09; 二、变量 &#xff08;一&#xff09;在playbook中使用自定义变量&#xff1…

Microsoft Outlook 共享收发邮件的权限给其他人

点击File 点击Account Settings→DelegateAccess 点击Add

数据可视化自助式分析工具:jvs-bi数据扩展及函数配置说明

jvs-bi数据拓展节点 数据拓展是数据可视化加工过程中的重要工具&#xff0c;它核心的作用是对原有数据表进行加工扩展&#xff0c;实现功能如下图所示 函数配置操作过程 操作说明 1、拖动数据拓展字段&#xff0c;并将字段拓展与之前的历史节点连接起来&#xff0c;点击数据拓…

访问Liunx文件系统

访问Liunx文件系统 识别文件系统和设备 存储管理概念 Linux服务器上文件按文件系统层次结构访问。该文件系统层次结构测试由系统可用的存储设备所提供的文件系统组装而来。每个文件系统都是一个已格式化的存储设备&#xff0c;可用于存储文件。 文件系统和挂载点 要让文件系…

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制

文章目录 sentinel控制台安装目标版本说明sentinel 规则整合验证pom.xml配置注解拦截资源控制规则---内存模式测试controller客户端接入控制台 测试sentinel控制台接口调用 下一篇&#xff1a;配置持久化策略规则外传 sentinel控制台安装 下载地址&#xff1a;https://github.…

SpringCloud学习路线(6)—— 远程调用HTTP客户端Feign

一、Feign替代RestTemplate RestTemplate示例 String url "http://userservice/user/" order.getUserId(); User user restTemplate.getForObject(url, User.class);RestTemplate的缺陷&#xff1a; 代码可读性差&#xff0c;编码体验不统一。参数复杂URL难以维…

(位运算)2023年7月19日学习笔记

位运算符的优先级&#xff08;从高到低&#xff09;&#xff1a;~、&、^、|【其中~&#xff08;取反&#xff09;的结合方向自右至左&#xff0c;且优先级高于算术运算符&#xff0c;其余运算符的结合方向都是自左至右&#xff0c;且优先级低于关系运算符】 声明一下关系运…