gpt4 book ai didi

c# - 在游戏中使用正确的多线程

转载 作者:行者123 更新时间:2023-11-30 14:55:17 25 4
gpt4 key购买 nike

我目前正在开发一款模拟可变形 3D 对象的 3D 游戏。对于可变形,我的意思是 3D 对象的几何形状在帧与帧之间发生变化。游戏中有一个渲染循环,应该尽可能频繁地执行(至少 30 次/秒)以获得下降帧率。但我还在这个渲染循环中做另外两件事:计算新几何体和计算轴对齐边界框层次结构 (AABVH)。我需要 AABVH 来进行碰撞检测。在渲染 3D 对象之前完成几何和 AABVH 计算非常重要。计算新的几何图形和 AABVH 是一项耗时的任务,因此我的帧率迅速下降。因此,我的想法是在单独的线程中计算 AABVH。这看起来像这样:

Thread t;
public void Render(Object3D o) // renders 3D object
{
if (t != null) // wait until the new geometry got calculated
{
t.Join();
}
o.RenderGeometry();
t = new Thread(() => o.CalcAABVH());
t.Start();
}

我不是 C# 并行编程方面的专家,但我确信这不是一个好的解决方案。每一帧,都会创建、执行和销毁一个新线程,这会导致很大的开销。在我的案例中,一个好的解决方案会是什么样子?

最佳答案

在更新几何体时,您不应该阻止下一帧的渲染。您也可以同步运行计算。阻止渲染会增加每帧的总渲染时间并对帧率产生负面影响 - 这是您特别要避免的效果!

相反,使用一个标志来指示新几何体的计算是否正在进行,如果是,则渲染旧几何体。现在您需要 2 个几何体集 - 就像使用帧缓冲区一样,当新几何体完成时交换它们。

最终结果是某些框架可能没有您希望的最新几何体可用。这在几何体计算时间较长的对象上会更加明显。大多数游戏的图形编程都是雾里看花,所以不要担心。

实现

请为这些更新操作使用线程池线程,因为创建成本较低。理想情况下,使用任务并行库。作为奖励,Task 对象会为您跟踪其运行状态!

    using System.Threading.Tasks;

...

Task t;
public void Render(Object3D o) // renders 3D object
{
if(t != null && t.Status == System.Threading.Tasks.TaskStatus.Running)
{
//render old geometry
}
else
{
t = Task.Factory.StartNew(o.CalcNewGeometry())
.ContinueWith(p => o.UpdateGeometry); //swap the new geometry in
}
}

您需要在此处进行一些同步,以确保在渲染旧几何体时不会换入新几何体。我会把它留给你。

关于c# - 在游戏中使用正确的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25761226/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com