如何使用图形管线基于密度函数渲染体积数据?


12

两种图形API(OpenGL和DirectX)都设计了明确定义的管道,其中几个阶段都可以编程。这些可编程阶段需要获取固定的最小数据量,并应在其上进行明确定义的操作范围,并输出一些已定义的最小输出,以便可以将数据正确地传递到下一个阶段。似乎这些流水线被设计为仅使用有限数量的几何数据类型,对于D3D和OGL而言,它们都是顶点数据和纹理坐标。

但是,如果我打算制作的应用程序在某种情况下不使用顶点(甚至是体素)来表示其几何数据,并且不完全进行变换或投影,栅格化或插值等操作,则API的局限性否则管道会使事情变得困难。

那么,是否有一种方法可以改变图形管道,从而使每个阶段对数据执行的功能以及每个阶段输出的数据类型都对我有利?如果没有,那么有没有办法我可以使用“原始” API函数来构建自己的管道?如果没有,请说明为什么不可能。

编辑:我的应用程序使用密度函数来表示几何。该函数在空间的每个点都有一个值。我将相机的视锥台分为3d网格,每个块可以投影为一个像素。在每个块上,我集成密度函数,并检查其值是否大于要求的值。如果是,则假定该块中存在某些东西,并且渲染与该块相对应的像素。因此,现在在渲染器中,我希望将函数(用字符串表示)传递给图形硬件,而不是传递顶点缓冲区中的顶点数据。这也意味着顶点着色器将没有顶点可以转换为同质的剪贴空间,并且片段着色器不会获取像素信息。取而代之的是,现在大多数查找和评估都针对每个像素进行。


“功能密度函数”是重言式吗?
法拉普2014年

@Pharap,那是一个错字。其简单的“神性功能”代表了空间中“物质”的存在。
The Light Spark

2
听起来您只想构建一个等值面,这是一个经过充分研究的问题。您是否看过http.developer.nvidia.com/GPUGems3/gpugems3_ch07.html或在Metaballs上搜索,点云可视化,等值面提取或体绘制?另外,您需要什么样的性能,当与计算的复杂性相结合时,这将在搜索技术选择时产生巨大差异。我认为您还会发现,当相机移动时,每个像素会引起闪烁,并且需要子像素。
Patrick Hughes 2014年

Answers:


18

您可以绝对使用GPU渲染体积数据。

由于您要评估屏幕上每个像素的一组功能,因此一种简单的方法是渲染全屏三角形。这只是覆盖整个屏幕的单个三角形(实际上,它覆盖的范围大于屏幕,因为屏幕不是三角形的,但屏幕外的部分被GPU丢弃了)。然后,您可以使用像素着色器(接收其阴影像素的屏幕坐标)来构造穿过体积的射线,评估功能,无论您需要做什么。

(与其他答案相反,我不推荐使用计算着色器,因为听起来您想按像素进行操作,并且全屏三角形+像素着色器通常比计算着色器更有效,尽管计算着色器当然也可以使用。)

全屏三角法在实时图形中用于后处理操作非常普遍,因此您可以通过使用Google谷歌搜索来找到所需的所有信息。

顺便说一句,您可能会喜欢IñigoQuílez的“ 具有两个三角形渲染世界”一书,该演讲描述了如何使用全屏像素着色器技术渲染使用数学函数(特别是距离场)组成的3D场景。


那么像素着色器是否可以接受任意输入(例如字符串或其他类型的用户定义对象),以便我可以传递函数?
The Light Spark

我怀疑您是否想尝试在GPU上的任意函数字符串上运行解析器和/或语言,这会很尴尬,因为GPU并不是真正的通用目的。您很可能希望在主代码中动态创建着色器本身,然后让图形系统编译并运行生成的着色器。
Patrick Hughes

@TheLightSpark对,您不会将字符串传递给着色器(着色语言甚至没有字符串类型),而是希望生成并编译所需功能的着色器代码。必要时可以在运行时完成。
内森·里德

开始阅读您的答案后,我想到了一个三角形的监视器;)仅使用一个三角形而不是两个覆盖屏幕而不丢弃像素的三角形是否有优势?
danijar

@danijar是的,它比使用四边形有一点优势,因为如果使用全屏四边形,沿对角线的某些像素将被着色两次。另一方面,舍弃屏幕外像素是免费的,因为光栅化器将不会生成这些像素。
内森·里德

6

光线跟踪和其他技术通常由Compute Shaders完成,自D3D11发行以来,Direct3D就已支持该技术,而自4.3起,OpenGL已受支持(以及通过使用OpenCL和某些变形而更长的时间)。


5

听起来非常像您想使用GPU计算着色器,或利用“ Shader Storage Buffer”对象来帮助扩展满足您需求的管道。数学家,科学家和其他依靠GPU进行计算的对象,这些对象并未完全转换为标准图形,而使用这种东西。

尽管现代图形处理管道非常灵活,但是开发人员仍然倾向于在某些限制上绊倒。但是,计算着色器功能使我们更容易生活,因为我们习惯于考虑顶点和片段,因此无需考虑流水线阶段。我们不再受某些管道阶段的输入和输出的限制。例如,Shader存储缓冲区对象(SSBO)功能已与计算着色器一起引入,它为在流水线级之间交换数据提供了更多可能性,并且为计算着色器提供了灵活的输入和输出。

http://community.arm.com/groups/arm-mali-graphics/blog/2014/04/17/get-started-with-compute-shaders

如果这不能为您指明正确的方向,您是否会介意扩展不适合顶点/片段范式的概念?


我编辑了答案以包括我在做什么。计算着色器似乎是答案,但是只要告诉我是否还有其他事情可以做。
The Light Spark
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.