396 lines
14 KiB
C#
396 lines
14 KiB
C#
|
using UnityEngine;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System;
|
|||
|
|
|||
|
namespace DigitalOpus.MB.Core
|
|||
|
{
|
|||
|
public class TextureBlenderStandardMetallicRoughness : TextureBlender
|
|||
|
{
|
|||
|
static Color NeutralNormalMap = new Color(.5f, .5f, 1f);
|
|||
|
|
|||
|
private enum Prop{
|
|||
|
doColor,
|
|||
|
doMetallic,
|
|||
|
doRoughness,
|
|||
|
doEmission,
|
|||
|
doBump,
|
|||
|
doNone,
|
|||
|
}
|
|||
|
|
|||
|
// This is used to cache the non texture property values. If all non-texutre property values are the same for a property for all source textures
|
|||
|
// then the source value will be re-used
|
|||
|
TextureBlenderMaterialPropertyCacheHelper sourceMaterialPropertyCache = new TextureBlenderMaterialPropertyCacheHelper();
|
|||
|
|
|||
|
// These are cached values read in OnBeforeTintTexture and used when blending pixels.
|
|||
|
Color m_tintColor;
|
|||
|
float m_roughness;
|
|||
|
float m_metallic;
|
|||
|
bool m_hasMetallicGlossMap;
|
|||
|
bool m_hasSpecGlossMap;
|
|||
|
float m_bumpScale;
|
|||
|
bool m_shaderDoesEmission;
|
|||
|
Color m_emissionColor;
|
|||
|
|
|||
|
// This just makes things more efficient so we arn't doing a string comparison for each pixel.
|
|||
|
Prop propertyToDo = Prop.doNone;
|
|||
|
|
|||
|
// These are the property values that will be assigned to the result material if
|
|||
|
// generating an atlas for those properties.
|
|||
|
Color m_generatingTintedAtlasColor = Color.white;
|
|||
|
float m_generatingTintedAtlasMetallic = 0f;
|
|||
|
float m_generatingTintedAtlasRoughness = .5f;
|
|||
|
float m_generatingTintedAtlasBumpScale = 1f;
|
|||
|
Color m_generatingTintedAtlasEmission = Color.white;
|
|||
|
|
|||
|
// These are the default property values that will be assigned to the result materials if
|
|||
|
// none of the source materials have a value for these properties.
|
|||
|
Color m_notGeneratingAtlasDefaultColor = Color.white;
|
|||
|
float m_notGeneratingAtlasDefaultMetallic = 0;
|
|||
|
float m_notGeneratingAtlasDefaultGlossiness = .5f;
|
|||
|
Color m_notGeneratingAtlasDefaultEmisionColor = Color.black;
|
|||
|
|
|||
|
public bool DoesShaderNameMatch(string shaderName)
|
|||
|
{
|
|||
|
return shaderName.Equals("Standard (Roughness setup)");
|
|||
|
}
|
|||
|
|
|||
|
public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
|
|||
|
{
|
|||
|
if (shaderTexturePropertyName.Equals("_MainTex"))
|
|||
|
{
|
|||
|
propertyToDo = Prop.doColor;
|
|||
|
if (sourceMat.HasProperty("_Color"))
|
|||
|
{
|
|||
|
m_tintColor = sourceMat.GetColor("_Color");
|
|||
|
} else
|
|||
|
{
|
|||
|
m_tintColor = m_generatingTintedAtlasColor;
|
|||
|
}
|
|||
|
} else if (shaderTexturePropertyName.Equals("_MetallicGlossMap"))
|
|||
|
{
|
|||
|
propertyToDo = Prop.doMetallic;
|
|||
|
m_metallic = m_generatingTintedAtlasMetallic;
|
|||
|
if (sourceMat.GetTexture("_MetallicGlossMap") != null)
|
|||
|
{
|
|||
|
m_hasMetallicGlossMap = true;
|
|||
|
} else
|
|||
|
{
|
|||
|
m_hasMetallicGlossMap = false;
|
|||
|
}
|
|||
|
|
|||
|
if (sourceMat.HasProperty("_Metallic"))
|
|||
|
{
|
|||
|
m_metallic = sourceMat.GetFloat("_Metallic");
|
|||
|
} else
|
|||
|
{
|
|||
|
m_metallic = 0f;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (shaderTexturePropertyName.Equals("_SpecGlossMap"))
|
|||
|
{
|
|||
|
propertyToDo = Prop.doRoughness;
|
|||
|
m_roughness = m_generatingTintedAtlasRoughness;
|
|||
|
if (sourceMat.GetTexture("_SpecGlossMap") != null)
|
|||
|
{
|
|||
|
m_hasSpecGlossMap = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_hasSpecGlossMap = false;
|
|||
|
}
|
|||
|
|
|||
|
if (sourceMat.HasProperty("_Glossiness"))
|
|||
|
{
|
|||
|
m_roughness = sourceMat.GetFloat("_Glossiness");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_roughness = 1f;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (shaderTexturePropertyName.Equals("_BumpMap"))
|
|||
|
{
|
|||
|
propertyToDo = Prop.doBump;
|
|||
|
if (sourceMat.HasProperty(shaderTexturePropertyName))
|
|||
|
{
|
|||
|
if (sourceMat.HasProperty("_BumpScale"))
|
|||
|
m_bumpScale = sourceMat.GetFloat("_BumpScale");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_bumpScale = m_generatingTintedAtlasBumpScale;
|
|||
|
}
|
|||
|
|
|||
|
} else if (shaderTexturePropertyName.Equals("_EmissionMap"))
|
|||
|
{
|
|||
|
propertyToDo = Prop.doEmission;
|
|||
|
m_shaderDoesEmission = sourceMat.IsKeywordEnabled("_EMISSION");
|
|||
|
if (sourceMat.HasProperty("_EmissionColor"))
|
|||
|
{
|
|||
|
m_emissionColor = sourceMat.GetColor("_EmissionColor");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_emissionColor = m_notGeneratingAtlasDefaultEmisionColor;
|
|||
|
}
|
|||
|
|
|||
|
} else
|
|||
|
{
|
|||
|
propertyToDo = Prop.doNone;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public Color OnBlendTexturePixel(string propertyToDoshaderPropertyName, Color pixelColor)
|
|||
|
{
|
|||
|
if (propertyToDo == Prop.doColor)
|
|||
|
{
|
|||
|
return new Color(pixelColor.r * m_tintColor.r, pixelColor.g * m_tintColor.g, pixelColor.b * m_tintColor.b, pixelColor.a * m_tintColor.a);
|
|||
|
} else if (propertyToDo == Prop.doMetallic)
|
|||
|
{
|
|||
|
if (m_hasMetallicGlossMap)
|
|||
|
{
|
|||
|
return pixelColor;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return new Color(m_metallic, 0, 0, m_roughness);
|
|||
|
}
|
|||
|
} else if (propertyToDo == Prop.doRoughness)
|
|||
|
{
|
|||
|
if (m_hasSpecGlossMap)
|
|||
|
{
|
|||
|
return pixelColor;
|
|||
|
} else
|
|||
|
{
|
|||
|
return new Color(m_roughness, 0, 0, 0);
|
|||
|
}
|
|||
|
} else if (propertyToDo == Prop.doBump)
|
|||
|
{
|
|||
|
return Color.Lerp(NeutralNormalMap, pixelColor, m_bumpScale);
|
|||
|
} else if (propertyToDo == Prop.doEmission)
|
|||
|
{
|
|||
|
if (m_shaderDoesEmission)
|
|||
|
{
|
|||
|
return new Color(pixelColor.r * m_emissionColor.r, pixelColor.g * m_emissionColor.g, pixelColor.b * m_emissionColor.b, pixelColor.a * m_emissionColor.a);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return Color.black;
|
|||
|
}
|
|||
|
}
|
|||
|
return pixelColor;
|
|||
|
}
|
|||
|
|
|||
|
public bool NonTexturePropertiesAreEqual(Material a, Material b)
|
|||
|
{
|
|||
|
if (!TextureBlenderFallback._compareColor(a, b, m_notGeneratingAtlasDefaultColor, "_Color"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool aHasMetallicTex = a.HasProperty("_MetallicGlossMap") && a.GetTexture("_MetallicGlossMap") != null;
|
|||
|
bool bHasMetallicTex = b.HasProperty("_MetallicGlossMap") && b.GetTexture("_MetallicGlossMap") != null;
|
|||
|
|
|||
|
if (!aHasMetallicTex && !bHasMetallicTex)
|
|||
|
{
|
|||
|
if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultMetallic, "_Metallic"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool aHasSpecTex = a.HasProperty("_SpecGlossMap") && a.GetTexture("_SpecGlossMap") != null;
|
|||
|
bool bHasSpecTex = b.HasProperty("_SpecGlossMap") && b.GetTexture("_SpecGlossMap") != null;
|
|||
|
if (!aHasSpecTex && !bHasSpecTex)
|
|||
|
{
|
|||
|
if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlasRoughness, "_Glossiness"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlasBumpScale, "_bumpScale"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlasRoughness, "_Glossiness"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (a.IsKeywordEnabled("_EMISSION") != b.IsKeywordEnabled("_EMISSION"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (a.IsKeywordEnabled("_EMISSION"))
|
|||
|
{
|
|||
|
if (!TextureBlenderFallback._compareColor(a, b, m_generatingTintedAtlasEmission, "_EmissionColor"))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
|
|||
|
{
|
|||
|
if (resultMaterial.GetTexture("_MainTex") != null)
|
|||
|
{
|
|||
|
resultMaterial.SetColor("_Color", m_generatingTintedAtlasColor);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
resultMaterial.SetColor("_Color", (Color)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Color", m_notGeneratingAtlasDefaultColor));
|
|||
|
}
|
|||
|
|
|||
|
if (resultMaterial.GetTexture("_MetallicGlossMap") != null)
|
|||
|
{
|
|||
|
resultMaterial.SetFloat("_Metallic", m_generatingTintedAtlasMetallic);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
resultMaterial.SetFloat("_Metallic", (float)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Metallic", m_notGeneratingAtlasDefaultMetallic));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (resultMaterial.GetTexture("_SpecGlossMap") != null)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
resultMaterial.SetFloat("_Glossiness", (float)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Glossiness", m_notGeneratingAtlasDefaultGlossiness));
|
|||
|
}
|
|||
|
|
|||
|
if (resultMaterial.GetTexture("_BumpMap") != null)
|
|||
|
{
|
|||
|
resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlasBumpScale);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlasBumpScale);
|
|||
|
}
|
|||
|
|
|||
|
if (resultMaterial.GetTexture("_EmissionMap") != null)
|
|||
|
{
|
|||
|
resultMaterial.EnableKeyword("_EMISSION");
|
|||
|
resultMaterial.SetColor("_EmissionColor", Color.white);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
resultMaterial.DisableKeyword("_EMISSION");
|
|||
|
resultMaterial.SetColor("_EmissionColor", (Color)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_EmissionColor", m_notGeneratingAtlasDefaultEmisionColor));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public Color GetColorIfNoTexture(Material mat, ShaderTextureProperty texPropertyName)
|
|||
|
{
|
|||
|
if (texPropertyName.name.Equals("_BumpMap"))
|
|||
|
{
|
|||
|
return new Color(.5f, .5f, 1f);
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_MainTex"))
|
|||
|
{
|
|||
|
if (mat != null && mat.HasProperty("_Color"))
|
|||
|
{
|
|||
|
try
|
|||
|
{ //need try because can't garantee _Color is a color
|
|||
|
Color c = mat.GetColor("_Color");
|
|||
|
sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Color", c);
|
|||
|
}
|
|||
|
catch (Exception) { }
|
|||
|
return Color.white;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_MetallicGlossMap"))
|
|||
|
{
|
|||
|
if (mat != null && mat.HasProperty("_Metallic"))
|
|||
|
{
|
|||
|
try
|
|||
|
{ //need try because can't garantee _Metallic is a float
|
|||
|
float v = mat.GetFloat("_Metallic");
|
|||
|
sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Metallic", v);
|
|||
|
}
|
|||
|
catch (Exception) { }
|
|||
|
return new Color(0f, 0f, 0f, .5f);
|
|||
|
} else
|
|||
|
{
|
|||
|
return new Color(0f,0f,0f,.5f);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_SpecGlossMap"))
|
|||
|
{
|
|||
|
bool success = false;
|
|||
|
|
|||
|
try
|
|||
|
{ //need try because can't garantee _Color is a color
|
|||
|
Color c = new Color(0f, 0f, 0f, .5f);
|
|||
|
if (mat.HasProperty("_Glossiness"))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
success = true;
|
|||
|
c.a = mat.GetFloat("_Glossiness");
|
|||
|
}
|
|||
|
catch (Exception) { }
|
|||
|
}
|
|||
|
sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Glossiness", c.a);
|
|||
|
return new Color(0f, 0f, 0f, .5f);
|
|||
|
}
|
|||
|
catch (Exception) { }
|
|||
|
if (!success)
|
|||
|
{
|
|||
|
return new Color(0f, 0f, 0f, .5f);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_ParallaxMap"))
|
|||
|
{
|
|||
|
return new Color(0f, 0f, 0f, 0f);
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_OcclusionMap"))
|
|||
|
{
|
|||
|
return new Color(1f, 1f, 1f, 1f);
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_EmissionMap"))
|
|||
|
{
|
|||
|
if (mat != null)
|
|||
|
{
|
|||
|
if (mat.IsKeywordEnabled("_EMISSION"))
|
|||
|
{
|
|||
|
if (mat.HasProperty("_EmissionColor"))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Color c = mat.GetColor("_EmissionColor");
|
|||
|
sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_EmissionColor", c);
|
|||
|
}
|
|||
|
catch (Exception) { }
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return Color.black;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return Color.black;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (texPropertyName.name.Equals("_DetailMask"))
|
|||
|
{
|
|||
|
return new Color(0f, 0f, 0f, 0f);
|
|||
|
}
|
|||
|
return new Color(1f, 1f, 1f, 0f);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|