OGL 4+/ GLSL / C++ - 尾随行星轨道

Posted

技术标签:

【中文标题】OGL 4+/ GLSL / C++ - 尾随行星轨道【英文标题】:OGL 4+/ GLSL / C++ - Trailing planetary orbits 【发布时间】:2014-09-19 23:09:24 【问题描述】:

我正在研究一个太阳系模拟器,现在正试图弄清楚如何在 C++ / OpenGL / GLSL 中做类似这样的尾随轨道:

Reference

问题在于我没有静态轨道,行星的位置每帧都会更新。

所有行星都从一个类中实例化。我有一个想法如何做到这一点,但不确定它在技术上是否可行。

请指教(是为了改进我的想法还是更好的东西)。

概念

    有一个具有特定顶点数据集的 VBO,例如 8 个顶点 创建描述每个连续点之间联系的 IBO

这个想法是有一个顶点的“跑步机”,第一个与行星一起移动:

IBO : [ 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 ]

---------------^ 使 glsl 只更新 vbo 中的第一个元素,这意味着在 vbo 中:

VBO : [ v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 ]

---------------^ 每次渲染调用要更新的当前顶点

    那么随着行星 & v1 从 v2 移动设定距离 D

将最后一个顶点位置设置为下一个轨道位置,即在链中向前移动:

IBO : [ 8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ]

----------------^ 当前要更新的索引,在 vbo 中表示:

VBO : [ v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 ]

----------------------------------- --------------------------^ 每次渲染调用要更新的当前顶点

这有意义吗?我真的很喜欢重用顶点的想法,给他们一生(褪色)然后..重新链接吗?甚至可以在 GPU 级别操作索引缓冲区吗?

也许我的想法只是徘徊在一条愚蠢的小巷里,也许这里有人有更好的主意?

【问题讨论】:

你过度优化了。传递十几个顶点来组成“尾随轨道线”在总体方案中是微不足道的数据量,因此每帧将整个缓冲区从 CPU 传递到 GPU 不会减慢渲染速度(假设你是渲染,10 或 100 颗行星,而不是数百万)。是的,您可能可以以这种方式实现循环缓冲区,但增加的复杂性不值得任何性能提升。 我同意,我继续预分配一个圈子,现在正试图弄清楚如何更新每个位置......这被证明是相当困难的...... 【参考方案1】:

我真的不明白你想用这段代码做什么,但据我所知,当你改变 IBO 时,你实际上改变了构成几何图形的三角形的顺序,如果你有动画的问题行星的位置,那么解决方案就很靠前了,

for each planet

glUniformMatrix4fv(matLocation, 1, GL_FALSE/*Or GL_TRUE depends on you implementation*/, planet.getModelMatrix());
planet.Render();

顶点着色器看起来像:

...
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
...

void main() 
...
gl_Position = projMatrix*viewMatrix*modelMatrix*in_vertexPosition;
...

如果这不是您想要的,那么请再详细说明一下!

【讨论】:

不,每个行星的位置已经计算过了,这与网格几何无关。相反,我想画一条尾随轨道线 - 即每个行星物体的运动线,一个圆圈是最简单的情况。但是想象一个圆圈,其中每个部分都会随着行星远离它而逐渐消失(参见我帖子中的参考图片)。这个想法是以某种方式重用旧的顶点,将最后一个移到链上。 aah 好的,你知道了,你想创建行星运动后留下的线条吗?我要做的是创建新的 VBO 来保存线数据,(在简单线的情况下开始和结束,在贝塞尔线的情况下有很多顶点)并渲染它们。 你的意思是每帧创建一个新的VBO?我们已经缩小了我丢失的范围:如何更新 VBO?现在我认为问题在于让地球越过一条铁路,它前面的轨道“没有更新”,而它后面的轨道是什么。所以我的想法就是你在上面看到的,将最后一个顶点向上移动并以某种方式重新链接——这是否过于复杂? ...这可能意味着更改索引缓冲区,每次更新时说“这就是现在链接点的方式”.. 跟进我之前的评论:另一种方法是只使用一个椭圆点,这消除了内存中只有可见点的优化,但仍然 - 如何更新特定索引那么VBO呢?我是否以某种方式标记每个顶点.. 我不是 VBO 专家,我的大脑仍然倾向于用 CPU 代码思考。 好的,如果这是您想要扩展的想法并且您正在关注性能并且想要消除不可见的对象,那么您想要使用批处理,因为它是绘制小精灵的最简单但最有效的方法,因此您将更新 CPU 中的点数组,然后使用 glSubBufferData(...) 或更有效的方式将它们发送到 GPU,然后可能使用几何着色器来读取要渲染的点和输出线。现在,如果您有兴趣,可以联系我提供批处理的代码示例(抱歉没有 github 帐户)。

以上是关于OGL 4+/ GLSL / C++ - 尾随行星轨道的主要内容,如果未能解决你的问题,请参考以下文章

GLSL中的动态VBO读/写?

GLSL 大气散射不随变换缩放

如何使用 OpenGL 和 GLSL 改变颜色(C++)?

从 C++ 运行 GLSL 着色器(尚未编译)的最快捷方式是啥?

如何在 C++ 中为 GLSL 片段着色器实现 iGlobalTime?

我的OpenGL学习进阶之旅如何抽取着色器代码到assets目录下的GLSL文件,以及如何通过Java或者C++代码来加载着GLSL文件?