unity text不能刷新_Unity使用ComputerShader实时压缩RT!

背景

computer shader最近突然变得异常火热,原神和UE开发者大会多次被人提到通过computershader对手机平台的优化。一方面得益于最近手机硬件的提升,对computer shader的支持和性能提升。另一方面,新出的游戏对于画面质量的要求越来越高,一些新特性,诸如:SSAO,屏幕空间反射,RVT,甚至GPU pipeline,对于computer shader的需求提高。

前不久,在unity实现了RVT,里边提到需要申请使用两种4k的RT,在手机上测试,法线性能还是有一定的损失。虽然,非RVT在使用四层纹理,总共需要9张地形相关的贴图(4*2 + 1,mask压缩到diffuse和normal),但是贴图的尺寸最多开到1024,一般就512就够了。而RVT需要两张4k的RT,并且RenderTexture是不能压缩的,也就是全展开的4k*2,在原本手机带宽就不够的情况下,这个算得上非常奢侈,非常影响效率。UE开发者大会,正好提到在4.26版本加入VT的压缩,正好可以拔过来,在Unity里实现了一下,用来支持RVT系统。

Computer Shader

UE4.26提供两种VT的压缩格式,BC3(PC)和ETC2(Android),并且ETC2的压缩算法看了一下,为了提升性能,做了很多精简。

我这里贴一下压缩的主体部分代码,具体压缩算法部分,可以在UE4.26preview的ETCCompressionCommon.ush和BCCompressionCommon.ush中,也可以在我后面提供的压缩文件里寻找(我做了一定的修改),或者拔GitHub上的代码darksylinc/betsy

#include "ETCCompress.hlsl"
#include "BCCompress.hlsl"
#pragma multi_compile _COMPRESS_BC3 _COMPRESS_ETC2
#pragma kernel CSMain
RWTexture2D<uint4> Result;
Texture2D<float4> RenderTexture0;
SamplerState samplerRenderTexture0;
uint4 DestRect;
[numthreads(8, 8, 1)]
void CSMain(uint3 ThreadId : SV_DispatchThreadID)
{
uint2 SamplePos = ThreadId.xy * 4;
if (any(SamplePos >= DestRect.zw))
return;

float2 TexelUVSize = 1.f / float2(DestRect.zw);
float2 SampleUV = (float2(SamplePos) + 0.5f) * TexelUVSize;

float3 BlockBaseColor[16];
ReadBlockRGB(RenderTexture0, samplerRenderTexture0, SampleUV, TexelUVSize, BlockBaseColor);

float BlockA[16];
for (int i = 0; i < 16; i++)
{
BlockA[i] = 1;
}
#ifdef _COMPRESS_ETC2
Result[ThreadId.xy] = CompressBlock_ETC2_RGBA(BlockBaseColor, BlockA);
#else
Result[ThreadId.xy] = CompressBC3Block_SRGB(BlockBaseColor, BlockA);
#endif
}

他这里的ETC2直接写死的4x4block,然后分RGB和RGBA两种。

C#调用

实例代码中,比如我们想要压缩一张256x256的图片,我们需要申请一张64x64的R32G32B32A32_Uint的RT,在computer shader里填入数据。这个RT肯定不能直接当贴图使用,我们需要把数据拷贝到Texture2D中,Texture2D是可以设置压缩格式的。直接使用Graphics.CopyTexture整体拷贝数据,这里比较坑的地方是

012c2ed5f02e5178be26373bd9c6a9ae.png

这两句话居然不是同一个意思,一定要使用上面那样,下面这种会报错。

