假设您要在3D场景中制作简单的雨/雪/尘/星空效果。将单个雨滴,雪花,尘埃或恒星作为场景层次中的单个节点会太慢。
另一种解决方案是使用某种粒子系统,该系统使用在所有方向上生成无限恒星的公式,在相机周围生成粒子立方体。对于这种情况,我有效地使用了
for N particles
particlePos = cameraPos +
euclideanModulo(pseudoRandomVector(0, 1) - camerPos, 1) *
boxSize - boxSize / 2;
此系统的问题在于,大多数粒子都在视图之外。
此处相机是中央的绿点。它绕Y轴旋转。显示了视锥。浪费很大,因为85%的粒子不在视锥中。
另一种解决方案是找到始终包含上面boxSize
的视锥的最大边框(这是一个较小的框),然后使用框的最小角代替位置来代替摄像机的位置>
boxSize = sizeOfAxiallyAlignedBoxThatContainsTheFrustumAtAnyOrientation()
minCorner = minCornerOfFrustumAtCurrentOrientation()
for N particles
particlePos = minCorner +
euclideanModulo(pseudoRandomVector(0, 1) - minCorner, 1) *
boxSize;
效果更好,因为现在浪费了更少的粒子。上面的两个图像都绘制了200个粒子,您可以看到在此版本中,视锥中的数字更加密集
看起来仍然有30%的粒子仍在视锥之外。实际上,随着截锥角的扩大,情况变得更加糟糕。
现在,我们回到了平截头体之外的大多数粒子。
如果不清楚,粒子需要相对于相机保持静态(如果它们不移动),那么至少就目前的算法而言,我认为我无法做得更好。将粒子移入或移出视锥将使密度根据视图方向发生变化。
由于这个原因,200个粒子散布在一个盒子中,该盒子的大小与在任何方向上始终包含视锥的最小盒子的大小相同。当平截头体为长方形时,该框会变得比平截头体的任何单个方向都大得多,因为有时平截头体会又高又瘦,而有时会又宽又短。
是否有任何解决方案可以浪费更少的颗粒,但仍保持相对于相机的静态位置相同的属性?