生成用于视锥的最佳过程3D粒子集

时间:2019-02-27 07:40:55

标签: glsl shader hlsl vertex-shader geometry-shader

假设您要在3D场景中制作简单的雨/雪/尘/星空效果。将单个雨滴,雪花,尘埃或恒星作为场景层次中的单个节点会太慢。

另一种解决方案是使用某种粒子系统,该系统使用在所有方向上生成无限恒星的公式,在相机周围生成粒子立方体。对于这种情况,我有效地使用了

for N particles
  particlePos = cameraPos + 
                euclideanModulo(pseudoRandomVector(0, 1) - camerPos, 1) * 
                boxSize - boxSize / 2;

此系统的问题在于,大多数粒子都在视图之外。

此处相机是中央的绿点。它绕Y轴旋转。显示了视锥。浪费很大,因为85%的粒子不在视锥中。

enter image description here

另一种解决方案是找到始终包含上面boxSize的视锥的最大边框(这是一个较小的框),然后使用框的最小角代替位置来代替摄像机的位置

boxSize = sizeOfAxiallyAlignedBoxThatContainsTheFrustumAtAnyOrientation()
minCorner = minCornerOfFrustumAtCurrentOrientation()

for N particles
  particlePos = minCorner + 
                euclideanModulo(pseudoRandomVector(0, 1) - minCorner, 1) * 
                boxSize;

enter image description here

效果更好,因为现在浪费了更少的粒子。上面的两个图像都绘制了200个粒子,您可以看到在此版本中,视锥中的数字更加密集

看起来仍然有30%的粒子仍在视锥之外。实际上,随着截锥角的扩大,情况变得更加糟糕。

enter image description here

现在,我们回到了平截头体之外的大多数粒子。

如果不清楚,粒子需要相对于相机保持静态(如果它们不移动),那么至少就目前的算法而言,我认为我无法做得更好。将粒子移入或移出视锥将使密度根据视图方向发生变化。

由于这个原因,200个粒子散布在一个盒子中,该盒子的大小与在任何方向上始终包含视锥的最小盒子的大小相同。当平截头体为长方形时,该框会变得比平截头体的任何单个方向都大得多,因为有时平截头体会又高又瘦,而有时会又宽又短。

是否有任何解决方案可以浪费更少的颗粒,但仍保持相对于相机的静态位置相同的属性?

0 个答案:

没有答案