在重新观看了Bisqwit的星场渲染器视频之后,我决定尝试重写这个程序,以便了解更多关于计算机着色器和着色器编程的知识。我在这一点上的知识仅限于中等简单的顶点和像素着色器。最初的程序是一个软件渲染器,它用BASIC的某个变体来绘制每个框架,大致如下:
for every rendered star:
update the star's position in the world
calculate the star's position on the screen
calculate the star's size on the screen
for every pixel of the screen:
for every star of the screen:
calculate the influence of the current star on the color of the current pixel
do dithering
draw the pixel in the resulting color我试着把它转换成一个电脑着色器,它绘制到一个纹理,然后使用全屏四角体呈现。抛开这种方法的明显问题不谈,我有点迷茫了。透视诽谤。我应该在哪里做他们,在CPU或GPU?有什么合适的机制来防止重复计算?我无法通过我的研究找到一个,所以每一个指向解决方案的指针都会受到赞赏。
编辑:
我想我可能有点不清楚什么是“轻球”/“明星”:它只是世界上的某个点,是以一种奇特的方式呈现出来的,而不是一个模型。
编辑2:感谢答案和注释中的所有指针,我决定使用两个计算着色器。一种是进行透视计算,另一种是将结果绘制到纹理上,纹理被呈现到全屏四角体上。从不太理想的性能来看,使用类似@Thomas的评论中概述的方法可能会更好,但这是另一个问题。
发布于 2023-03-08 14:13:55
首先,简单介绍一下你需要的矩阵。
perspective projection感兴趣。所以你的相机有一个圆柱体,就像一个截短的pyramid.The,金字塔的顶端就在你的相机里面。金字塔的脚就是你看到的地方。金字塔内部的一切都是可见的,金字塔之外的一切都是不可见的。像field of view``aspect ratio``near clipping plane和far clipping plane这样的信息被编码到这个矩阵中。只要这些参数不改变,就可以重用这个矩阵。当在3D空间中有一个点(顶点)时,你可以将它作为一个四维向量存储,方法是将数字(1)添加到第4维。就像这样:vector4d(positionX, positionY, positionZ, 1)。这被称为homogeneous coordinate
正如您注意到的,我们有4x4矩阵和一个4分量向量。所以我们可以把它们相乘,得到另一个四维向量。你可以这样做:
vertexWorldSpace = modelMatrix * vertex4D --这将你的顶点从模型空间转换成世界空间。
vertexViewSpace = viewMatrix * vertexWorldSpace --这可以将顶点从世界坐标空间转换为查看空间。
vertexScreenSpace = projectionMatrix * vertexViewSpace --将视图空间坐标转换为屏幕空间坐标。通常,您必须将结果除以其第四个组件,但是OpenGL和direct3D在将位置从顶点传递到像素/片段着色器时为您完成了这一任务。
现在,您可以将这些乘法写成一个等式:
因为所有的矩阵都可以组合成一个矩阵
这个modelViewProjectionMatrix可以加载到GPU,模型中的每个顶点都可以乘以这个矩阵来接收屏幕坐标。
矩阵乘法应尽量避免在GPU上使用。这意味着,不要把所有的矩阵都移到GPU去把它们相乘.您可以在CPU上进行乘法以接收modelViewProjectionMatrix。然后将此矩阵存储到GPU,以便每个顶点只进行一个矩阵乘法。thump规则:将矩阵的各个部分合并成一个矩阵,该矩阵将等于呈现调用中的所有顶点。请记住:矩阵乘法不是累积的。所以A*B不是B* A!
有一个非常好的OpenGL教程关于矩阵演算在计算机图形学OpenGL矩阵教程。请注意,direct3D和vulkan使用不同的坐标.因此,如果使用direct3D或vulkan,请使用另一个教程。但原则上,它的工作方式是一样的。
在你的情况下,计算着色器应该计算每颗恒星的新位置(世界空间)。之后,您可以通过使用顶点着色器来应用modelViewProjectionMatrix和像素/片段着色器对结果进行着色来呈现结果。
https://computergraphics.stackexchange.com/questions/13357
复制相似问题