专业网站开发哪里有,泉州网站制作企业,网页设计公司建设网站,怎么做网络推广优化背景computer shader最近突然变得异常火热#xff0c;原神和UE开发者大会多次被人提到通过computershader对手机平台的优化。一方面得益于最近手机硬件的提升#xff0c;对computer shader的支持和性能提升。另一方面#xff0c;新出的游戏对于画面质量的要求越来越高#… 背景computer shader最近突然变得异常火热原神和UE开发者大会多次被人提到通过computershader对手机平台的优化。一方面得益于最近手机硬件的提升对computer shader的支持和性能提升。另一方面新出的游戏对于画面质量的要求越来越高一些新特性诸如SSAO屏幕空间反射RVT甚至GPU pipeline对于computer shader的需求提高。前不久在unity实现了RVT里边提到需要申请使用两种4k的RT在手机上测试法线性能还是有一定的损失。虽然非RVT在使用四层纹理总共需要9张地形相关的贴图(4*2 1mask压缩到diffuse和normal)但是贴图的尺寸最多开到1024一般就512就够了。而RVT需要两张4k的RT并且RenderTexture是不能压缩的也就是全展开的4k*2在原本手机带宽就不够的情况下这个算得上非常奢侈非常影响效率。UE开发者大会正好提到在4.26版本加入VT的压缩正好可以拔过来在Unity里实现了一下用来支持RVT系统。Computer ShaderUE4.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 CSMainRWTexture2Duint4 Result;Texture2Dfloat4 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引擎应用