【问题标题】:How to render point sprites in 3D space among other objects如何在其他对象之间渲染 3D 空间中的点精灵
【发布时间】:2018-04-13 08:18:42
【问题描述】:

渲染混合点精灵和 3D 对象的最佳方式是什么?

例如,我想将“太空尘埃”粒子建模为点精灵。在太空中,我可以有大的小行星物体(为简单起见是立方体),太空尘埃颗粒可能位于小行星立方体的前面或后面。

我被两种情况困住了:

  1. 我先渲染空间尘埃点精灵,使用gl_DepthMask(GL_TRUE),然后渲染小行星立方体(空间尘埃总是小行星之后)
  2. 我先渲染小行星立方体,使用gl_DepthMask(GL_FALSE),渲染空间尘埃点精灵并设置gl_DepthMask(GL_TRUE)(空间尘埃总是出现在小行星前面)

我目前正在使用单个粒子发射器顶点着色器,该着色器在随机 (x,y,z) 位置绘制大量带有gl_DrawArrays() 的粒子。

如何渲染大量粒子,使它们同时出现在小行星立方体的前后?

如果我的粒子是单独的四边形,那么我可以对 Z 渲染的顺序进行排序,但我不知道如何使用 gl_DrawArrays()GL_POINTs 和我的顶点着色器来实现这种行为。

我是否应该将粒子拆分为数组集?例如,我是否必须这样做:

  1. 绘制所有小行星背后的粒子阵列
  2. 将小行星拉到最远的地方
  3. 绘制另一个粒子阵列,这些粒子出现在上面的小行星前面,但在下一个最近的小行星后面
  4. 画出最前面的小行星

如果我有很多小行星,这不是非常低效吗?

与我上面的建议相比,OpenGL 肯定有更好的方法来实现这一点?

更新:尝试 Thomas 的建议:

我的立方体和粒子使用以下混合/深度调用进行渲染:

  // First render opaque object(s)
  glEnable( GL_DEPTH_TEST );
  glDepthMask( true );
  g_ObjCube1.Render();

  // Now render sprites with particle emitter - sprites should appear
  // behind and in front of above cube
  glEnable( GL_POINT_SPRITE );

  // Stop overlapping particles from interfering with each other
  //glDisable( GL_DEPTH_TEST );  <- NO! Must leave depth test enabled
  glDepthMask( false );

  glEnable( GL_BLEND );
  //glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  glBlendFunc( GL_SRC_ALPHA, GL_ONE );    // Doing the same as above
  glBlendEquation( GL_FUNC_ADD );
...
  glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
...
  glDepthMask( true );

【问题讨论】:

    标签: opengl fragment-shader vertex-shader glm-math geometry-shader


    【解决方案1】:

    我假设你的粒子有一定的透明度,否则不会有问题。

    然后答案与所有​​透明对象相同。首先渲染不透明物体(小行星)(使用深度缓冲,以任意顺序)。然后按从后到前的顺序渲染所有透明对象。这个排序(据我所知)需要在 CPU 上完成。

    或者,根据您的目标效果,您可以对粒子使用添加剂混合 (glBlendFunc(GL_SRC_ALPHA, GL_ONE))。然后渲染顺序无关紧要,因为加法是可交换的。请务必为此禁用深度写入。

    作为另一种选择,使用 alpha 测试(真/假)而不是 alpha 混合可以让您以任意顺序渲染粒子。在这种情况下,完全透明的像素不会被写入深度缓冲区。但是,使用这种技术时,您不能有部分透明的区域。

    This article 是一个很好的参考。

    【讨论】:

    • 是的,粒子确实具有透明度。我实际上正在渲染小的圆形斑点。我真的很想学习如何结合其他实体对象来实现粒子。例如,如果我有彗星,这将由一个“小行星”和一个尾巴或粒子组成。如果这颗彗星穿过小行星流,那么我需要在一些小行星前面和其他小行星后面渲染彗星的尾巴。如果有数千个粒子组成一条气态尾巴,这真的会在 CPU 上完成吗?对不起,我是这一切的初学者。
    • 添加了另一种可能的方法。
    • 感谢您的链接。我将不得不做更多的阅读。我很快尝试了您的 GL_ONE 混合建议(请参阅问题更新),但我仍然得到相同的结果。目前,所有点精灵都在我的不透明对象之上渲染。
    • 这不应该发生。您是否不小心禁用了深度 testing 而不是深度 writing
    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 2019-03-27
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 2018-02-25
    相关资源
    最近更新 更多