首页 > 编程知识 正文

dither,matlab dither

时间:2023-05-06 02:46:22 阅读:217437 作者:4112

在unity开发过程中,游戏图片占用了很大一部分的手机内存。所以在游戏开发中,对图片的优化也至关重要。

在Unity中常用的的图片格式有RGBA32,RGBA16,ETC,PVRTC等。这里我们主要讨论带透明通道的RGBA32和RGBA16这两种格式的图片在Unity占用的内存空间已经优化方案。

我们知道,RGBA32是R,G,B,A四个通道每个通道用8位来表示,RGBA16则是用4位。所以RGBA32能够带来更好的显示效果。同时也会带来更大的内存消耗。下面给两张RGBA16和RGBA32的对比图。

RGBA32

 

RGBA32.png

RGBA16

 

RGBA16.png

从上面两个图可以看得出,RGBA32能够带来更好的显示效果。而RGBA16在有些地方的色阶太明显,导致显示效果不尽人意。由此keijiro(Github地址)写了一个dither算法来消除这种色阶,以达到高于RGBA16低于RGBA32的显示效果。

下图为Dither优化之后的RGBA16

RGBA16-Dither.png

通过对比能明显看出优化后的RGBA16能够消除色阶,如果不是放大特意看,和RGBA32几乎差别不同。通过这种方式将内存降低一半确认带来更好的效果。

万事总会存在利弊,这个算法在消除了色阶的同事,带来的是更多的噪点。所以这个方法不适用于图片需要放大来显示的。总体来说,该方案在一定程度上还是能够带来很好的效果。
最后把算法的核心代码贴出来 。

public class TextureImportSetting : AssetPostprocessor { string[] assetTexturePath = new string[]{"Assets/Resources/TextureVN/"}; //放置需要优化的路径 void OnPreprocessTexture(){ foreach (var str in assetTexturePath) { if (this.assetPath.StartsWith(str) ) { TextureImporter textureImporter = this.assetImporter as TextureImporter; textureImporter.textureType = TextureImporterType.Advanced; textureImporter.npotScale = TextureImporterNPOTScale.ToNearest; textureImporter.mipmapEnabled = false; textureImporter.isReadable = false; if ( textureImporter.DoesSourceTextureHaveAlpha()) { textureImporter.textureFormat = TextureImporterFormat.RGBA32; } } } } public static void OnPostprocessRGB16 (Texture2D texture) { var texw = texture.width; var texh = texture.height; var pixels = texture.GetPixels (); var offs = 0; var k1Per15 = 1.0f / 15.0f; var k1Per16 = 1.0f / 16.0f; var k3Per16 = 3.0f / 16.0f; var k5Per16 = 5.0f / 16.0f; var k7Per16 = 7.0f / 16.0f; for (var y = 0; y < texh; y++) { for (var x = 0; x < texw; x++) { float a = pixels [offs].a; float r = pixels [offs].r; float g = pixels [offs].g; float b = pixels [offs].b; var a2 = Mathf.Clamp01 (Mathf.Floor (a * 16) * k1Per15); var r2 = Mathf.Clamp01 (Mathf.Floor (r * 16) * k1Per15); var g2 = Mathf.Clamp01 (Mathf.Floor (g * 16) * k1Per15); var b2 = Mathf.Clamp01 (Mathf.Floor (b * 16) * k1Per15); var ae = a - a2; var re = r - r2; var ge = g - g2; var be = b - b2; pixels [offs].a = a2; pixels [offs].r = r2; pixels [offs].g = g2; pixels [offs].b = b2; var n1 = offs + 1; var n2 = offs + texw - 1; var n3 = offs + texw; var n4 = offs + texw + 1; if (x < texw - 1) { pixels [n1].a += ae * k7Per16; pixels [n1].r += re * k7Per16; pixels [n1].g += ge * k7Per16; pixels [n1].b += be * k7Per16; } if (y < texh - 1) { pixels [n3].a += ae * k5Per16; pixels [n3].r += re * k5Per16; pixels [n3].g += ge * k5Per16; pixels [n3].b += be * k5Per16; if (x > 0) { pixels [n2].a += ae * k3Per16; pixels [n2].r += re * k3Per16; pixels [n2].g += ge * k3Per16; pixels [n2].b += be * k3Per16; } if (x < texw - 1) { pixels [n4].a += ae * k1Per16; pixels [n4].r += re * k1Per16; pixels [n4].g += ge * k1Per16; pixels [n4].b += be * k1Per16; } } offs++; } } texture.SetPixels (pixels); EditorUtility.CompressTexture (texture, TextureFormat.RGBA4444, TextureCompressionQuality.Best); } void OnPostprocessTexture(Texture2D texture){ foreach (var str in assetTexturePath) { if (this.assetPath.StartsWith(str) ) { TextureImporter textureImporter = this.assetImporter as TextureImporter; if ( textureImporter.DoesSourceTextureHaveAlpha()) { OnPostprocessRGB16(texture); } } } }}

更多unity2018的功能介绍请到paws3d爪爪学院查找。链接https://www.paws3d.com/,也可以加入unity学习讨论群935714213

近期更有资深开发人士直播分享unity开发经验,详情请进入官网或加入QQ群了解

win7系统出现电脑蓝屏如何解决

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。