Unity Custom Mipmap
程序员文章站
2022-03-16 16:30:39
...
基于Github上Unity Custom Mipmap 工程
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
public class TestTextureIporter : AssetPostprocessor {
bool m_isReadable;
bool m_importing;
bool ShouldImportAsset(string path)
{
string pattern = GetMipmapFilenamePattern(path);
string mip1Path = string.Format(pattern, 1);
return File.Exists(mip1Path);
}
string GetMipmapFilenamePattern(string path)
{
var filename = Path.GetFileName(path);
var filenameWithoutExtention = Path.GetFileNameWithoutExtension(path);
var extension = Path.GetExtension(path);
var directoryName = Path.GetDirectoryName(path);
return Path.Combine(directoryName, filenameWithoutExtention + ".mip{0}" + extension);
}
void OnPreprocessTexture()
{
string extension = Path.GetExtension(assetPath);
string filenameWithoutExtention = Path.GetFileNameWithoutExtension(assetPath);
var match = Regex.Match(filenameWithoutExtention, @".mip(\d)+$");
if(match.Success)
{
string filenameWithoutMip = filenameWithoutExtention.Substring(0, match.Index);
string directoryName = Path.GetDirectoryName(assetPath);
string mip0Path = Path.Combine(directoryName, filenameWithoutMip + extension);
TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(mip0Path);
if(importer != null)
importer.SaveAndReimport();
}
if (ShouldImportAsset(assetPath))
{
m_importing = true;
string pattern = GetMipmapFilenamePattern(assetPath);
int m = 1;
bool reimport = false;
while(true)
{
string mipPath = string.Format(pattern, m);
m++;
TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(mipPath);
if(importer != null)
{
if(!importer.mipmapEnabled || !importer.isReadable)
{
importer.mipmapEnabled = true;
importer.isReadable = true;
importer.SaveAndReimport();
reimport = true;
}
continue;
}
else
{
break;
}
}
if(reimport)
{
m_importing = false;
return;
}
TextureImporter textureImporter = (TextureImporter)assetImporter;
m_isReadable = textureImporter.isReadable;
textureImporter.isReadable = true;
}
}
void OnPostprocessTexture(Texture2D texture)
{
if (m_importing)
{
string pattern = GetMipmapFilenamePattern(assetPath);
for (int m = 0; m < texture.mipmapCount; m++)
{
var mipmapTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(string.Format(pattern, m));
if(mipmapTexture != null)
{
Color[] c = mipmapTexture.GetPixels(0);
texture.SetPixels(c, m);
}
}
texture.Apply(false, !m_isReadable);
TextureImporter textureImporter = (TextureImporter)assetImporter;
textureImporter.isReadable = m_isReadable;
}
}
}
Mipmap
mipmap是为了处理在不同距离情况下,节约gpu计算资源的一种方法。在真实世界中,较远的物体反射到人眼睛中的光线占比越少,所需要的细节越少。因此在游戏中,我们不仅仅需要将远处的模型进行lod简化处理,还需要对贴图进行简化。这种处理方式就是mipmap
mipmap是预处理阶段处理,因此只计算一次,但是同时会占用一定的内存。是用空间换时间的一种方法。
如下图,
处理效果
Custom Mipmap
上图中是mipmap自定义的效果。由近到远为0,1,2,3。
核心代码如下
void OnPostprocessTexture(Texture2D texture)
{
// 设置mipmap
if (m_importing)
{
string pattern = GetMipmapFilenamePattern(assetPath);
for (int m = 0; m < texture.mipmapCount; m++)
{
var mipmapTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(string.Format(pattern, m));
if(mipmapTexture != null)
{
Color[] c = mipmapTexture.GetPixels(0);
// 通过setpixel来设置mipmap
texture.SetPixels(c, m);
}
}
texture.Apply(false, !m_isReadable);
TextureImporter textureImporter = (TextureImporter)assetImporter;
textureImporter.isReadable = m_isReadable;
}
}
在unity的回调函数OnPostprocessTexture中,通过setpixel来设置了贴图所对应的mipmap像素。由此设置完毕。
在窗口中,右上角为mipmap调节窗口,可以通过调整查看。
上一篇: python爬虫--【百度知道】自动答题
下一篇: echarts忽隐忽现问题