using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.UI;
public class ComputeShaderTest : MonoBehaviour
{
public ComputeShader shader;
Material _mat;
public Texture _mask;
int kernelHandle;
int[] DestRect;
public RenderTexture tex;
public Texture2D copyTex;
public Text tt;

GraphicsFormat format;
void Awake()
{
DestRect = new int[4] { 0, 0, 256, 256 };
}
void Start()
{
#if UNITY_ANDROID && !UNITY_EDITOR format = GraphicsFormat.RGBA_ETC2_UNorm;
shader.DisableKeyword("_COMPRESS_BC3");
shader.EnableKeyword("_COMPRESS_ETC2");
#else format = GraphicsFormat.RGBA_DXT5_UNorm;
shader.DisableKeyword("_COMPRESS_ETC2");
shader.EnableKeyword("_COMPRESS_BC3");
#endif kernelHandle = shader.FindKernel("CSMain");
tex = new RenderTexture(64, 64, 24)
{
graphicsFormat = GraphicsFormat.R32G32B32A32_UInt,
enableRandomWrite = true,
};
tex.Create();
//tt.text = format.ToString() + SystemInfo.IsFormatSupported(format, FormatUsage.Linear).ToString() + SystemInfo.supportsComputeShaders + SystemInfo.copyTextureSupport;
shader.SetTexture(kernelHandle, "Result", tex);
shader.SetTexture(kernelHandle, "RenderTexture0", _mask);
shader.SetInts("DestRect", DestRect);
shader.Dispatch(kernelHandle, (256 / 4 + 7) / 8, (256 / 4 + 7) / 8, 1);
copyTex = new Texture2D(256, 256, format, TextureCreationFlags.None);
Graphics.CopyTexture(tex, 0,0,0,0,64,64,copyTex,0,0,0,0);
_mat = GetComponent().sharedMaterial;
_mat.mainTexture = copyTex;
}
}

效果展示

3b279a7f8ce724eb76fd144681b06df4.png

在移动和PC都可以,vulkan在某些机型有bug,切换到GLES3就可以了。

最后贴一下主要代码

链接:pan.baidu.com/15Ny0khWHg_MUKfzXkwopjg

提取码:onbr

来源知乎专栏:Unity引擎应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SVN Could not open the requested SVN filesystem解决办法

如果TortoiseSVN的版本过高&#xff0c;而SVN服务器的版本过低有可能造成&#xff0c;创建的资源库无法访问&#xff08;SVN Could not open the requested SVN filesystem&#xff09;。因此版本要相符。当然为避免上面的问题也可以直接用命令来创建&#xff0c;在命令行窗口&…

zip转直链php,蓝奏网盘直链转换器

蓝奏网盘直链转换器是一款非常不错的网盘直链转换工具&#xff0c;能够帮助用户批量进行蓝奏云网盘链接转换&#xff0c;可以自定义设置转换线程数&#xff0c;让用户能够直接下载分享的文件&#xff0c;下载速度非常快&#xff0c;有需要的用户不要错过了&#xff0c;赶快来下…

hdu 1695

题目&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1695 给出a b c d k 在 [a,b] [c,d]内各找一个数&#xff0c;使得gcd(x,y) k&#xff0c;也就是说 gcd(x / k, y / k) 1&#xff0c;所以就是在 [1,b / k] [1, d / k]中找互质的对数。容斥原理和欧拉函数的应用&a…

python流量监控_用python中的pcapy实现网络流量监控

我写了一个简单的网络流量监视器来获得B/s和/或总数据传输率(B)。然而&#xff0c;当我用ftp(使用Total Commander)传输一个文件来测试它时&#xff0c;我不能让它把Total transfer作为文件大小来衡量。它总是比实际尺寸小得多。我不确定我是不是做错了什么。。我设置的BPF过滤…

php cve-2014-9427漏洞,WEB应用漏洞-温州特种设备检测研究院.DOC

WEB应用漏洞-温州特种设备检测研究院附件3&#xff1a;重点网站技术检测报告重点网站技术检测报告网站属地&#xff1a;浙江温州网站名称&#xff1a;温州市特种设备检测研究院域名&#xff1a;_重点网站技术检测报告经技术检测发现&#xff0c;你单位网站(地址&#xff1a;)存…

