UE4图片文本

本文介绍了如何在UE4中使用动态纹理和材质来实现自定义样式的文本渲染,包括创建和更新动态UV偏移贴图,以及调整材质以利用四个颜色通道来节省资源。此外,还提供了对单行文本的处理方法,并指出如何扩展到多行文本。最后展示了更新和创建UV偏移贴图的代码示例,以及如何在蓝图中使用这些功能来渲染文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

制作游戏UI的时候经常会有界面上的自定义样式的文本需求,在2d引擎中我们都会以

这样的图片资源来进行动态数字文本的显示,而固定的属性名称等内容则使用指定贴图代替,现在我们就在ue4中实现这样的渲染

注意:

1.本实例只实现了横向文本渲染,没有多行文本处理,如有需要可以在uv采样上添加Y轴的起始及偏移自行扩展

2.理论上采样贴图size设置的够大能支持无限字符长度采样,但是受限于引擎或者性能影响,建议还是根据需求合理扩展使用

8-22更新:

将4个通道都用起来,兼容更多的字符节约开销

1.修改uv存储贴图的数据写入逻辑,将起始uv分别写入4个通道(如果是做多行的情况,这里就需要修改为分别写入两个通道,每个像素填入两个字符)

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static void UpdateDynImage(UTexture2DDynamic* tex, TArray<float> values) {
		if (!tex) {
			return;
		}
		FTexture2DDynamicResource* dynRes = static_cast<FTexture2DDynamicResource*>(tex->Resource);
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), tex->SizeX);	
		if (values.Num() > 0) {
			int len = values.Num() / 4;
			if (values.Num() - len * 4 > 0) {
				len = len + 1;
			}
			for (size_t i = 0; i < len; i++)
			{
				if (i >= src.Num())break;
				int index = i * 4;
				float r, g, b, a;
				r = values[index];
				if (index + 1 < values.Num()) {
					g = values[index + 1];
				}
				if (index + 2 < values.Num()) {
					b = values[index + 2];
				}
				if (index + 3 < values.Num()) {
					a = values[index + 3];
				}
				FLinearColor c(r, g, b, a);
				src[i] = (c.ToFColor(false));
			}
		}
		/*
		更新实现参照
		UTexture2D::UpdateTextureRegions();
		*/

		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				if (dynRes) {
					FRHITexture2D* rhi = dynRes->GetTexture2DRHI();
					uint32 d = 0;
					FColor* data = reinterpret_cast<FColor*>(RHILockTexture2D(rhi, 0, RLM_WriteOnly, d, false));

					FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());

					RHIUnlockTexture2D(rhi, 0, false);
				}
			}
		);
	}

2.修改材质采样部分,使用4个通道数据

 3.修改组件蓝图兼容的最大字符数计算

 

材质

 

材质中包含动态赋予属性:

fontTexSampleScale 文字贴图的每个字符所占的uv宽度 ,我们采样的时候根据这个数据来计算出采样uv插值 

NumSize 在实际渲染中每个字符在渲染网格或Image上所占用的uv宽度

uvOffsetSampleSize  每个字符的起始uv数据在动态uv偏移贴图上所对应的uv宽度

FontSampleTex 根据当前文本数据动态刷新的uv偏移贴图,采样获取每个文本单元的起始uv

NumTex  需要渲染的文本字符集贴图,因制作的时候是出于需要动态掉血数值绘制,所以取名NumTex

UV偏移贴图

创建

贴图高度永远为1,因为我们只考虑横向采样

 参数width:贴图的宽度,代表了可以采样的最大文本长度

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static UTexture2DDynamic* CreateDynImage(int width) {
		UTexture2DDynamic* tex= UTexture2DDynamic::Create(width, 1);
		tex->SRGB = false;
		tex->SamplerAddressMode = AM_Clamp;
		tex->CompressionSettings = TC_HDR;
		tex->Filter = TF_Nearest;
		tex->MipGenSettings = TMGS_NoMipmaps;
		tex->UpdateResource();
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), width);
		for (size_t i = 0; i < width; i++)
		{
			auto v = (i % 2)*255;
			FColor c(v, v, v);
			src[i] = c;
		}
		FTexture2DDynamicResource* dynRes= static_cast<FTexture2DDynamicResource*>(tex->Resource);
		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				FRHITexture2D* rhi= dynRes->GetTexture2DRHI();
				uint32 d = 0;
				FColor* data= reinterpret_cast<FColor*>( RHILockTexture2D(rhi, 0, RLM_WriteOnly, d,false));
				
				FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());
				
				RHIUnlockTexture2D(rhi, 0, false);
			}
		);
		return tex;
	}

更新

参数 tex:uv偏移的动态贴图对象,有上面的创建方法创建后用户进行存档,更新时传入

参数values:字符串的uv偏移值数组,长度为字符串的长度

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static void UpdateDynImage(UTexture2DDynamic* tex, TArray<float> values) {
		if (!tex) {
			return;
		}
		FTexture2DDynamicResource* dynRes = static_cast<FTexture2DDynamicResource*>(tex->Resource);
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), tex->SizeX);		
		for (size_t i = 0; i < values.Num(); i++)
		{
			if (i >= src.Num())break;
			FLinearColor c(values[i], values[i], values[i]);
			src[i]=(c.ToFColor(false));
		}
		/*
		更新实现参照
		UTexture2D::UpdateTextureRegions();
		*/

		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				FRHITexture2D* rhi = dynRes->GetTexture2DRHI();
				uint32 d = 0;
				FColor* data = reinterpret_cast<FColor*>(RHILockTexture2D(rhi, 0, RLM_WriteOnly, d, false));

				FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());

				RHIUnlockTexture2D(rhi, 0, false);
			}
		);
	}

对齐方式枚举

        

组件蓝图

变量

 dynFontMat 动态渲染材质

 uvmap 字符集的起始uv偏移映射表

 fontSize 渲染的字符大小,起始就是image对象的单元大小,每个字符这里实现都是正方形

 text 当前渲染的文本

 dynFontUVTex 动态uv偏移贴图的缓存

 maxLength 最大字符长度,超出长度的字符不会做渲染

 align 横向对齐方式,参照对齐方式枚举,纵向始终居中

 fontImage UMG组件,用于最终文本的渲染

构造

初始化布局

初始化渲染

 

 

 

设置文本渲染

 

 

 最终效果

1.

 2.

3.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值