summaryrefslogtreecommitdiff
path: root/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders
diff options
context:
space:
mode:
authortylermurphy534 <tylermurphy534@gmail.com>2022-11-06 15:12:42 -0500
committertylermurphy534 <tylermurphy534@gmail.com>2022-11-06 15:12:42 -0500
commiteb84bb298d2b95aec7b2ae12cbf25ac64f25379a (patch)
treeefd616a157df06ab661c6d56651853431ac6b08b /VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders
downloadunityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.tar.gz
unityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.tar.bz2
unityprojects-eb84bb298d2b95aec7b2ae12cbf25ac64f25379a.zip
move to self host
Diffstat (limited to 'VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders')
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs61
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs243
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs75
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs71
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs84
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs.meta12
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs343
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs397
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs.meta12
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs359
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs.meta8
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs588
-rw-r--r--VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs.meta11
18 files changed, 2304 insertions, 0 deletions
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs
new file mode 100644
index 00000000..36b9a01e
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs
@@ -0,0 +1,61 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ /// <summary>
+ /// A TextureBlender will attempt to blend non-texture properties with textures so that the result material looks the same as source material.
+ /// </summary>
+ public interface TextureBlender
+ {
+ /// <summary>
+ /// The shader name that must be matched on the result material in order for this TextureBlender to be used. This should return something like "Legacy/Bumped Difuse"
+ /// </summary>
+ bool DoesShaderNameMatch(string shaderName);
+
+ /// <summary>
+ /// This is called to prepare the TextureBlender before any calls to OnBlendTexturePixel
+ /// Use this to grab the non-texture property values from the material that will be used to alter the Pixel color in the texture.
+ /// Note that the sourceMat may not use a shader matching ShaderName. It may not have expected properties. Check that properties exist
+ /// before grabing them.
+ /// </summary>
+ void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName);
+
+ /// <summary>
+ /// Called once for each pixel in the texture to alter the pixel color. For efficiency don't check shaderPropertyName every call. Instead use OnBeforeTintTexture
+ /// to prepare this textrure blender for a batch of OnBlendTexturePixel calls.
+ /// </summary>
+ Color OnBlendTexturePixel(string shaderPropertyName, Color pixelColor);
+
+ /// <summary>
+ /// Material a & b may have the same set of textures but different non-texture properties (colorTint etc...)
+ /// If so then they need to be put into separate rectangels in the atlas. This method should check the non-texture properties
+ /// and return false if they are different. Note that material a and b may use a different shader than GetShaderName so your code
+ /// should handle the case where properties do not exist.
+ /// </summary>
+ bool NonTexturePropertiesAreEqual(Material a, Material b);
+
+ /// <summary>
+ /// Sets the non texture properties on the result materail after textures have been baked. If for example _Color has been blended with
+ /// the _Albedo textures then the _Color property on the result material should probably be set to white.
+ /// </summary>
+ void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial);
+
+ /// <summary>
+ /// Some textures may not be assigned for a material. This method should return a color that will used to create a small solid color texture
+ /// to be used in these cases. Note that this small solid color texture will later be blended using OnBlendTexturePixel. If the texturePropertyname is _mainTex
+ /// then the the returned color should probably be white so it looks correct when OnBlendTexturePixel blends the _Color.
+ ///
+ /// This is also used to determine if an atlas needs to be generated for a texture property. If all the source materials are missing the texture for
+ /// texPropertyName property (eg. _MainTex), but some of the source materials return different value for:
+ /// OnBlendTexturePixel(texturePropertyName, GetColorIfNoTexture(sourceMat, texturePropertyName))
+ /// Then an atlas will be generated with the different colors.
+ ///
+ /// This method can also be used to collect the value of non texture properties and cache them for each source material. This information can be useful
+ /// for setting values on the result material.
+ /// </summary>
+ Color GetColorIfNoTexture(Material m, ShaderTextureProperty texPropertyName);
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs.meta
new file mode 100644
index 00000000..d2e044be
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlender.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 646e6367ec395784ba07a11709c5dbc9
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs
new file mode 100644
index 00000000..efeda5be
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs
@@ -0,0 +1,243 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderFallback : TextureBlender
+ {
+ bool m_doTintColor = false;
+ Color m_tintColor;
+
+ Color m_defaultColor = Color.white;
+
+ public bool DoesShaderNameMatch(string shaderName)
+ {
+ return true; //matches everything
+ }
+
+ public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
+ {
+ if (shaderTexturePropertyName.Equals("_MainTex"))
+ {
+ m_doTintColor = true;
+ m_tintColor = Color.white;
+ if (sourceMat.HasProperty("_Color"))
+ {
+ m_tintColor = sourceMat.GetColor("_Color");
+ }
+ else if (sourceMat.HasProperty("_TintColor"))
+ {
+ m_tintColor = sourceMat.GetColor("_TintColor");
+ }
+ } else
+ {
+ m_doTintColor = false;
+ }
+ }
+
+ public Color OnBlendTexturePixel(string shaderPropertyName, Color pixelColor)
+ {
+ if (m_doTintColor)
+ {
+ return new Color(pixelColor.r * m_tintColor.r, pixelColor.g * m_tintColor.g, pixelColor.b * m_tintColor.b, pixelColor.a * m_tintColor.a);
+ }
+ return pixelColor;
+ }
+
+ public bool NonTexturePropertiesAreEqual(Material a, Material b)
+ {
+ if (a.HasProperty("_Color"))
+ {
+ if (_compareColor(a, b, m_defaultColor, "_Color"))
+ {
+ return true;
+ }
+ //return false;
+ }
+ else if (a.HasProperty("_TintColor"))
+ {
+ if (_compareColor(a, b, m_defaultColor, "_TintColor"))
+ {
+ return true;
+ }
+ //return false;
+ }
+ return false;
+ }
+
+ public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
+ {
+ if (resultMaterial.HasProperty("_Color"))
+ {
+ resultMaterial.SetColor("_Color", m_defaultColor);
+ }
+ else if (resultMaterial.HasProperty("_TintColor"))
+ {
+ resultMaterial.SetColor("_TintColor", m_defaultColor);
+ }
+ }
+
+ public Color GetColorIfNoTexture(Material mat, ShaderTextureProperty texProperty)
+ {
+ if (texProperty.isNormalMap)
+ {
+ return new Color(.5f, .5f, 1f);
+ }
+ else if (texProperty.name.Equals("_MainTex"))
+ {
+ if (mat != null && mat.HasProperty("_Color"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ return mat.GetColor("_Color");
+ }
+ catch (Exception) { }
+ }
+ else if (mat != null && mat.HasProperty("_TintColor"))
+ {
+ try
+ { //need try because can't garantee _TintColor is a color
+ return mat.GetColor("_TintColor");
+ }
+ catch (Exception) { }
+ }
+ }
+ else if (texProperty.name.Equals("_SpecGlossMap"))
+ {
+ if (mat != null && mat.HasProperty("_SpecColor"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ Color c = mat.GetColor("_SpecColor");
+ if (mat.HasProperty("_Glossiness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Glossiness");
+ }
+ catch (Exception) { }
+ }
+ Debug.LogWarning(c);
+ return c;
+ }
+ catch (Exception) { }
+ }
+ }
+ else if (texProperty.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");
+ Color c = new Color(v, v, v);
+ if (mat.HasProperty("_Glossiness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Glossiness");
+ }
+ catch (Exception) { }
+ }
+ return c;
+ }
+ catch (Exception) { }
+ }
+ }
+ else if (texProperty.name.Equals("_ParallaxMap"))
+ {
+ return new Color(0f, 0f, 0f, 0f);
+ }
+ else if (texProperty.name.Equals("_OcclusionMap"))
+ {
+ return new Color(1f, 1f, 1f, 1f);
+ }
+ else if (texProperty.name.Equals("_EmissionMap"))
+ {
+ if (mat != null)
+ {
+ if (mat.HasProperty("_EmissionScaleUI"))
+ {
+ //Standard shader has weird behavior if EmissionMap has never
+ //been set then no EmissionColorUI color picker. If has ever
+ //been set then is EmissionColorUI color picker.
+ if (mat.HasProperty("_EmissionColor") &&
+ mat.HasProperty("_EmissionColorUI"))
+ {
+ try
+ {
+ Color c1 = mat.GetColor("_EmissionColor");
+ Color c2 = mat.GetColor("_EmissionColorUI");
+ float f = mat.GetFloat("_EmissionScaleUI");
+ if (c1 == new Color(0f, 0f, 0f, 0f) &&
+ c2 == new Color(1f, 1f, 1f, 1f))
+ {
+ //is virgin Emission values
+ return new Color(f, f, f, f);
+ }
+ else { //non virgin Emission values
+ return c2;
+ }
+ }
+ catch (Exception) { }
+
+ }
+ else {
+ try
+ { //need try because can't garantee _Color is a color
+ float f = mat.GetFloat("_EmissionScaleUI");
+ return new Color(f, f, f, f);
+ }
+ catch (Exception) { }
+ }
+ }
+ }
+ }
+ else if (texProperty.name.Equals("_DetailMask"))
+ {
+ return new Color(0f, 0f, 0f, 0f);
+ }
+ return new Color(1f, 1f, 1f, 0f);
+ }
+
+ public static bool _compareColor(Material a, Material b, Color defaultVal, string propertyName)
+ {
+ Color aColor = defaultVal;
+ Color bColor = defaultVal;
+ if (a.HasProperty(propertyName))
+ {
+ aColor = a.GetColor(propertyName);
+ }
+ if (b.HasProperty(propertyName))
+ {
+ bColor = b.GetColor(propertyName);
+ }
+ if (aColor != bColor)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static bool _compareFloat(Material a, Material b, float defaultVal, string propertyName)
+ {
+ float aFloat = defaultVal;
+ float bFloat = defaultVal;
+ if (a.HasProperty(propertyName))
+ {
+ aFloat = a.GetFloat(propertyName);
+ }
+ if (b.HasProperty(propertyName))
+ {
+ bFloat = b.GetFloat(propertyName);
+ }
+ if (aFloat != bFloat)
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs.meta
new file mode 100644
index 00000000..db6067c9
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderFallback.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 71f9f92825289a14d83f3c273044b8e6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs
new file mode 100644
index 00000000..fb47947c
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs
@@ -0,0 +1,75 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderLegacyBumpDiffuse : TextureBlender
+ {
+ bool doColor;
+ Color m_tintColor;
+ Color m_defaultTintColor = Color.white;
+
+ public bool DoesShaderNameMatch(string shaderName)
+ {
+ if (shaderName.Equals ("Legacy Shaders/Bumped Diffuse")) {
+ return true;
+ } else if (shaderName.Equals ("Bumped Diffuse")) {
+ return true;
+ }
+ return false;
+ }
+
+ public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
+ {
+ if (shaderTexturePropertyName.EndsWith("_MainTex"))
+ {
+ doColor = true;
+ m_tintColor = sourceMat.GetColor("_Color");
+ } else
+ {
+ doColor = false;
+ }
+ }
+
+ public Color OnBlendTexturePixel(string propertyToDoshaderPropertyName, Color pixelColor)
+ {
+ if (doColor)
+ {
+ return new Color(pixelColor.r * m_tintColor.r, pixelColor.g * m_tintColor.g, pixelColor.b * m_tintColor.b, pixelColor.a * m_tintColor.a);
+ }
+ return pixelColor;
+ }
+
+ public bool NonTexturePropertiesAreEqual(Material a, Material b)
+ {
+ return TextureBlenderFallback._compareColor(a, b, m_defaultTintColor, "_Color");
+ }
+
+ public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
+ {
+ resultMaterial.SetColor("_Color", Color.white);
+ }
+
+ public Color GetColorIfNoTexture(Material m, ShaderTextureProperty texPropertyName)
+ {
+ if (texPropertyName.name.Equals("_BumpMap"))
+ {
+ return new Color(.5f, .5f, 1f);
+ }
+ if (texPropertyName.name.Equals("_MainTex"))
+ {
+ if (m != null && m.HasProperty("_Color"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ return m.GetColor("_Color");
+ }
+ catch (Exception) { }
+ }
+ }
+ return new Color(1,1,1,0);
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs.meta
new file mode 100644
index 00000000..91f648f2
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyBumpDiffuse.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4157773ac1b12a94a83d67cdbc18b534
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs
new file mode 100644
index 00000000..b1c3305c
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs
@@ -0,0 +1,71 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderLegacyDiffuse : TextureBlender
+ {
+ bool doColor;
+ Color m_tintColor;
+ Color m_defaultTintColor = Color.white;
+
+ public bool DoesShaderNameMatch(string shaderName)
+ {
+ if (shaderName.Equals ("Legacy Shaders/Diffuse")) {
+ return true;
+ } else if (shaderName.Equals ("Diffuse")) {
+ return true;
+ }
+ return false;
+ }
+
+ public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
+ {
+ if (shaderTexturePropertyName.EndsWith("_MainTex"))
+ {
+ doColor = true;
+ m_tintColor = sourceMat.GetColor("_Color");
+ } else
+ {
+ doColor = false;
+ }
+ }
+
+ public Color OnBlendTexturePixel(string propertyToDoshaderPropertyName, Color pixelColor)
+ {
+ if (doColor)
+ {
+ return new Color(pixelColor.r * m_tintColor.r, pixelColor.g * m_tintColor.g, pixelColor.b * m_tintColor.b, pixelColor.a * m_tintColor.a);
+ }
+ return pixelColor;
+ }
+
+ public bool NonTexturePropertiesAreEqual(Material a, Material b)
+ {
+ return TextureBlenderFallback._compareColor(a, b, m_defaultTintColor, "_Color");
+ }
+
+ public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
+ {
+ resultMaterial.SetColor("_Color", Color.white);
+ }
+
+ public Color GetColorIfNoTexture(Material m, ShaderTextureProperty texPropertyName)
+ {
+ if (texPropertyName.name.Equals("_MainTex"))
+ {
+ if (m != null && m.HasProperty("_Color"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ return m.GetColor("_Color");
+ }
+ catch (Exception) { }
+ }
+ }
+ return new Color(1,1,1,0);
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs.meta
new file mode 100644
index 00000000..1bbd92f9
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderLegacyDiffuse.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c86cc13385933e94a915ee9b0520efcb
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs
new file mode 100644
index 00000000..ebaf3cba
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs
@@ -0,0 +1,84 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderMaterialPropertyCacheHelper
+ {
+ private struct MaterialPropertyPair
+ {
+ public Material material;
+ public string property;
+
+ public MaterialPropertyPair(Material m, string prop)
+ {
+ material = m;
+ property = prop;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is MaterialPropertyPair)) return false;
+ MaterialPropertyPair b = (MaterialPropertyPair)obj;
+ if (!material.Equals(b.material)) return false;
+ if (property != b.property) return false;
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ }
+
+ private Dictionary<MaterialPropertyPair, object> nonTexturePropertyValuesForSourceMaterials = new Dictionary<MaterialPropertyPair, object>();
+
+ private bool AllNonTexturePropertyValuesAreEqual(string prop)
+ {
+ bool foundFirst = false;
+ object firstVal = null;
+ foreach (MaterialPropertyPair k in nonTexturePropertyValuesForSourceMaterials.Keys)
+ {
+ if (k.property.Equals(prop))
+ {
+ if (!foundFirst)
+ {
+ firstVal = nonTexturePropertyValuesForSourceMaterials[k];
+ foundFirst = true;
+ }
+ else
+ {
+ if (!firstVal.Equals(nonTexturePropertyValuesForSourceMaterials[k]))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ public void CacheMaterialProperty(Material m, string property, object value)
+ {
+ nonTexturePropertyValuesForSourceMaterials[new MaterialPropertyPair(m, property)] = value;
+ }
+
+ public object GetValueIfAllSourceAreTheSameOrDefault(string property, object defaultValue)
+ {
+ if (AllNonTexturePropertyValuesAreEqual(property))
+ {
+ foreach (MaterialPropertyPair k in nonTexturePropertyValuesForSourceMaterials.Keys)
+ {
+ if (k.property.Equals(property))
+ {
+ return nonTexturePropertyValuesForSourceMaterials[k];
+ }
+ }
+ }
+
+ return defaultValue;
+ }
+ }
+} \ No newline at end of file
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs.meta
new file mode 100644
index 00000000..7a2239a6
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderMaterialPropertyCacheHelper.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6ee4be839d395884797ef7560cd1d58c
+timeCreated: 1524701272
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs
new file mode 100644
index 00000000..d3eadb8a
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs
@@ -0,0 +1,343 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderStandardMetallic : TextureBlender
+ {
+ static Color NeutralNormalMap = new Color(.5f, .5f, 1f);
+
+ private enum Prop{
+ doColor,
+ doMetallic,
+ 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_glossiness;
+ float m_glossMapScale;
+ float m_metallic;
+ bool m_hasMetallicGlossMap;
+ 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_generatingTintedAtlasGlossiness = 1f;
+ float m_generatingTintedAtlasGlossMapScale = 1f;
+ 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") || shaderName.EndsWith("StandardTextureArray");
+ }
+
+ 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;
+ }
+
+ if (sourceMat.HasProperty("_GlossMapScale"))
+ {
+ m_glossMapScale = sourceMat.GetFloat("_GlossMapScale");
+ } else
+ {
+ m_glossMapScale = 1f;
+ }
+
+ if (sourceMat.HasProperty("_Glossiness"))
+ {
+ m_glossiness = sourceMat.GetFloat("_Glossiness");
+ } else
+ {
+ m_glossiness = 0f;
+ }
+
+ } 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 = new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a * m_glossMapScale);
+ }
+ else
+ {
+ return new Color(m_metallic, 0, 0, m_glossiness);
+ }
+ }
+ 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;
+ }
+
+ if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultGlossiness, "_Glossiness"))
+ {
+ 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, "_GlossMapScale"))
+ {
+ return false;
+ }
+ } else if (!aHasMetallicTex && !bHasMetallicTex)
+ {
+ if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultMetallic, "_Metallic"))
+ {
+ return false;
+ }
+ } else
+ {
+ return false;
+ }
+
+ if (a.IsKeywordEnabled("_EMISSION") != b.IsKeywordEnabled("_EMISSION"))
+ {
+ return false;
+ }
+ if (a.IsKeywordEnabled("_EMISSION"))
+ {
+ if (!TextureBlenderFallback._compareColor(a, b, m_notGeneratingAtlasDefaultEmisionColor, "_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);
+ resultMaterial.SetFloat("_GlossMapScale", m_generatingTintedAtlasGlossMapScale);
+ resultMaterial.SetFloat("_Glossiness", m_generatingTintedAtlasGlossiness);
+ } else
+ {
+ resultMaterial.SetFloat("_Metallic", (float) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Metallic", m_notGeneratingAtlasDefaultMetallic));
+ resultMaterial.SetFloat("_Glossiness", (float) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Glossiness", m_notGeneratingAtlasDefaultGlossiness));
+ }
+
+ if (resultMaterial.GetTexture("_BumpMap") != null)
+ {
+ resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlasBumpScale);
+ }
+
+ if (resultMaterial.GetTexture("_EmissionMap") != null)
+ {
+ resultMaterial.EnableKeyword("_EMISSION");
+ resultMaterial.SetColor("_EmissionColor", m_generatingTintedAtlasEmission);
+ }
+ 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);
+ return 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");
+ Color c = new Color(v, v, v);
+ if (mat.HasProperty("_Glossiness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Glossiness");
+ }
+
+ catch (Exception) { }
+ }
+
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Metallic", v);
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Glossiness", c.a);
+ return c;
+ }
+ catch (Exception) { }
+ return new Color(0f, 0f, 0f, .5f);
+ } else
+ {
+ 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);
+ return 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);
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs.meta
new file mode 100644
index 00000000..967edfc5
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallic.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ad6e327911774fb4d9cf5c3b4c233d15
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs
new file mode 100644
index 00000000..3fae60ad
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs
@@ -0,0 +1,397 @@
+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);
+ return 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);
+ return 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);
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs.meta
new file mode 100644
index 00000000..0afcdc18
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardMetallicRoughness.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 93f246464bc2f0e468fdc4761cc80c6c
+timeCreated: 1524695231
+licenseType: Store
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs
new file mode 100644
index 00000000..dd91a79f
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs
@@ -0,0 +1,359 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderStandardSpecular : TextureBlender
+ {
+ static Color NeutralNormalMap = new Color(.5f, .5f, 1f);
+
+ private enum Prop
+ {
+ doColor,
+ doSpecular,
+ 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_glossiness;
+ float m_SpecGlossMapScale;
+ Color m_specColor;
+ 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_generatingTintedAtlaColor = Color.white;
+ Color m_generatingTintedAtlaSpecular = Color.black;
+ float m_generatingTintedAtlaGlossiness = 1f;
+ float m_generatingTintedAtlaSpecGlossMapScale = 1f;
+ float m_generatingTintedAtlaBumpScale = 1f;
+ Color m_generatingTintedAtlaEmission = 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;
+ Color m_notGeneratingAtlasDefaultSpecularColor = new Color(0f,0f,0f,1f);
+ float m_notGeneratingAtlasDefaultGlossiness = .5f;
+ Color m_notGeneratingAtlasDefaultEmisionColor = Color.black;
+
+ public bool DoesShaderNameMatch(string shaderName)
+ {
+ return shaderName.Equals("Standard (Specular 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_generatingTintedAtlaColor;
+ }
+ }
+ else if (shaderTexturePropertyName.Equals("_SpecGlossMap"))
+ {
+ propertyToDo = Prop.doSpecular;
+ m_specColor = m_generatingTintedAtlaSpecular;
+ if (sourceMat.GetTexture("_SpecGlossMap") != null)
+ {
+ m_hasSpecGlossMap = true;
+ }
+ else
+ {
+ m_hasSpecGlossMap = false;
+ }
+
+ if (sourceMat.HasProperty("_SpecColor"))
+ {
+ m_specColor = sourceMat.GetColor("_SpecColor");
+ } else
+ {
+ m_specColor = new Color(0f, 0f, 0f, 1f);
+ }
+
+ if (sourceMat.HasProperty("_GlossMapScale"))
+ {
+ m_SpecGlossMapScale = sourceMat.GetFloat("_GlossMapScale");
+ }
+ else
+ {
+ m_SpecGlossMapScale = 1f;
+ }
+
+ if (sourceMat.HasProperty("_Glossiness"))
+ {
+ m_glossiness = sourceMat.GetFloat("_Glossiness");
+ }
+ else
+ {
+ m_glossiness = 0f;
+ }
+ } 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_generatingTintedAtlaBumpScale;
+ }
+ } else if (shaderTexturePropertyName.Equals("_EmissionMap"))
+ {
+ propertyToDo = Prop.doEmission;
+ m_shaderDoesEmission = sourceMat.IsKeywordEnabled("_EMISSION");
+ if (sourceMat.HasProperty("_EmissionColor")) {
+ m_emissionColor = sourceMat.GetColor("_EmissionColor");
+ } else
+ {
+ m_generatingTintedAtlaColor = 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.doSpecular)
+ {
+ if (m_hasSpecGlossMap)
+ {
+ return pixelColor = new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a * m_SpecGlossMapScale);
+ }
+ else
+ {
+ Color c = m_specColor;
+ c.a = m_glossiness;
+ return c;
+ }
+ }
+ 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_generatingTintedAtlaColor, "_Color"))
+ {
+ return false;
+ }
+
+ if (!TextureBlenderFallback._compareColor(a, b, m_generatingTintedAtlaSpecular, "_SpecColor"))
+ {
+ 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_generatingTintedAtlaSpecGlossMapScale, "_GlossMapScale"))
+ {
+ return false;
+ }
+ }
+ else if (!aHasSpecTex && !bHasSpecTex)
+ {
+ if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlaGlossiness, "_Glossiness"))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlaBumpScale, "_BumpScale"))
+ {
+ return false;
+ }
+
+ if (a.IsKeywordEnabled("_EMISSION") != b.IsKeywordEnabled("_EMISSION"))
+ {
+ return false;
+ }
+ if (a.IsKeywordEnabled("_EMISSION"))
+ {
+ if (!TextureBlenderFallback._compareColor(a, b, m_generatingTintedAtlaEmission, "_EmissionColor"))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
+ {
+ if (resultMaterial.GetTexture("_MainTex") != null)
+ {
+ resultMaterial.SetColor("_Color", m_generatingTintedAtlaColor);
+ }
+ else
+ {
+ resultMaterial.SetColor("_Color", (Color)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Color", m_notGeneratingAtlasDefaultColor));
+ }
+
+ if (resultMaterial.GetTexture("_SpecGlossMap") != null) {
+ resultMaterial.SetColor("_SpecColor", m_generatingTintedAtlaSpecular);
+ resultMaterial.SetFloat("_GlossMapScale", m_generatingTintedAtlaSpecGlossMapScale);
+ resultMaterial.SetFloat("_Glossiness", m_generatingTintedAtlaGlossiness);
+ } else {
+ resultMaterial.SetColor("_SpecColor", (Color) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_SpecColor", m_notGeneratingAtlasDefaultSpecularColor));
+ resultMaterial.SetFloat("_Glossiness", (float) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Glossiness", m_notGeneratingAtlasDefaultGlossiness));
+ }
+
+ if (resultMaterial.GetTexture("_BumpMap") != null)
+ {
+ resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlaBumpScale);
+ }
+ else
+ {
+ resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlaBumpScale);
+ }
+
+ 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);
+ return c;
+ }
+ catch (Exception) { }
+ return Color.white;
+ }
+ }
+ else if (texPropertyName.name.Equals("_SpecGlossMap"))
+ {
+ if (mat != null && mat.HasProperty("_SpecColor"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ Color c = mat.GetColor("_SpecColor");
+ if (mat.HasProperty("_Glossiness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Glossiness");
+ }
+ catch (Exception) { }
+ }
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_SpecColor", c);
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Glossiness", c.a);
+ return c;
+ }
+ catch (Exception) { }
+ }
+ 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);
+ return 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);
+ }
+
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs.meta
new file mode 100644
index 00000000..a58af881
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderStandardSpecular.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3a3737d1f36bf3b4c889c6f805d700bd
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs
new file mode 100644
index 00000000..943d3109
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs
@@ -0,0 +1,588 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System;
+
+namespace DigitalOpus.MB.Core
+{
+ public class TextureBlenderURPLit : TextureBlender
+ {
+ static Color NeutralNormalMap = new Color(.5f, .5f, 1f);
+
+ private enum Prop
+ {
+ doColor,
+ doSpecular,
+ doMetallic,
+ doEmission,
+ doBump,
+ doNone,
+ }
+
+ private enum WorkflowMode
+ {
+ unknown,
+ metallic,
+ specular,
+ }
+
+ private enum SmoothnessTextureChannel
+ {
+ unknown,
+ albedo,
+ metallicSpecular,
+ }
+
+ // 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();
+
+ WorkflowMode m_workflowMode = WorkflowMode.unknown;
+
+ SmoothnessTextureChannel m_smoothnessTextureChannel = SmoothnessTextureChannel.unknown;
+
+ // These are cached values read in OnBeforeTintTexture and used when blending pixels.
+ Color m_tintColor;
+
+ float m_smoothness; // shared by both metallic maps and spec maps
+
+ Color m_specColor; // Used if no spec map
+ bool m_hasSpecGlossMap;
+
+ float m_metallic; // Used if no metallic map
+ bool m_hasMetallicGlossMap;
+
+ 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_generatingTintedAtlaColor = Color.white;
+ float m_generatingTintedAtlasMetallic = 0f;
+ Color m_generatingTintedAtlaSpecular = Color.black;
+ float m_generatingTintedAtlasMetallic_smoothness = 1f;
+ float m_generatingTintedAtlasSpecular_somoothness = 1f;
+ float m_generatingTintedAtlaBumpScale = 1f;
+ Color m_generatingTintedAtlaEmission = 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_notGeneratingAtlasDefaultSmoothness_MetallicWorkflow = 0f;
+ float m_notGeneratingAtlasDefaultSmoothness_SpecularWorkflow = 1f;
+ Color m_notGeneratingAtlasDefaultSpecularColor = new Color(.2f,.2f,.2f,1f);
+ Color m_notGeneratingAtlasDefaultEmisionColor = Color.black;
+
+ public bool DoesShaderNameMatch(string shaderName)
+ {
+ return shaderName.Equals("Universal Render Pipeline/Lit") ||
+ shaderName.Equals("Universal Render Pipeline/Simple Lit") ||
+ shaderName.Equals("Universal Render Pipeline/Baked Lit");
+ }
+
+ private WorkflowMode _MapFloatToWorkflowMode(float workflowMode)
+ {
+ if (workflowMode == 0f)
+ {
+ return WorkflowMode.specular;
+ }
+ else
+ {
+ return WorkflowMode.metallic;
+ }
+ }
+
+ private float _MapWorkflowModeToFloat(WorkflowMode workflowMode)
+ {
+ if (workflowMode == WorkflowMode.specular)
+ {
+ return 0f;
+ } else
+ {
+ return 1f;
+ }
+ }
+
+ private SmoothnessTextureChannel _MapFloatToTextureChannel(float texChannel)
+ {
+ if (texChannel == 0f)
+ {
+ return SmoothnessTextureChannel.metallicSpecular;
+ }
+ else
+ {
+ return SmoothnessTextureChannel.albedo;
+ }
+ }
+
+ private float _MapTextureChannelToFloat(SmoothnessTextureChannel workflowMode)
+ {
+ if (workflowMode == SmoothnessTextureChannel.metallicSpecular)
+ {
+ return 0f;
+ }
+ else
+ {
+ return 1f;
+ }
+ }
+
+ public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
+ {
+ if (m_workflowMode == WorkflowMode.unknown)
+ {
+ if (sourceMat.HasProperty("_WorkflowMode"))
+ {
+ m_workflowMode = _MapFloatToWorkflowMode(sourceMat.GetFloat("_WorkflowMode"));
+ }
+ } else
+ {
+ if (sourceMat.HasProperty("_WorkflowMode") && _MapFloatToWorkflowMode(sourceMat.GetFloat("_WorkflowMode")) != m_workflowMode)
+ {
+ Debug.LogError("Using the Universal Render Pipeline TextureBlender to blend non-texture-propertyes. Some of the source materials used different 'WorkflowModes'. These "+
+ " cannot be blended properly. Results will be unpredictable.");
+ }
+ }
+
+ if (m_smoothnessTextureChannel == SmoothnessTextureChannel.unknown)
+ {
+ if (sourceMat.HasProperty("_SmoothnessTextureChannel"))
+ {
+ m_smoothnessTextureChannel = _MapFloatToTextureChannel(sourceMat.GetFloat("_SmoothnessTextureChannel"));
+ }
+ } else
+ {
+ if (sourceMat.HasProperty("_SmoothnessTextureChannel") && _MapFloatToTextureChannel(sourceMat.GetFloat("_SmoothnessTextureChannel")) != m_smoothnessTextureChannel)
+ {
+ Debug.LogError("Using the Universal Render Pipeline TextureBlender to blend non-texture-properties. Some of the source materials store smoothness in the Albedo texture alpha" +
+ " and some source materials store smoothness in the Metallic/Specular texture alpha channel. The result material can only read smoothness from one or the other. Results will be unpredictable.");
+ }
+ }
+
+ if (shaderTexturePropertyName.Equals("_BaseMap"))
+ {
+ propertyToDo = Prop.doColor;
+ if (sourceMat.HasProperty("_BaseColor"))
+ {
+ m_tintColor = sourceMat.GetColor("_BaseColor");
+ }
+ else
+ {
+ m_tintColor = m_generatingTintedAtlaColor;
+ }
+ }
+ else if (shaderTexturePropertyName.Equals("_SpecGlossMap"))
+ {
+ propertyToDo = Prop.doSpecular;
+ m_specColor = m_generatingTintedAtlaSpecular;
+ if (sourceMat.GetTexture("_SpecGlossMap") != null)
+ {
+ m_hasSpecGlossMap = true;
+ }
+ else
+ {
+ m_hasSpecGlossMap = false;
+ }
+
+ if (sourceMat.HasProperty("_SpecColor"))
+ {
+ m_specColor = sourceMat.GetColor("_SpecColor");
+ } else
+ {
+ m_specColor = new Color(0f, 0f, 0f, 1f);
+ }
+
+ if (sourceMat.HasProperty("_Smoothness") && m_workflowMode == WorkflowMode.specular)
+ {
+ m_smoothness = sourceMat.GetFloat("_Smoothness");
+ Debug.LogError("TODO smooth " + sourceMat + " " + m_smoothness);
+ }
+ else if (m_workflowMode == WorkflowMode.specular)
+ {
+ m_smoothness = 1f;
+ }
+ }
+ else if (shaderTexturePropertyName.Equals("_MetallicGlossMap"))
+ {
+ propertyToDo = Prop.doMetallic;
+ 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;
+ }
+
+ if (sourceMat.HasProperty("_Smoothness") && m_workflowMode == WorkflowMode.metallic)
+ {
+ m_smoothness = sourceMat.GetFloat("_Smoothness");
+ }
+ else if (m_workflowMode == WorkflowMode.metallic)
+ {
+ m_smoothness = 0f;
+ }
+
+
+ }
+ 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_generatingTintedAtlaBumpScale;
+ }
+ } else if (shaderTexturePropertyName.Equals("_EmissionMap"))
+ {
+ propertyToDo = Prop.doEmission;
+ m_shaderDoesEmission = sourceMat.IsKeywordEnabled("_EMISSION");
+ if (sourceMat.HasProperty("_EmissionColor")) {
+ m_emissionColor = sourceMat.GetColor("_EmissionColor");
+ } else
+ {
+ m_generatingTintedAtlaColor = m_notGeneratingAtlasDefaultEmisionColor;
+ }
+ } else
+ {
+ propertyToDo = Prop.doNone;
+ }
+ Debug.LogError("TODO end " + m_smoothness + " " + sourceMat + " " + shaderTexturePropertyName);
+ }
+
+ 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 = new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a * m_smoothness);
+ }
+ else
+ {
+ return new Color(m_metallic, 0, 0, m_smoothness);
+ }
+ }
+ else if (propertyToDo == Prop.doSpecular)
+ {
+ if (m_hasSpecGlossMap)
+ {
+ return pixelColor = new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a * m_smoothness);
+ }
+ else
+ {
+ Color c = m_specColor;
+ c.a = m_smoothness;
+ return c;
+ }
+ }
+ 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_generatingTintedAtlaColor, "_BaseColor"))
+ {
+ return false;
+ }
+
+ if (!TextureBlenderFallback._compareColor(a, b, m_generatingTintedAtlaSpecular, "_SpecColor"))
+ {
+ return false;
+ }
+
+ if (m_workflowMode == WorkflowMode.specular){
+ 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_notGeneratingAtlasDefaultSmoothness_SpecularWorkflow, "_Smoothness"))
+ {
+ Debug.LogError("Are equal A");
+ return false;
+ }
+ }
+ else if (!aHasSpecTex && !bHasSpecTex)
+ {
+ if (!TextureBlenderFallback._compareColor(a, b, m_notGeneratingAtlasDefaultSpecularColor, "_SpecColor") &&
+ !TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultSmoothness_SpecularWorkflow, "_Smoothness"))
+ {
+ Debug.LogError("Are equal B");
+ return false;
+ }
+ }
+ else
+ {
+ Debug.LogError("Are equal C");
+ return false;
+ }
+ }
+
+ if (m_workflowMode == WorkflowMode.metallic) {
+ 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_notGeneratingAtlasDefaultSmoothness_MetallicWorkflow, "_Smoothness"))
+ {
+ return false;
+ }
+ }
+ else if (!aHasMetallicTex && !bHasMetallicTex)
+ {
+ if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultMetallic, "_Metallic") &&
+ !TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultSmoothness_MetallicWorkflow, "_Smoothness"))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (!TextureBlenderFallback._compareFloat(a, b, m_generatingTintedAtlaBumpScale, "_BumpScale"))
+ {
+ return false;
+ }
+
+ if (a.IsKeywordEnabled("_EMISSION") != b.IsKeywordEnabled("_EMISSION"))
+ {
+ return false;
+ }
+ if (a.IsKeywordEnabled("_EMISSION"))
+ {
+ if (!TextureBlenderFallback._compareColor(a, b, m_generatingTintedAtlaEmission, "_EmissionColor"))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
+ {
+ if (m_workflowMode != WorkflowMode.unknown)
+ {
+ resultMaterial.SetFloat("_WorkflowMode", _MapWorkflowModeToFloat(m_workflowMode));
+ }
+
+ if (m_smoothnessTextureChannel != SmoothnessTextureChannel.unknown)
+ {
+ resultMaterial.SetFloat("_SmoothnessTextureChannel", _MapTextureChannelToFloat(m_smoothnessTextureChannel));
+ }
+
+ if (resultMaterial.GetTexture("_BaseMap") != null)
+ {
+ resultMaterial.SetColor("_BaseColor", m_generatingTintedAtlaColor);
+ }
+ else
+ {
+ resultMaterial.SetColor("_BaseColor", (Color)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_BaseColor", m_notGeneratingAtlasDefaultColor));
+ }
+
+ if (m_workflowMode == WorkflowMode.specular)
+ {
+ if (resultMaterial.GetTexture("_SpecGlossMap") != null)
+ {
+ Debug.LogError("Setting A " + m_smoothness);
+ resultMaterial.SetColor("_SpecColor", m_generatingTintedAtlaSpecular);
+ resultMaterial.SetFloat("_Smoothness", m_generatingTintedAtlasSpecular_somoothness);
+ }
+ else
+ {
+ Debug.LogError("Setting B " + m_smoothness);
+ resultMaterial.SetColor("_SpecColor", (Color)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_SpecColor", m_notGeneratingAtlasDefaultSpecularColor));
+ resultMaterial.SetFloat("_Smoothness", m_smoothness);
+ }
+ }
+
+ if (m_workflowMode == WorkflowMode.metallic)
+ {
+ if (resultMaterial.GetTexture("_MetallicGlossMap") != null)
+ {
+ resultMaterial.SetFloat("_Metallic", m_generatingTintedAtlasMetallic);
+ resultMaterial.SetFloat("_Smoothness", m_generatingTintedAtlasMetallic_smoothness);
+ }
+ else
+ {
+ resultMaterial.SetFloat("_Metallic", (float)sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Metallic", m_notGeneratingAtlasDefaultMetallic));
+ resultMaterial.SetFloat("_Smoothness", m_smoothness);
+ }
+ }
+
+ if (resultMaterial.GetTexture("_BumpMap") != null)
+ {
+ resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlaBumpScale);
+ }
+ else
+ {
+ resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlaBumpScale);
+ }
+
+ 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("_BaseMap"))
+ {
+ if (mat != null && mat.HasProperty("_BaseColor"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ Color c = mat.GetColor("_BaseColor");
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_BaseColor", c);
+ }
+ catch (Exception) { }
+ return Color.white;
+ }
+ }
+ else if (texPropertyName.name.Equals("_SpecGlossMap"))
+ {
+ if (mat != null && mat.HasProperty("_SpecColor"))
+ {
+ try
+ { //need try because can't garantee _Color is a color
+ Color c = mat.GetColor("_SpecColor");
+ /*
+ if (mat.HasProperty("_Glossiness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Glossiness");
+ }
+ catch (Exception) { }
+ }
+ */
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_SpecColor", c);
+ //sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Glossiness", c.a);
+ }
+ catch (Exception) { }
+ }
+ return new Color(0f, 0f, 0f, .5f);
+ }
+ 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");
+ Color c = new Color(v, v, v);
+
+ if (mat.HasProperty("_Smoothness"))
+ {
+ try
+ {
+ c.a = mat.GetFloat("_Smoothness");
+ }
+
+ catch (Exception) { }
+ }
+
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Metallic", v);
+ sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Smoothness", c.a);
+ }
+ catch (Exception) { }
+ return new Color(0f, 0f, 0f, .5f);
+ }
+ else
+ {
+ return new Color(0f, 0f, 0f, .5f);
+ }
+ }
+ 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);
+ }
+
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs.meta b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs.meta
new file mode 100644
index 00000000..e793edaf
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/MeshBaker/scripts/TextureBlenders/TextureBlenderURPLit.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 727a1b5619dc36f43a2d00164cd6c964
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: