关于Optix v6和Optix v7之间的种种区别

目录

Optix v6

基本构成组件

射线与求交

纹理

三角Mesh

Optix v7结构

基本构成组件

管线

着色器绑定表(SBT)

第一个例子

第二个例子


全局光照(GI)有很多种解决方案,比如VXGI、Lumen、DDGI、SSGI、IBL、PRT、SurfelsGI等,其中,越来越火的Nvidia的RTX技术也是软硬件结合的实时光追解决方案。

Optix的缺点是就像D3D或者OpenGL,代码比较难以理解。更难的问题在于Optix的资料太少,没有多少可以用来参考或者学习的资料,尤其是比较通俗的中文资料。笔者在广泛搜集和阅读源码后,撰写了Optix v6和Optix v7两个系列文章。其中,Optix v6来自于对官方源码结合用户手册的解读;Optix v7来自于对一个已有教程的解读。见[Optix v6-v7 - 应用与代码构建]。

Optix v6

基本构成组件

主要的对象模型有:

  • Context:用于运行 Optix 引擎的实例。
  • Program:CUDA 函数,编译为 NVIDIA PTX 虚拟汇编语言 (virtual assembly language)。
  • Variables:一种变量,用于将数据传入 Optix 程序。
  • Buffer:绑定到一个变量的多维数组。
  • TextureSampler:Buffer 的插值机制。
  • Geometry:ray 可以相交的基元,比如三角形或者用户自定义类型。
  • Material:材质程序,当 ray 相交与基元相交时执行。
  • GeometryInstance:绑定 Geometry 和 Material。
  • GroupNode:一系列安排在层次结构 (hierarchy) 中的对象。
  • TransformNode:一个层次节点 (hierarchy node) 用于变换几何和 ray。
  • SelectorNode:可编程层次节点,用来选择去遍历的子对象。
  • AccelerationStructure:绑定到层次节点 (hierarchy node) 的加速结构对象。

组件程序有:

  • Ray generation programs:光追管线的入口,由每个像素样本或者用户自定义的任务(比如一些自定义的特殊算法)来调用。
  • Exception programs:异常控制。
  • Closest hit programs:当 ray 找到最近交点时调用,在该程序中执行比如材质着色等程序。
  • Any hit programs:当 ray 找到一个新的潜在的最近交点时调用,比如对于计算阴影时有用。
  • Intersection programs:实现一个 ray 和基元交点测试,在 traversal 时调用。
  • Bounding box programs:计算基元的世界空间包围盒,当构建一个新的加速结构时调用。
  • Miss programs:当追踪的光线错过了所有几何结构时调用。
  • Attribute programs:当与内置三角形相交时调用,用于为任何命中和最近命中的程序提供三角形特定属性。

主机可以对Variables(rtDeclareVariable)进行赋值,并在GPU设备上访问这些值。

主机上申请Buffer(rtBuffer),然后用于在GPU设备上访问Buffer里的值或者计算并往Buffer里面填充值。

GPU启动渲染需要一个入口程序,一般就是光线生成程序,我们可以在一个Context里设置多个入口程序,并在发射时根据情况选择使用哪个入口程序。

射线与求交

发射启动后,如果光线检测到与最近的基元求交得到了交点,就会调用该物体绑定的closest-hit程序,如果与任意一个物体相交(比如在阴影计算时),就会调用any-hit程序。如果与任何基元都没有交点,就会调用miss程序。

进行光线追踪时,一般都是这样调用:

rtTrace(top_object, ray, payload);

其中,第一个参数表示加速结构最顶层,ray就是光线,payload就是光线携带的信息,比如根据BRDF当前的光衰减量,或者光此时反弹的次数等。计算阴影着色时的射线和计算辐射度的射线都用rtTrace(...)来追踪。

每个基元类型都需要绑定一种求交程序(内置的三角形可以不用绑定),以及设置该基元的包围盒。

然后为每种基元设计closest-hit程序和any-hit程序,并且绑定到材质对象中。之后再把材质对象和基元绑定在一起。绑定好的基元和材质叫做几何实例(GeometryInstance)。多个几何实例可以构成一个几何组(GeometryGroup)。

对于射线遍历过程中发现的每个潜在的最近交点,都会执行 any-hit program。执行程序的交点可能不会沿着射线相交顺序排序,但如果需要,最终可以枚举射线与场景的所有交点。不过在计算阴影光线时,一般会给采样射线的负载Payload设置一个衰减值,当衰减值到0,则终止射线的遍历,否则就忽略交点:

