智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...
随笔 - 991, 文章 - 0, 评论 - 27, 阅读 - 341万

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

ue4读取灰度图生成三维地形mesh

Posted on   Bill Yuan  阅读(1164)  评论(0编辑  收藏  举报

转自:https://www.cnblogs.com/gucheng/p/10116857.html

新建ue c++工程。
在Build.cs中添加"ProceduralMeshComponent"模块。
在 uproject中添加"ProceduralMeshComponent"模块。
创建材质,传入grass贴图
导入灰度图资源
创建继承自Actor的类 ATerrainCreateActor,并创建蓝图类对象
将蓝图对象拖入场景,设置其灰度贴图参数、Z值缩放比例参数、材质参数
最终效果
ATerrainCreateActor类代码如下
 
头文件

 

复制代码
#pragma once
 
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
#include "TerrainCreateActor.generated.h"
 
UCLASS()
class UETERRAIN_API ATerrainCreateActor : public AActor
{
    GENERATED_BODY()
     
public: 
    ATerrainCreateActor();
private:
    UPROPERTY(VisibleAnywhere)
        UProceduralMeshComponent * mesh;//自定义mesh
    UPROPERTY(EditAnywhere)
        UTexture2D * grayTexture;//传入灰度图
    UPROPERTY(EditAnywhere)
        float zScale;//z值系数
    UPROPERTY(EditAnywhere)
        UMaterial* meshMat;//材质
 
protected:
      
    virtual void BeginPlay() override; 
public:
      
    virtual void Tick(float DeltaTime) override;
};
复制代码

源文件

复制代码
#include "TerrainCreateActor.h"
  
ATerrainCreateActor::ATerrainCreateActor()
{
    PrimaryActorTick.bCanEverTick = true; 
    mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("terrainMesh"));
    RootComponent = mesh;
    mesh->bUseAsyncCooking = true;
}
  
void ATerrainCreateActor::BeginPlay()
{
    Super::BeginPlay();
 
    //读取灰度图像素信息
    FTexture2DMipMap* MyMipMap = &grayTexture->PlatformData->Mips[0];
    FByteBulkData* RawImageData = &MyMipMap->BulkData;
    FColor* FormatedImageData = static_cast<FColor*>(RawImageData->Lock(LOCK_READ_ONLY));
    uint32 TextureWidth = MyMipMap->SizeX, TextureHeight = MyMipMap->SizeY;
    //mesh基础信息
    TArray<FVector> vertices;
    TArray<int32> Triangles;
    TArray<FVector> normals;
    TArray<FVector2D> UV0;
    TArray<FProcMeshTangent> tangents;
    TArray<FLinearColor> vertexColors;
    for (size_t i = 0; i < TextureWidth; i++)
    {
        for (size_t j = 0; j < TextureHeight; j++)
        {
            //根据颜色设定顶点z值
            FColor PixelColor = FormatedImageData[j * TextureWidth + i];
            float tempZ = (PixelColor .B* 299 + PixelColor .G* 587 + PixelColor.R * 114 + 500) / 1000;//rgb转灰度
            tempZ *= zScale;
            vertices.Add(FVector(i*5, j*5, tempZ));  //顶点
            normals.Add(FVector(0, 0, 1));//法线
            UV0.Add(FVector2D((float)i/(float)TextureWidth, (float)j/(float)TextureHeight));//uv
            //UV0.Add(FVector2D(i,j));//uv
            tangents.Add(FProcMeshTangent(1, 0, 0));//切线
            vertexColors.Add(FLinearColor(0.75, 0.75, 0.75, 1.0)); //顶点颜色
 
            if (j < TextureHeight - 1 && i < TextureWidth - 1)
            {
                //三角索引  此处按照vertice的添加顺序确定索引
                Triangles.Add(i*TextureHeight + j);
                Triangles.Add(i*TextureHeight + j + 1);
                Triangles.Add(i*TextureHeight + j + TextureHeight);
 
                Triangles.Add(i*TextureHeight + j + TextureHeight);
                Triangles.Add(i*TextureHeight + j + 1);
                Triangles.Add(i*TextureHeight + j + TextureHeight + 1);
            }
        }
    }
      
 
    RawImageData->Unlock(); 
 
    //创建mesh
    mesh->CreateMeshSection_LinearColor(0, vertices, Triangles, normals, UV0, vertexColors, tangents, true);
    mesh->ContainsPhysicsTriMeshData(true);
    mesh->SetMaterial(0, meshMat);
}
  
void ATerrainCreateActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}
复制代码

 

(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2010-11-05 VC2008编译STLPort
2010-11-05 boost::asio 的同、异步方式
2010-11-05 以boost::function和boost:bind取代虚函数
2010-11-05 Boost.Asio和ACE之间关于Socket编程的比较
2010-11-05 知识框架
2010-11-05 ACE的Socket
点击右上角即可分享
微信分享提示