在虚幻引擎中运行时编辑顶点位置的有效方式



我正在寻找一种方法,从C++代码中更新具有65536个顶点的网格的每个顶点的顶点位置。它需要每隔几帧用代码中计算的值进行更新,因此它需要有一定的效率。

我试过了,但没有效果:

if (NewElement->GetStaticMeshComponent()->GetStaticMesh()->RenderData->LODResources.Num() > 0)
{
FPositionVertexBuffer* VertexBuffer = &NewElement->GetStaticMeshComponent()->GetStaticMesh()->RenderData->LODResources[0].VertexBuffers.PositionVertexBuffer;
if (VertexBuffer)
{
const int32 VertexCount = VertexBuffer->GetNumVertices();
for (int32 Index = 0; Index < VertexCount; Index++)
{
VertexBuffer->VertexPosition(Index) += FVector(float(Index), float(100* Index), float(10000 * Index));
}
}
}

我将感谢您帮助我找到一个有效的解决方案。

就目前而言,我正在寻找一个简单的解决方案,只是从一些事情开始。但我知道,更新网格CPU端不是最有效的方法,所以计算每个顶点的位置,然后将其传递给顶点着色器可能会更容易/更快?或者生成一些伪纹理,将其上传到GPU并在顶点着色器中使用?有人在UE中有这样的机制的例子吗?

问候

您的代码实际上不会向GPU推送任何更新。你在这里使用的是一个静态网格,它实际上并不打算在运行时修改顶点,因此";静态";绰号。这并不是说你不能在运行时修改这些数据,但这不是你在这里要做的。您的代码只是在更改CPU端的数据。

如果你仔细查看引擎代码中实现的各种顶点缓冲区,你会发现它们最终都扩展了提供RHI管理功能的FRenderResource或FVertexBuffer,这是一个FRenderResources,包含一个FBufferRIRef字段,这是实际的GPU绑定顶点缓冲区。

由于虚幻引擎中的渲染是多线程的,因此该引擎使用了从FPrimitiveSceneProxy扩展而来的场景代理的概念。游戏线程上存在的每个需要渲染的基元类型都将创建某种形式的FPrimitiveSceneProxy,并将以线程安全的方式将数据和更新传递给其代理,通常是通过ENQUEUE_RENDER_COMMAND(…(对渲染命令进行排队,当渲染线程确定运行时间时,您将传递一个应执行内容的lamba函数。该代理将包含顶点和索引缓冲区;真实的";将更新渲染的几何体。

一个例子可能是以下(摘录自BaseDynamicMeshSceneProxy。h,FMeshRenderBufferSet::TransferVertexUpdateToGPU((函数(,它显示了UDynamicMeshComponent的场景代理中的渲染缓冲区集合,通过将其CPU绑定的数据直接复制到其GPU绑定的顶点位置缓冲区中,将其顶点位置的更新推送到GPU:

FPositionVertexBuffer& VertexBuffer = this->PositionVertexBuffer;
void* VertexBufferData = RHILockBuffer(VertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetNumVertices() * VertexBuffer.GetStride(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetVertexData(), VertexBuffer.GetNumVertices() * VertexBuffer.GetStride());
RHIUnlockBuffer(VertexBuffer.VertexBufferRHI);

我不会在这里为您提供完整的示例,因为正如您从目前所描述的一切中看到的那样,要实现您想要的目标,它不仅仅是一个简单的代码片段,但我想概述实现这一目标所需了解的总体概念和模式,因为如果您要直接在自己的代码中实现这一点,您必须理解这些概念,当您第一次开始挖掘虚幻引擎的渲染代码时,可能会有点困惑。

帮助您深入了解引擎期望您遵循的模式的最佳资源是此处的官方文档:虚幻引擎图形编程。

如果你想在运行时修改几何体,还有其他选项可以让这个过程比完全自己编写更容易,比如引擎提供的Procedure Mesh Component插件、第三方RuntimeMeshComponent插件,以及更高版本的虚幻引擎(4和5(,UDynamicMeshComponent(早期版本中称为USimpleDynamicMeshComponent(是交互式工具框架的一部分,在最新版本的引擎中已成为引擎运行时模块GeometryFramework的核心部分。

我希望这对你的旅程有所帮助。运行时可修改的几何体很难入门,但它绝对值得一试。

最新更新