if(optix::luminance(prd_shadow.attenuation) < importance_cutoff)rtTerminateRay();
elsertIgnoreIntersection();

纹理

纹理的定

义看着跟CUDA有一些区别,但其实基本过程都是一致的(只不过Optix 7的函数名跟CUDA都是基本一样的)。

纹理需要在.cu文件里用rtTextureSampler声明,然后在主机上通过Context创建,然后初始化。

纹理并不会和材质绑定在一起,因此,哪怕是相同的材质类型,如果纹理不同,也需要分别实现不同的closest-hit程序。

三角Mesh

三角mesh可以自己写求交程序,也可以用optix自己内置的程序,但是如果我们用内置的程序的话,如果额外提供了法向量贴图,那么就需要实现attribute程序来计算着色法向量。attribute程序在closest-hit和any-hit程序执行之前执行,更新法向量等信息。

注意每个不同的mesh都有自己的indexBuffer以及vertexBuffer,自定义求交程序时,必须给一个参数primIdx,使得程序可以知道是与Buffer里哪个三角形获得了交点。

如果实例化的对象们的材质不同,假设总共涉及三种材质,那么就需要所有的实例化对象都包含这三种材质,并通过函数预先指定我们需要哪种材质。

Optix v7结构

Optix v7的结构就复杂了很多。尤其是引入了着色器绑定表/发射参数等概念。

Optix v6中,相机等参数都是使用rtDeclareVariable变量定义的,纹理/三角顶点数组等信息也都是通过全局变量来设置,比如rtBuffer/rtTextureSampler/rtDeclareVariable。在Optix v7中,这些内容都被列入了着色器绑定表里。

基本构成组件

Moudle会包含各种类型的程序,Moudle的创建需要两个很重要的参数结构:

OptixPipelineCompileOptions
OptixModuleCompileOptions

moudles定义了一些特性,这些特性来自于上面两个参数结构设置的属性,这些特性相当于给绑定到管线里的progrmas进行一些设置(比如第二个参数结构可以设置最大追踪深度/是否用离焦模糊等)。用于创建链接到单个管线中的程序组的所有moudles都必须使用相同的第一个参数结构(即,单个管线里的所有程序,最大追踪深度等属性都必须是一样的)。同一管线内的模块可能会有不同的第二个参数结构。

因此,如果我们想进行二次光线追踪来获得一幅图像,且两次光追用不同的管线,就需要设置两组管线,并且为其配置不同的Moudles。

管线

一个管线里可以有多个采样射线生成程序Raygen,可以有多个Miss程序,以及多个Hitgroup程序。每个Hitgroup程序都包含了closest-hit和any-hit程序。

着色器绑定表(SBT)

着色器绑定表可以理解为当响应了closest-hit或者any-hit程序以后,执行计算时需要访问的数据,比如使用哪个纹理/访问顶点数组。其实实际上,当物体与射线有交点时,去执行哪个closest-hit或者哪个any-hit程序,时根据物体绑定的SBT来决定的。

在构建加速结构时,每个OptixBuildInput对象(比如代表一个球体,或者代表一个mesh组)都对应一个物体ID。

当我们只有一种发射的射线类型时,每个物体绑定的一个SBT,该SBT对应一个Hitgroup程序就可以了。如果有两种发射的射线类型,而且每个物体都要实现对两种射线类型不同的着色计算,那么就需要两种类型的SBT,分别绑定两个不同的Hitgroup程序。当此时求交时是第一个SBT,那么第一个Hitgroup程序响应;当此时求交时是第二个SBT,那么第二个Hitgroup程序响应。

sbt.hitgroupRecordBase属性设置了Hitgroup的SBT的地址。用以GPU程序响应求交程序后访问SBT。

当设置有两种采样射线类型且需要访问两种不同的SBT时(采样辐射度射线/采样阴影的射线)时,所有OptixBuildInput对象对应的SBT都应该是两个,而不能有的是2个,有的是1个,否则就会在optixTrace(...)时因为SBT stride(optixTrace(...)是对整个场景的所有加载进去的物体进行光追)不一致而导致访问错误。我们再给两个例子加深一下印象。

现在假设有三个closest-hit程序与三个any-hit程序,设名字分别为:

    __closesthit_1__closesthit_2__closesthit_3__anyhit_1__anyhit_2__anyhit_3

hitgroup程序也有3个,分别绑定了上面的三组closest-hit和any-hit程序:

hitgroup_1
hitgroup_2
hitgroup_3

以上的假设并不会直接用到,仅仅是作为一些场景罢了。

第一个例子

