239 lines
8.0 KiB
C#
239 lines
8.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UniGLTF;
|
|
using UniGLTF.ShaderPropExporter;
|
|
using UnityEngine;
|
|
using VRMShaders;
|
|
using ColorSpace = VRMShaders.ColorSpace;
|
|
|
|
namespace VRM
|
|
{
|
|
public class VRMMaterialExporter : MaterialExporter
|
|
{
|
|
public static string VrmMaterialName(string shaderName)
|
|
{
|
|
switch (shaderName)
|
|
{
|
|
case "VRM/UnlitTexture":
|
|
case "VRM/UnlitTransparent":
|
|
case "VRM/UnlitCutout":
|
|
case "VRM/UnlitTransparentZWrite":
|
|
return "KHR_materials_unlit";
|
|
|
|
case "VRM/MToon":
|
|
return "MToon";
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected override glTFMaterial CreateMaterial(Material m)
|
|
{
|
|
switch (m.shader.name)
|
|
{
|
|
case "VRM/UnlitTexture":
|
|
return Export_VRMUnlitTexture(m);
|
|
|
|
case "VRM/UnlitTransparent":
|
|
return Export_VRMUnlitTransparent(m);
|
|
|
|
case "VRM/UnlitCutout":
|
|
return Export_VRMUnlitCutout(m);
|
|
|
|
case "VRM/UnlitTransparentZWrite":
|
|
return Export_VRMUnlitTransparentZWrite(m);
|
|
|
|
case "VRM/MToon":
|
|
return Export_VRMMToon(m);
|
|
|
|
default:
|
|
return base.CreateMaterial(m);
|
|
}
|
|
}
|
|
|
|
static glTFMaterial Export_VRMUnlitTexture(Material m)
|
|
{
|
|
var material = glTF_KHR_materials_unlit.CreateDefault();
|
|
material.alphaMode = "OPAQUE";
|
|
return material;
|
|
}
|
|
static glTFMaterial Export_VRMUnlitTransparent(Material m)
|
|
{
|
|
var material = glTF_KHR_materials_unlit.CreateDefault();
|
|
material.alphaMode = "BLEND";
|
|
return material;
|
|
}
|
|
static glTFMaterial Export_VRMUnlitCutout(Material m)
|
|
{
|
|
var material = glTF_KHR_materials_unlit.CreateDefault();
|
|
material.alphaMode = "MASK";
|
|
return material;
|
|
}
|
|
static glTFMaterial Export_VRMUnlitTransparentZWrite(Material m)
|
|
{
|
|
var material = glTF_KHR_materials_unlit.CreateDefault();
|
|
material.alphaMode = "BLEND";
|
|
return material;
|
|
}
|
|
|
|
static glTFMaterial Export_VRMMToon(Material m)
|
|
{
|
|
var material = glTF_KHR_materials_unlit.CreateDefault();
|
|
|
|
switch (m.GetTag("RenderType", true))
|
|
{
|
|
case "Transparent":
|
|
material.alphaMode = "BLEND";
|
|
break;
|
|
|
|
case "TransparentCutout":
|
|
material.alphaMode = "MASK";
|
|
material.alphaCutoff = m.GetFloat("_Cutoff");
|
|
break;
|
|
|
|
default:
|
|
material.alphaMode = "OPAQUE";
|
|
break;
|
|
}
|
|
|
|
switch ((int)m.GetFloat("_CullMode"))
|
|
{
|
|
case 0:
|
|
material.doubleSided = true;
|
|
break;
|
|
|
|
case 1:
|
|
Debug.LogWarning("ignore cull front");
|
|
break;
|
|
|
|
case 2:
|
|
// cull back
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
return material;
|
|
}
|
|
|
|
#region CreateFromMaterial
|
|
|
|
static readonly string[] TAGS = new string[]{
|
|
"RenderType",
|
|
// "Queue",
|
|
};
|
|
|
|
public static glTF_VRM_Material CreateFromMaterial(Material m, ITextureExporter textureExporter)
|
|
{
|
|
var material = new glTF_VRM_Material
|
|
{
|
|
name = m.name,
|
|
shader = m.shader.name,
|
|
renderQueue = m.renderQueue,
|
|
};
|
|
|
|
if (!PreShaderPropExporter.VRMExtensionShaders.Contains(m.shader.name))
|
|
{
|
|
material.shader = glTF_VRM_Material.VRM_USE_GLTFSHADER;
|
|
return material;
|
|
}
|
|
|
|
var prop = PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name);
|
|
if (prop == null)
|
|
{
|
|
Debug.LogWarningFormat("Fail to export shader: {0}", m.shader.name);
|
|
}
|
|
else
|
|
{
|
|
foreach (var keyword in m.shaderKeywords)
|
|
{
|
|
material.keywordMap.Add(keyword, m.IsKeywordEnabled(keyword));
|
|
}
|
|
|
|
// get properties
|
|
//material.SetProp(prop);
|
|
foreach (var kv in prop.Properties)
|
|
{
|
|
switch (kv.ShaderPropertyType)
|
|
{
|
|
case ShaderPropertyType.Color:
|
|
{
|
|
// No color conversion. Because color property is serialized to raw float array.
|
|
var value = m.GetColor(kv.Key).ToFloat4(ColorSpace.Linear, ColorSpace.Linear);
|
|
material.vectorProperties.Add(kv.Key, value);
|
|
}
|
|
break;
|
|
|
|
case ShaderPropertyType.Range:
|
|
case ShaderPropertyType.Float:
|
|
{
|
|
var value = m.GetFloat(kv.Key);
|
|
material.floatProperties.Add(kv.Key, value);
|
|
}
|
|
break;
|
|
|
|
case ShaderPropertyType.TexEnv:
|
|
{
|
|
var texture = m.GetTexture(kv.Key);
|
|
if (texture != null)
|
|
{
|
|
var value = -1;
|
|
var isNormalMap = kv.Key == "_BumpMap";
|
|
if (isNormalMap)
|
|
{
|
|
value = textureExporter.RegisterExportingAsNormal(texture);
|
|
}
|
|
else
|
|
{
|
|
var needsAlpha = kv.Key == "_MainTex";
|
|
value = textureExporter.RegisterExportingAsSRgb(texture, needsAlpha);
|
|
}
|
|
if (value == -1)
|
|
{
|
|
Debug.LogFormat("not found {0}", texture.name);
|
|
}
|
|
else
|
|
{
|
|
material.textureProperties.Add(kv.Key, value);
|
|
}
|
|
}
|
|
|
|
// offset & scaling
|
|
var offset = m.GetTextureOffset(kv.Key);
|
|
var scaling = m.GetTextureScale(kv.Key);
|
|
material.vectorProperties.Add(kv.Key,
|
|
new float[] { offset.x, offset.y, scaling.x, scaling.y });
|
|
}
|
|
break;
|
|
|
|
case ShaderPropertyType.Vector:
|
|
{
|
|
var value = m.GetVector(kv.Key).ToArray();
|
|
material.vectorProperties.Add(kv.Key, value);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var tag in TAGS)
|
|
{
|
|
var value = m.GetTag(tag, false);
|
|
if (!String.IsNullOrEmpty(value))
|
|
{
|
|
material.tagMap.Add(tag, value);
|
|
}
|
|
}
|
|
|
|
return material;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|