使用CUDA绘制三角形

7
我正在编写自己的图形库(是的,这是我的作业 :)),并使用CUDA快速进行所有渲染和计算。我在绘制填充三角形时遇到了问题。我将其编写为一个进程绘制一个三角形的方式。当场景中有许多小三角形时,它的效果非常好,但当三角形很大时,性能会完全崩溃。我的想法是进行两次通行。首先只计算有关扫描线(从这里到那里绘制)的信息表。这将是类似于当前算法中每个进程的三角形计算。然后在第二遍通行中,真正绘制具有一个以上进程的三角形的扫描线。但这样做是否足够快?也许有更好的解决方案吗?
3个回答

3
您可以查看这个博客:使用CUDA的软件渲染流水线。我不认为这是最优的方法,但至少作者分享了一些有用的资源。
其次,阅读这篇论文:可编程、并行渲染架构。我认为这是最近发表的论文之一,也是基于CUDA的。
如果我要做这个,我会选择像Larrabee(TBR)或甚至REYES中的数据并行光栅化流水线,并将其适应于CUDA: http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip(请参见演示文稿的第二部分) http://graphics.stanford.edu/papers/mprast/

0

我怀疑您对CUDA及其使用方式存在一些误解,尤其是当您提到一个“进程”时,在CUDA术语中并不存在这样的东西。

对于大多数CUDA应用程序来说,获得良好性能有两个重要因素:优化内存访问和确保warp中每个“活动”的CUDA线程同时执行相同操作。这两个方面都似乎很重要,也与您的应用程序相关。

为了优化内存访问,您需要确保从全局内存读取和写入全局内存的操作是合并的。您可以在CUDA编程指南中了解更多信息,但这实质上意味着,半个warp中相邻的线程必须从相邻的内存位置进行读或写操作。此外,每个线程应该每次读取或写入4、8或16个字节。

如果您的内存访问模式是随机的,则可能需要考虑使用纹理内存。当需要引用块中其他线程已读取的内存时,应使用共享内存。

在您的情况下,我不确定您的输入数据是什么,但您至少应该确保您的写操作是合并的。获取高效的读取也可能需要投入一定的努力。

对于第二部分,我建议每个CUDA线程处理输出图像中的一个像素。使用这种策略时,您应该注意内核中的循环,这些循环将根据每个线程的数据执行更长或更短的时间。warp中的每个线程应按相同顺序执行相同数量的步骤。唯一的例外是,如果warp中有一些线程不执行任何操作,而其余线程一起执行相同的操作,则没有真正的性能惩罚。
因此,我建议每个线程检查其像素是否在给定的三角形内。如果不是,则不执行任何操作。如果是,则计算该像素的输出颜色。
此外,我强烈建议阅读更多关于CUDA的资料,因为似乎您在没有充分理解一些基本原理的情况下就跳入了深水区。

1
抱歉我的语言表达不好,英语不是我的母语。那么在图形卡上进行处理的正确术语是什么?嗯,我认为我对CUDA相当了解,但是我在并行算法方面缺乏知识。我的输入是剪辑空间中的一组顶点,我必须绘制三角形。我认为每个像素都要检查每个三角形的算法不会是最优的。 - qba
避免检查每个三角形的每个像素可以通过使用BVH、KD-Tree或R-Tree对三角形进行分区来实现。 - whatnick

-1

不是要无礼,但这不是图形卡本来就设计用来做的吗?使用标准的OpenGL和Direct3D API似乎更有意义。

为什么不使用API来进行基本渲染,而不是使用更低级别的CUDA?然后,如果您希望执行不受支持的其他操作,可以使用CUDA在其上应用它们。或者将它们实现为着色器。


是的,确实如此。但他在这里的目标是构建一个不使用传统API的图形光栅化管道。可以将其视为概念验证或教育目的项目。 - elmattic
是的,这是我为研究而做的项目。我们必须自己完成所有的光栅化工作。大多数人使用CPU,但我决定使用CUDA。 - qba
嗯,在那种情况下,这听起来像是一个有趣的项目。虽然有点反向思维,但仍然很有趣。 - BobMcGee
是的,直到现在我一直试图避免在OpenGL编程中使用矩阵,但现在我不再害怕它们了:> - qba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接