假设我们只有一种类型的相机采样射线。

假如我们加载了5个meshes,每个mesh都包括不同数量的三角形。

假设初始化了5个hitgroup SBT。因为我们要设置optixTrace(...)的SBT offset为0,且SBT stride为1(每个mesh绑定的SBT数量都是1个),也就是说:第一个mesh相当于绑定了第一个hitgroup SBT;第二个mesh相当于绑定了第二个hitgroup SBT;以此类推。

不同的SBT可以绑定不同的hitgroup程序。

第二个例子

假如我们加载了5个meshes,每个mesh都包括不同数量的三角形。

假设初始化了10个hitgroup SBT,设为HitgroupRecord[10]。我们希望追踪相机射线或者阴影射线时,响应不同的求交程序(closest-hit程序与any-hit程序)。

我们要设置optixTrace(...)的SBT stride为2(每个mesh绑定的SBT数量都是2个),也就是说:

当optixTrace(...)的SBT offset为0时;当相机射线与mesh[0]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[0];当相机射线与mesh[1]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[2];当相机射线与mesh[2]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[3];以此类推。

当optixTrace(...)的SBT offset为1时;当相机射线与mesh[0]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[1];当相机射线与mesh[1]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[3];当相机射线与mesh[2]有交点,那么此时响应的Hitgroup SBT就是HitgroupRecord[5];以此类推。

第一个mesh相当于绑定了第一个和第二个hitgroup SBT;第二个mesh相当于绑定了第二个和第四个hitgroup SBT;以此类推。根据optixTrace的SBT offset参数来设置meshes应该去响应哪个SBT。

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

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

相关文章

k8s-ingress-context deadline exceeded

报错&#xff1a; rancher-rke-01:~/rke # helm install rancher rancher-latest/rancher --namespace cattle-system --set hostnamewww.rancher.local Error: INSTALLATION FAILED: Internal error occurred: failed calling webhook "validate.nginx.ingress.kube…

C语言刷题训练DAY.13

1.有序序列判断 解题思路&#xff1a; 这里我们先看代码&#xff0c;我们定义了一个flag1和flag2&#xff0c;它的作用主要就是判断是不是升序&#xff0c;具体怎么使用的&#xff0c;我为大家画图展示。 解题代码&#xff1a; #include<stdio.h> int main() {int n 0;…

实验一 ubuntu 网络环境配置

ubuntu 网络环境配置 【实验目的】 掌握 ubuntu 下网络配置的基本方法&#xff0c;能够通过有线网络连通 ubuntu 和开发板 【实验环境】 ubuntu 14.04 发行版FS4412 实验平台 【注意事项】 实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行&#xff0c;以“#”开头的…

介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。

Docker是一个开放源代码的容器化平台&#xff0c;可以将应用程序及其依赖项打包到一个轻量级的容器中&#xff0c;以便在任何地方运行。以下是Docker的基本概念和优势&#xff1a; 基本概念&#xff1a; 镜像&#xff08;image&#xff09;&#xff1a;Docker的基本构建块&am…

go 语法 基础包

目录 高性能go并发建议测试系统字符串flag日志reflect文件IOmath数字runtime远程调用限流注册中心链路跟踪监控日期时间time Decimal配置缓存异常开发工具包调试工具分布式调度json网络net/httphttp clientwebsocketpinguser_agent 并发sync 异步channelcontext异步并发 数据库…

改进YOLO系列:6.添加ECA注意力机制

添加ECA注意力机制 1. ECA注意力机制论文2. ECA注意力机制原理3. ECA注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. ECA注意力机制论文 论文题目:ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks 论文链接:ECA-N…

[国产MCU]-W801开发实例-按键与GPIO输入

按键与GPIO输入 文章目录 按键与GPIO输入1、硬件准备2、软件准备3、驱动实现4、驱动测试在前面的文章中,我们成功点亮了LED,同时也知道W801的GPIO是可软件配置的。在这里,将详细介绍如何通过按键控制LED。 1、硬件准备 W801开发板一块微动开关一个10K电阻一个导线若干1uF电容…

pytest fixture 创建一个 requests.session() 对象

当你运行这段代码时&#xff0c;它会执行以下操作&#xff1a; 1. 导入必要的库&#xff1a;pytest 和 requests。 2. 定义一个夹具&#xff08;fixture&#xff09;函数 session&#xff0c;使用 pytest.fixture(scopesession) 装饰器进行标记。这个夹具函数在整个测试会话期…

微服务参数透传实现

