游戏《孢子》的思考 —— Marching Cube算法

这篇博客介绍了Marching Cube这种用于三角化各类隐式曲面的算法,以及记录了我对应的思考。


背景

游戏《孢子》运用的三角化隐式曲面的算法是Compact Cube算法,然而Compact Cube算法是基于Marching Cube进行的优化算法,所以了解对应的Marching Cube算法是必要的。


Marching Cube算法介绍

总体的Marching Cube算法可以分成两块,一块是根据曲面方程构建出对应的三角形顶点,另一块是构建出对应的点法线。

体素及各顶点的density

如果想要使用Marching Cube算法来构建对应的三角面的话,那么需要使用到体素。

可以想象,针对于一个球面方程:

F(x,y,z)=x2+y2+z21=0

在对应的空间中可以散布很多的小立方体栅格。

每个立方体栅格的每个顶点都有对应的Density,根据集合关系可以很方便的推断出:

  • 如果一个立方体栅格的每个顶点的Density值都 <0 <script type="math/tex" id="MathJax-Element-2">< 0</script>,那么可以认为这个立方体完全位于曲面的一侧。
  • 同样的,如果每个顶点的Density值都 > ,那么可以认为这个立方体完全位于曲面的另一侧。
  • 如果有部分顶点值
  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在UE4中展示Marching Cubes算法,可以按照以下步骤进行: 1. 创建一个Actor,并将其命名为MarchingCubesActor。 2. 在MarchingCubesActor中添加一个ProceduralMeshComponent,用于展示Marching Cubes算法生成的网格。 3. 创建一个C++类,例如MarchingCubes,用于实现Marching Cubes算法。在该类中,实现GenerateMesh函数,用于生成网格。该函数应该接受一个三维数组,该数组存储了Marching Cubes算法中的体数据。 4. 在MarchingCubesActor的BeginPlay函数中,实例化MarchingCubes类,并调用GenerateMesh函数生成网格。将生成的网格数据传递给ProceduralMeshComponent对象,用于展示。 以下是一个简单的示例代码段,用于实现Marching Cubes算法: ``` // MarchingCubes.h #pragma once #include "CoreMinimal.h" class MARCHINGCUBES_API MarchingCubes { public: static void GenerateMesh(TArray<float>& Data, TArray<FVector>& Vertices, TArray<int32>& Triangles); }; ``` ``` // MarchingCubes.cpp #include "MarchingCubes.h" void MarchingCubes::GenerateMesh(TArray<float>& Data, TArray<FVector>& Vertices, TArray<int32>& Triangles) { // Implement the Marching Cubes algorithm here // ... // Add vertices and triangles to the output arrays Vertices.Add(FVector(0, 0, 0)); Vertices.Add(FVector(1, 0, 0)); Vertices.Add(FVector(0, 1, 0)); Triangles.Add(0); Triangles.Add(1); Triangles.Add(2); } ``` ``` // MarchingCubesActor.cpp #include "MarchingCubesActor.h" #include "ProceduralMeshComponent.h" #include "MarchingCubes.h" AMarchingCubesActor::AMarchingCubesActor() { // Create a ProceduralMeshComponent and set it as the root component Mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("Mesh")); RootComponent = Mesh; } void AMarchingCubesActor::BeginPlay() { Super::BeginPlay(); // Generate the mesh using Marching Cubes algorithm TArray<float> Data; // Fill the data array with voxel data TArray<FVector> Vertices; TArray<int32> Triangles; MarchingCubes::GenerateMesh(Data, Vertices, Triangles); // Set the mesh data to ProceduralMeshComponent Mesh->CreateMeshSection(0, Vertices, Triangles, TArray<FVector>(), TArray<FVector2D>(), TArray<FColor>(), TArray<FProcMeshTangent>(), false); } ``` 这是一个基本的示例,您可以根据您的需求进一步修改。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值