343 lines
16 KiB
C#
343 lines
16 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEditor.AssetImporters;
|
||
|
using UnityEngine.Rendering;
|
||
|
using UnityEngine.Rendering.Universal;
|
||
|
|
||
|
namespace UnityEditor.Rendering.Universal
|
||
|
{
|
||
|
class AutodeskInteractiveMaterialImport : AssetPostprocessor
|
||
|
{
|
||
|
static readonly uint k_Version = 2;
|
||
|
static readonly int k_Order = -970;
|
||
|
public override uint GetVersion()
|
||
|
{
|
||
|
return k_Version;
|
||
|
}
|
||
|
|
||
|
public override int GetPostprocessOrder()
|
||
|
{
|
||
|
return k_Order;
|
||
|
}
|
||
|
|
||
|
public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips)
|
||
|
{
|
||
|
var pipelineAsset = GraphicsSettings.currentRenderPipeline;
|
||
|
if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset))
|
||
|
return;
|
||
|
|
||
|
if (IsAutodeskInteractiveMaterial(description))
|
||
|
{
|
||
|
float floatProperty;
|
||
|
Vector4 vectorProperty;
|
||
|
TexturePropertyDescription textureProperty;
|
||
|
|
||
|
bool isMasked = description.TryGetProperty("mask_threshold", out floatProperty);
|
||
|
bool isTransparent = description.TryGetProperty("opacity", out floatProperty);
|
||
|
|
||
|
Shader shader;
|
||
|
if (isMasked)
|
||
|
shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveMaskedShader;
|
||
|
else if (isTransparent)
|
||
|
shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader;
|
||
|
else
|
||
|
shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader;
|
||
|
|
||
|
if (shader == null)
|
||
|
return;
|
||
|
|
||
|
material.shader = shader;
|
||
|
foreach (var clip in clips)
|
||
|
{
|
||
|
clip.ClearCurves();
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("base_color", out vectorProperty))
|
||
|
material.SetColor("_Color", vectorProperty);
|
||
|
if (description.TryGetProperty("emissive", out vectorProperty))
|
||
|
material.SetColor("_EmissionColor", vectorProperty);
|
||
|
|
||
|
if (description.TryGetProperty("roughness", out floatProperty))
|
||
|
material.SetFloat("_Roughness", floatProperty);
|
||
|
|
||
|
if (description.TryGetProperty("metallic", out floatProperty))
|
||
|
material.SetFloat("_Metallic", floatProperty);
|
||
|
|
||
|
if (description.TryGetProperty("uvTransform", out vectorProperty))
|
||
|
{
|
||
|
material.SetVector("_UvOffset", new Vector4(vectorProperty.x, vectorProperty.y, .0f, .0f));
|
||
|
material.SetVector("_UvTiling", new Vector4(vectorProperty.w, vectorProperty.z, .0f, .0f));
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("TEX_color_map", out textureProperty))
|
||
|
{
|
||
|
material.SetTexture("_MainTex", textureProperty.texture);
|
||
|
material.SetFloat("_UseColorMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("_UseColorMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("TEX_normal_map", out textureProperty))
|
||
|
{
|
||
|
material.SetTexture("_BumpMap", textureProperty.texture);
|
||
|
material.SetFloat("_UseNormalMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("_UseNormalMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("TEX_roughness_map", out textureProperty))
|
||
|
{
|
||
|
material.SetTexture("RoughnessMap", textureProperty.texture);
|
||
|
material.SetFloat("_UseRoughnessMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("_UseRoughnessMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("TEX_metallic_map", out textureProperty))
|
||
|
{
|
||
|
material.SetTexture("_MetallicMap", textureProperty.texture);
|
||
|
material.SetFloat("_UseMetallicMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("_UseMetallicMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("TEX_emissive_map", out textureProperty))
|
||
|
{
|
||
|
material.SetTexture("_EmissionMap", textureProperty.texture);
|
||
|
material.SetFloat("_UseEmissiveMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("_UseEmissiveMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("hasTransparencyTexture", out floatProperty))
|
||
|
material.SetFloat("_UseOpacityMap", floatProperty);
|
||
|
|
||
|
if (description.TryGetProperty("transparencyMaskThreshold", out floatProperty))
|
||
|
material.SetFloat("_OpacityThreshold", floatProperty);
|
||
|
|
||
|
if (description.TryGetProperty("TEX_ao_map", out textureProperty))
|
||
|
{
|
||
|
var tex = AssetDatabase.LoadAssetAtPath<Texture>(textureProperty.relativePath);
|
||
|
material.SetTexture("AoMap", tex);
|
||
|
material.SetFloat("UseAoMap", 1.0f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
material.SetFloat("UseAoMap", 0.0f);
|
||
|
}
|
||
|
|
||
|
RemapColorCurves(description, clips, "base_color", "_Color");
|
||
|
RemapCurve(description, clips, "mask_threshold", "_Cutoff");
|
||
|
RemapCurve(description, clips, "metallic", "_Metallic");
|
||
|
RemapCurve(description, clips, "roughness", "_Glossiness");
|
||
|
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
if (description.HasAnimationCurveInClip(clips[i].name, "uv_scale.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_scale.y"))
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.x", out curve))
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvTiling.x", curve);
|
||
|
else
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvTiling.x", AnimationCurve.Constant(0.0f, 1.0f, 1.0f));
|
||
|
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.y", out curve))
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvTiling.y", curve);
|
||
|
else
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvTiling.y", AnimationCurve.Constant(0.0f, 1.0f, 1.0f));
|
||
|
}
|
||
|
|
||
|
if (description.HasAnimationCurveInClip(clips[i].name, "uv_offset.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_offset.y"))
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.x", out curve))
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvOffset.x", curve);
|
||
|
else
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvOffset.x", AnimationCurve.Constant(0.0f, 1.0f, 0.0f));
|
||
|
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.y", out curve))
|
||
|
{
|
||
|
ConvertKeys(curve, ConvertFloatNegate);
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvOffset.y", curve);
|
||
|
}
|
||
|
else
|
||
|
clips[i].SetCurve("", typeof(Material), "_UvOffset.y", AnimationCurve.Constant(0.0f, 1.0f, 0.0f));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (description.HasAnimationCurve("emissive_intensity"))
|
||
|
{
|
||
|
Vector4 emissiveColor;
|
||
|
description.TryGetProperty("emissive", out emissiveColor);
|
||
|
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve);
|
||
|
// remap emissive intensity to emission color
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve);
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve);
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve);
|
||
|
}
|
||
|
}
|
||
|
else if (description.TryGetProperty("emissive", out vectorProperty))
|
||
|
{
|
||
|
if (vectorProperty.x > 0.0f || vectorProperty.y > 0.0f || vectorProperty.z > 0.0f)
|
||
|
{
|
||
|
material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive;
|
||
|
material.EnableKeyword("_EMISSION");
|
||
|
}
|
||
|
|
||
|
if (description.TryGetProperty("emissive_intensity", out floatProperty))
|
||
|
{
|
||
|
vectorProperty *= floatProperty;
|
||
|
}
|
||
|
|
||
|
material.SetColor("_EmissionColor", vectorProperty);
|
||
|
|
||
|
|
||
|
if (description.HasAnimationCurve("emissive.x"))
|
||
|
{
|
||
|
if (description.HasAnimationCurve("emissive_intensity"))
|
||
|
{
|
||
|
// combine color and intensity.
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
AnimationCurve intensityCurve;
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out intensityCurve);
|
||
|
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive.x", out curve);
|
||
|
MultiplyCurves(curve, intensityCurve);
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve);
|
||
|
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive.y", out curve);
|
||
|
MultiplyCurves(curve, intensityCurve);
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve);
|
||
|
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive.z", out curve);
|
||
|
MultiplyCurves(curve, intensityCurve);
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RemapColorCurves(description, clips, "emissive", "_EmissionColor");
|
||
|
}
|
||
|
}
|
||
|
else if (description.HasAnimationCurve("emissive_intensity"))
|
||
|
{
|
||
|
Vector4 emissiveColor;
|
||
|
description.TryGetProperty("emissive", out emissiveColor);
|
||
|
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve);
|
||
|
// remap emissive intensity to emission color
|
||
|
AnimationCurve curveR = new AnimationCurve();
|
||
|
ConvertAndCopyKeys(curveR, curve, value => ConvertFloatMultiply(emissiveColor.x, value));
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curveR);
|
||
|
|
||
|
AnimationCurve curveG = new AnimationCurve();
|
||
|
ConvertAndCopyKeys(curveG, curve, value => ConvertFloatMultiply(emissiveColor.y, value));
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curveG);
|
||
|
|
||
|
AnimationCurve curveB = new AnimationCurve();
|
||
|
ConvertAndCopyKeys(curveB, curve, value => ConvertFloatMultiply(emissiveColor.z, value));
|
||
|
clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curveB);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static bool IsAutodeskInteractiveMaterial(MaterialDescription description)
|
||
|
{
|
||
|
return description.TryGetProperty("renderAPI", out string stringValue) && stringValue == "SFX_PBS_SHADER";
|
||
|
}
|
||
|
|
||
|
static void ConvertKeys(AnimationCurve curve, System.Func<float, float> convertionDelegate)
|
||
|
{
|
||
|
Keyframe[] keyframes = curve.keys;
|
||
|
for (int i = 0; i < keyframes.Length; i++)
|
||
|
{
|
||
|
keyframes[i].value = convertionDelegate(keyframes[i].value);
|
||
|
}
|
||
|
curve.keys = keyframes;
|
||
|
}
|
||
|
|
||
|
static void ConvertAndCopyKeys(AnimationCurve curveDest, AnimationCurve curveSource, System.Func<float, float> convertionDelegate)
|
||
|
{
|
||
|
for (int i = 0; i < curveSource.keys.Length; i++)
|
||
|
{
|
||
|
var sourceKey = curveSource.keys[i];
|
||
|
curveDest.AddKey(new Keyframe(sourceKey.time, convertionDelegate(sourceKey.value), sourceKey.inTangent, sourceKey.outTangent, sourceKey.inWeight, sourceKey.outWeight));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static float ConvertFloatNegate(float value)
|
||
|
{
|
||
|
return -value;
|
||
|
}
|
||
|
|
||
|
static float ConvertFloatMultiply(float value, float multiplier)
|
||
|
{
|
||
|
return value * multiplier;
|
||
|
}
|
||
|
|
||
|
static void MultiplyCurves(AnimationCurve curve, AnimationCurve curveMultiplier)
|
||
|
{
|
||
|
Keyframe[] keyframes = curve.keys;
|
||
|
for (int i = 0; i < keyframes.Length; i++)
|
||
|
{
|
||
|
keyframes[i].value *= curveMultiplier.Evaluate(keyframes[i].time);
|
||
|
}
|
||
|
curve.keys = keyframes;
|
||
|
}
|
||
|
|
||
|
static void RemapCurve(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName)
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName, out curve))
|
||
|
{
|
||
|
clips[i].SetCurve("", typeof(Material), newPropertyName, curve);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName)
|
||
|
{
|
||
|
AnimationCurve curve;
|
||
|
for (int i = 0; i < clips.Length; i++)
|
||
|
{
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve))
|
||
|
{
|
||
|
clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve))
|
||
|
{
|
||
|
clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve);
|
||
|
}
|
||
|
|
||
|
if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve))
|
||
|
{
|
||
|
clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|