c#左移、右移基础

转&#xff1a;http://www.cnblogs.com/songsz1/archive/2012/10/16/2725983.html转载于:https://www.cnblogs.com/piaopiao7891/archive/2012/10/16/2726358.html

oracle导出审计表,Oracle审计表AUD$处理方法

Oracle版本&#xff1a;11.2.0&#xff0c;其他版本要测试DBMS_AUDIT_MGMT能否成功1. 查询表&#xff0c;然后truncateselect count(*) from aud$;truncate table aud$;select count(*) from aud$;2.创建表空间create tablespace adttbsdatafile /oracle/OMT/admin/oradata/aud…

python转c报错no module named_python异常No module named 'win32com'

异常原因:python调用com组件操作office将word转pdf报错如下Traceback (most recent call last):File "D:/wordTest/wordTest.py", line 2, in from win32com import clientModuleNotFoundError: No module named win32comTraceback (most recent call last):File &qu…

如何清除tomcat缓存

用tomcat容器&#xff0c;大家可能会发现这样的问题&#xff0c;修改jsp文件后&#xff0c;但用IE打开 依然是以前的Jsp的页面。 出现这种现象的原因主要是tomcat缓存的原因。 解决办法如下: 在jsp文件头加上 <meta http-equiv"Expires" content"0"&…

sql 链接到oracle数据库,通过MSSQL连接服务器连接至Oracle数据库

前言有很多时候&#xff0c;我们需要MSSQL与Oracle进行跨库查询或数据交互。本篇随笔将阐述如何通过MSSQL的连接服务器连接至Oracle数据库&#xff0c;并且读取数据的示例。具体步骤首先需要到Oracle的官网下载Oracle Client(简称OCT)&#xff0c;也就是通常大家所说的Oracle客…

python一看就很厉害的代码_Python学习教程:怎么写出让人看起来就很舒服的代码?...

Python学习教程&#xff1a;怎么写出让人看起来很优雅舒服的代码&#xff1f;让人眼前一亮&#xff01;很多新手在开始学一门新的语言的时候&#xff0c;往往会忽视一些不应该忽视的细节&#xff0c;比如变量命名和函数命名以及注释等一些内容的规范性&#xff0c;久而久之养成…

VBS 自动发送邮件

--------------------------------------------------------------------------------- 函数名称 : SendMail 函数功能 : 自动发送邮件功能 函数输入 : SendTo----收件人&#xff0c;多个收件人可使用";"隔开MailTopic----邮件主题MailBody----邮件内容,此处内容格式…

oracle更新数据没有变化,往oracle里面写入数据,怎么表空间都没有变化

当freelist里面没有记录了&#xff0c;也就是块空间已经没有办法容纳新的记录了&#xff0c;这时候就需要扩展extent.这里有一个脚本来查看段空间使用情况。[php]create or replace procedure show_space( p_segname in varchar2,p_owner in varchar2 default user,p_type …

关于python变量的描述_Python变量命名的详细介绍

目前开发命名规范基本都遵循驼峰命名法&#xff0c;如&#xff1a;userName。我也不将这个规范的特性了&#xff0c;大家都明白。接下来进入正题&#xff0c;如何在python中取一个好名字&#xff0c;让你能更好的见名知意呢&#xff1f;1.元组(Tuple)类型变量命名在python中Tup…

Visual Studio 2010 单元测试之一---普通单元测试:http://blog.csdn.net/tjvictor/archive/2011/02/09/6175362.aspx...

本文以Visual Studio 2010为例&#xff0c;来介绍如何在Visual Studio里面进行单元测试. 首先来介绍普通单元测试&#xff0c;这是进行顺序测试、压力测试的基础。如果在Visual Studio 2010(2008)里面没有发现下图中的Test菜单&#xff0c;请用Visual Studio安装光盘进行安装&a…