您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

104 行
3.6 KiB

using System;
using UnityEditor;
using UnityEngine;
public class NormalMapVarianceTexturePostprocessor : AssetPostprocessor
{
void OnPreprocessTexture()
{
if (assetPath.IndexOf("_variance", StringComparison.InvariantCultureIgnoreCase) != -1)
{
// Make sure we don't convert as a normal map.
TextureImporter textureImporter = (TextureImporter)assetImporter;
textureImporter.convertToNormalmap = false;
textureImporter.textureCompression = TextureImporterCompression.CompressedHQ;
textureImporter.linearTexture = true; // Says deprecated but won't work without it.
textureImporter.sRGBTexture = false; // But we're setting the new property just in case it changes later...
}
}
private static Color GetColor(Color[] source, int x, int y, int width, int height)
{
x = (x + width) % width;
y = (y + height) % height;
int index = y * width + x;
var c = source[index];
return c;
}
private static Vector3 GetNormal(Color[] source, int x, int y, int width, int height)
{
Vector3 n = (Vector4)GetColor(source, x, y, width, height);
n = 2.0f * n - Vector3.one;
n.Normalize();
return n;
}
private static Vector3 GetAverageNormal(Color[] source, int x, int y, int width, int height, int texelFootprint)
{
Vector3 averageNormal = new Vector3(0, 0, 0);
// Calculate the average color over the texel footprint.
for (int i = 0; i < texelFootprint; ++i)
{
for (int j = 0; j < texelFootprint; ++j)
{
averageNormal += GetNormal(source, x + i, y + j, width, height);
}
}
averageNormal /= (texelFootprint * texelFootprint);
return averageNormal;
}
void OnPostprocessTexture(Texture2D texture)
{
if (assetPath.IndexOf("_variance", StringComparison.InvariantCultureIgnoreCase) != -1)
{
// For mip 0, set the normal length to 1.
{
Color[] c = texture.GetPixels(0);
for (int i = 0; i < c.Length; i++)
{
c[i].a = 1.0f;
}
texture.SetPixels(c, 0);
}
// Based on The Order : 1886 SIGGRAPH course notes implementation. Sample all normal map
// texels from the base mip level that are within the footprint of the current mipmap texel.
Color[] source = texture.GetPixels(0);
for (int m = 1; m < texture.mipmapCount; m++)
{
Color[] c = texture.GetPixels(m);
int mipWidth = Math.Max(1, texture.width >> m);
int mipHeight = Math.Max(1, texture.height >> m);
for (int x = 0; x < mipWidth; ++x)
{
for (int y = 0; y < mipHeight; ++y)
{
int texelFootprint = 1 << m;
Vector3 averageNormal = GetAverageNormal(source, x * texelFootprint, y * texelFootprint,
texture.width, texture.height, texelFootprint);
// Store the normal length for the average normal.
int outputPosition = y * mipWidth + x;
//c[outputPosition].a = averageNormal.magnitude;
float normalLength = Math.Max(0.0f, Math.Min(1.0f, averageNormal.magnitude));
c[outputPosition].a = normalLength;
}
}
texture.SetPixels(c, m);
}
}
}
}