我试图创建一个合理的交互式N体模拟,其新颖之处在于能够从其中一个物体的表面观察模拟。我的意思是,我有一些随机放置的质量很大的"恒星",它们的速度是随机的,而质量较小的"行星",它们的初始圆周速度是给定的。通过Linux上的OpenGL和Windows上的DirectX11进行实时操作。
我的问题是关于渲染场景,而不是N体模拟。我有一个非常有效/准确的求解器工作,现在,它总是可以改善以后不影响渲染。
问题很明显的出现了,恒星之间的距离非常远,因此碎片着色器无法渲染遥远的恒星,因为它们的大小只有像素的几分之一。使用对数深度缓冲区可以很好的站在行星上看月亮和主恒星,但是我真的很难处理遥远的恒星。我对"假装"它不感兴趣。或者渲染一张以玩家为中心的星图,因为重点是能够实时查看模拟。Aidokyanda你的星球绕着轨道运行的恒星距离你约1 e6米,被渲染为一个球体,因为它的半径约1 e4米。其他恒星距离你约1 e8米,因此,它们显示为远Z平面约为1e13的单个发光像素(有时)。
我想我有一个想法/计划,但我认为它涉及到我还不知道的知识/技术。
理由:
1.在给定帧上具有恒星的世界空间
1.这给了我们"屏幕"空间,或碎片位置,恒星的质心在碎片着色器
1.我们可以尝试模仿眼睛的实际动作,而不是将其渲染为缩放球体:将这个点(像素)与一个艾里圆盘(或者高斯或者任何最有效的方法,都没关系)卷积,这样星星就被渲染成天空中的"模糊",它们的"大"取决于它们的亮度和距离(本质上是免费重新创建星等系统)
1.从理论上讲,这将使我能够随意改变我的Airy光盘的"镜头"参数,以便制作出看起来相当准确/艺术的东西。
问题是:我不知道如何达到这种模糊效果!
我对着色器有一些基本的了解,目前正在进行不同的渲染过程,但这似乎涉及到我没有偶然发现的事情,甚至如何实现这种效果。
TLDR:给定一个片段位置的输入,我如何在一个片段/像素着色器中使用一个airy disc/gaussian/等来模糊它?
我原以为对数深度缓冲器会在一开始起作用,但显然这只对z轴战斗有帮助,而对远距离物体的Angular 大小没有帮助。
1条答案
按热度按时间x759pob21#
你想太多了。对于小于一个像素的星星,只需要用艾里圆盘纹理渲染一个正方形就可以了。这不是“伪造”--这正是计算机图形的工作原理。
如果透镜直径发生变化,则计算新的艾里斑纹理。
对于只有几个像素大的恒星(它们存在吗?)也许你想渲染一个与艾里斑卷积的几个像素的球体,然后使用该纹理。要求GPU每帧都做卷积是浪费时间,除非你真的需要它。如果大小真的只有几个像素,你可以选择渲染几个单像素纹理的副本,重叠本身和1个像素的距离。虽然计算纹理将允许您有精度小于一个像素,如果这是你需要的东西。
对于附近的恒星,每个像素的艾里圆盘加起来会形成一个光环,我想?然后你就可以渲染一个光环,而不是做卷积。我发誓,这不是作弊。
如果你真的想做卷积运算,你可以直接做:通过使用帧缓冲区将所有内容渲染到纹理中,然后使用着色器将该纹理渲染到屏幕上,着色器读取几个相邻的纹理像素,并将它们乘以内核。由于这是针对每个像素乘以内核大小运行的,因此它很快就会变得昂贵,您想要采样的用于卷积的像素越多,所以你可以跳过一些,使它近似。如果你不做实时渲染,那么你可以使它慢,因为你想要的,当然。
当游戏开发者做高斯模糊(很常见)或方块模糊时,他们会做一个单独的X模糊和Y模糊。这是因为X模糊和Y模糊的卷积是一个2D模糊,但我不知道这是否适用于艾里斑函数。它最小化了卷积采样的像素数。