说明&#xff1a;在微服务架构中&#xff0c;用户身份经网关验证后&#xff0c;我们可以将用户信息&#xff0c;如ID加入到请求头上。后面的微服务中&#xff0c;可以设置一个拦截器&#xff0c;拦截请求&#xff0c;获取请求头上的用户ID&#xff0c;加入到ThreadLocal中。 最…

C++:函数

函数参数的传递机制 C的每个程序至少有一个函数&#xff0c;即主函数main()&#xff0c;函数也是类的方法的实现手段。C的函数包括两类&#xff1a;预定于函数和用户自定义函数。 函数的定义格式为&#xff1a; <返回值类型><函数名>(<参数列表>) <函…

深入解析:树结构及其应用

文章目录 学习树的基本概念理解树的遍历方式学习堆和优先队列的应用案例分析&#xff1a;使用堆进行Top K元素的查找结论 &#x1f389;欢迎来到数据结构学习专栏~深入解析&#xff1a;树结构及其应用 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈…

Python HTML解析新玩法:掌握BeautifulSoup4从入门到精通

介绍 BeautifulSoup4是Python中一个强大的第三方库&#xff0c;用于解析HTML和XML文档&#xff0c;并提供了简单又灵活的方式来遍历文档树、搜索文档元素以及提取所需信息。BeautifulSoup4的功能使得在Python中进行网页数据抓取和解析变得非常方便。本文将从入门到精通地介绍B…

556、Vue 3 学习笔记 -【常用Composition API(五)】 2023.08.25

目录 一、生命周期二、自定义hook函数三、toRef四、参考链接 一、生命周期 Vue3中可以继续使用Vue2中的生命周期钩子&#xff0c;但有两个被更名&#xff1a; beforeDestroy改名为beforeUnmountdestroy改名为unmounted Vue3也提供了组合式API形式的生命周期钩子&#xff0c;…

Redis三种持久化方式详解

一、Redis持久性 Redis如何将数据写入磁盘 持久性是指将数据写入持久存储&#xff0c;如固态磁盘&#xff08;SSD&#xff09;。Redis提供了一系列持久性选项。其中包括&#xff1a; RDB&#xff08;快照&#xff09;&#xff1a;RDB持久性以指定的时间间隔执行数据集的时间点…

前端Vue3框架知识点大全

Vue.js是一种流行的JavaScript前端框架&#xff0c;它的第三个版本Vue3带来了许多令人兴奋的新特性和改进。 1、响应式数据&#xff1a; Vue 3采用了基于Proxy的响应式系统&#xff0c;相比Vue 2中的Object.defineProperty&#xff0c;Proxy提供了更强大和灵活的拦截器&#…

【AUTOSAR】【CAN通信】CanNm

目录 一、概述 二、说明 三、功能说明 3.1 协调算法 3.2 操作模式 3.2.1 网络模式

Stable Diffusion 系列教程 | 如何获得更高清优质的AI绘画

目录 1 高清修复 1.1 原理 1.2 基本操作 1.3 优缺点 2 UpScale 放大脚本 2.1 原理 2.2 基本操作 2.3 优缺点 3 附加功能放大 3.1 原理 3.2 基本操作 3.3 优缺点 优化出图质量&#xff0c;产出更高清&#xff0c;分辨率更高&#xff0c;更有细节的绘画作品呢&#x…

B. Burning Midnight Oil

Problem - B - Codeforces 问题描述&#xff1a;给定n和k&#xff0c;求满足以下条件的最小的v。 n ≥ ∑ i 0 ∞ [ v k i ] n \ge \sum_{i0}^{\infty}[ \frac v {k^i}] n≥i0∑∞​[kiv​] 具有单调性&#xff0c;用二分。二分答案&#xff0c;最大值最小。 代码&#xff…

Nexus 如何配置匿名用户访问一个仓库

现在有这样一个需求&#xff0c;我们需要匿名用户访问 Nexus 的一个公共仓库。 设置 Roles 在满足这个需求之前&#xff0c;我们需要设置一个 Roles。 Role 的名字是可以随填写的。 这里关键的问题在你需要访问的仓库的 View 的权限需要设置 Read 和 Browse 这 2 个权限。 如…

08-信息收集-架构、搭建、WAF等

信息收集-架构、搭建、WAF等 信息收集-架构、搭建、WAF等一、前言说明二、CMS识别技术三、源码获取技术四、架构信息获取技术五、站点搭建分析1、搭建习惯-目录型站点2、搭建习惯-端口类站点3、搭建习惯-子域名站点4、搭建习惯-类似域名站点5、搭建习惯-旁注&#xff0c;c段站点…