在UE中有时需要在CPU阶段操作像素,生成纹理贴图等,此时可以通过UTexture2D来进行处理,例子如下:
1.CPP部分
首先创建一个蓝图函数库,将UTexture2D的绘制逻辑封装成单个函数:
.h:
#include "CoreMinimal.h"
#include "Engine/Texture2D.h"
#include "Engine/Texture.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
UCLASS()
class MYPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, Category = "Texture")
static UTexture2D* GenTexture(int32 Width, int32 Height);
};
.cpp:
#include "MyBlueprintFunctionLibrary.h"
UTexture2D* UMyBlueprintFunctionLibrary::GenTexture(int32 Width, int32 Height)
{
// 创建临时纹理
UTexture2D* NewTexture = UTexture2D::CreateTransient(Width, Height);
// 配置纹理
NewTexture->MipGenSettings = TMGS_NoMipmaps;
NewTexture->CompressionSettings = TC_VectorDisplacementmap;
NewTexture->SRGB = false;
// 锁定纹理数据进行写入
FTexture2DMipMap& Mip = NewTexture->PlatformData->Mips[0];
void* TextureData = Mip.BulkData.Lock(LOCK_READ_WRITE);
// 设置三角形的大小
int32 TriangleSize = Width / 10; // 每个三角形的宽度和高度
// 设置默认颜色
FColor* FormattedImageData = static_cast<FColor*>(TextureData);
for (int32 y = 0; y < Height; ++y)
{
for (int32 x = 0; x < Width; ++x)
{
int32 LocalX = x % TriangleSize;
int32 LocalY = y % TriangleSize;
// 判断像素是否在当前三角形内
if (LocalX >= LocalY) // 这里绘制一个局部的三角形
{
FormattedImageData[x + y * Width] = FColor::Red; // 三角形内部像素
}
else
{
FormattedImageData[x + y * Width] = FColor::Black; // 背景色
}
}
}
// 解锁纹理数据
Mip.BulkData.Unlock();
NewTexture->UpdateResource();
return NewTexture;
}
需要修改build.cs添加模块引用:
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "RenderCore", "RHI", "ProceduralMeshComponent" });
2.蓝图部分
新建材质球暴露材质参数img1:
创建Actor类型蓝图,添加一个Mesh类组件,这里添加一个Cube:
使用刚刚的GenTexture节点创建材质纹理,运行后即可查看效果。
https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Engine/Engine/UTexture2D