背景

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 CSMainRWTexture2D<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整体拷贝数据,这里比较坑的地方是


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

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;    }}

效果展示


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

最后贴一下主要代码

链接:pan.baidu.com/15Ny0khWHg_MUKfzXkwopjg

提取码:onbr

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

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

  1. unity text不能刷新_unity自走棋制作(二)-UI制作

    上节做完了自走棋的地图创建,这节就接着来做UI方面的内容.先易后难.把简单的先做完了,然后再弄难度大的.UI的话呢,注要是做和游戏关联性大的,比如刷新,升级,英雄信息等.其他UI后期补.先来看看这节做 ...

  2. unity text不能刷新_厦门泳池派对惊喜之Carta与Unity合作新单预告派对

    我们多久没有号召厦门的好朋友们见面了?也许几个月?也许半年以上?值得庆幸的是,在令人烦躁.焦虑的夏日,我们发现了有趣的清凉时刻.你最爱的泳池派对回来了.「Sunset Sessions」对于任何舞客来 ...

  3. Unity Text 插入超链接

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 当前测试 ...

  4. Unity Text 插入图片

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 当前测试 ...

  5. Unity Text富文本(文本变得多姿多彩)

    Unity Text富文本(文本变得多姿多彩) 实例: 步骤如下: 1.创建一个UI Text 2.Text组件中的Rich Text要勾选上 3.写内容 html控制代码 实例: 步骤如下: 1.创 ...

  6. unity Text文字淡入效果

    unity Text文字淡入效果 CrossFadeAlpha()方法 先将alpha降为0,再改为1. public Text t;void Start() {t.CrossFadeAlpha(0f ...

  7. unity Text Mesh Pro Sprite Animation 支持动图,动态表情

    unity Text Mesh Pro Sprite Animation 支持动图,动态表情 使用格式 <sprite='assetName' anim='first frame, last f ...

  8. Unity Text 实现文本上下标功能

    Unity Text 实现文本上下标功能 可修改上下标颜色以及大小 说明: 文本:1[1=上标1(ce)]2[2=下标2($%6)]3[1|30=上标3{^&}]4[2|30=下标4]5[1| ...

  9. unity字符串换行符_Unity中Text中首行缩进两个字符和换行的代码

    float浮点数的二进制存储方式及转换 int和float都是4字节32位表示形式.为什么float的范围大于int? float精度为6-7位.1.66*10^10的数字结果并不是166 0000 ...

最新文章

  1. 大区块的BCH给智能合约更大的发展潜力
  2. LeetCode5377. 将二进制表示减到1的步骤数
  3. iPhone设备分辨率及尺寸
  4. opensuse x64下编译Ice源码(以编译c++为例)
  5. mybatis collection标签_一对多的关系,在MyBatis中如何映射?
  6. APIGEE:用于API代理的CI / CD管道
  7. 情爱宝典:识破男女间的“放电”信号
  8. Codeforces 1103 E. Radix sum
  9. 【iOS】彩虹渐变色 的 Swift 实现
  10. 详解全局免流原理(转载)
  11. SIM868中的GPRS调试失败的几个原因
  12. C语言实现洗牌发牌程序,用C语言实现的扑克牌洗牌程序
  13. Alphabetic Removals详解(特殊算法巧解)
  14. 耿建超英语语法---时态+疑问句
  15. Android基础篇-四大组件之使用ContentProvider实现数据共享
  16. AI-大型软件研发效能倍增的银弹
  17. 变电所无人值守系统的优点
  18. 《许渊冲西南联大求学日记》摘抄
  19. 【LaTeX公式】LaTeX数学公式的符号表示
  20. ACE Proactor框架

热门文章

  1. 小程序 获取当前用户城市信息(省市区)
  2. Python爬虫利器四PhantomJS的用法
  3. non-aggregates cannot be initialized with initializer list
  4. OOB套接字传输实例(达不到预期结果)
  5. [html] 举例说明图片懒加载的方案有哪些?
  6. [html] 为什么移动端页面的设计稿一般是750px/640px呢?
  7. [html] 你是如何区分HTML和HTML5的?
  8. 工作315:uni-修改添加时间的逻辑
  9. 前端学习(2501):动态绑定样式
  10. “约见”面试官系列之常见面试题之第七十八篇之fetch(建议收藏)