Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 51 additions & 18 deletions Editor/MMDEngineEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,44 @@ private bool OnInspectorGUIforOutlineWidth()
{
MMDEngine self = (MMDEngine)target;
bool is_update = false;

#if !MFU_DISABLE_LEGACY_DATA_SUPPORT
if (0 == self.material_outline_widths.Length) {
//material_outline_widthsが設定されていないなら(昔の変換データ)
Material[] materials = GetMaterials(self);
if (0 < materials.Length) {
//マテリアルが有り、今のエッジ幅が0.0fで無いなら
//データ生成を試みる
self.material_outline_widths = materials.Select(x=>x.GetFloat("_OutlineWidth")).ToArray();
}
}
#endif

float outline_width = self.outline_width;
outline_width = EditorGUILayout.Slider("Outline Width", outline_width, 0.0f, 2.0f);
if (self.outline_width != outline_width) {
//変更が掛かったなら
Material[] materials = GetMaterials(self);
//Undo登録
var record_objects = materials.Select(x=>(UnityEngine.Object)x) //マテリアル全てと
.Concat(new UnityEngine.Object[]{self}) //UnityEngine
.ToArray();
#if !UNITY_4_2 //4.3以降
Undo.RecordObject(self, "Outline Width Change");
Undo.RecordObjects(record_objects, "Outline Width Change");
#else
Undo.RegisterUndo(self, "Outline Width Change");
Undo.RegisterUndo(record_objects, "Outline Width Change");
#endif
//更新
const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
self.outline_width = outline_width;
foreach (var i in Enumerable.Range(0, materials.Length)
.Select(x=>new {material = materials[x], edge_size = self.material_outline_widths[x]})) {
i.material.SetFloat("_OutlineWidth", i.edge_size * outline_width * self.scale / c_default_scale);
}

is_update = true;
}

return is_update;
}

Expand Down Expand Up @@ -141,7 +163,7 @@ private bool OnInspectorGUIforIkList()
}
return is_update;
}

/// <summary>
/// シェーダーリストの為のInspector描画
/// </summary>
Expand All @@ -156,21 +178,7 @@ private bool OnInspectorGUIforShaderList()
//シェーダーリスト内部
if (shader_display_) {
//シェーダーリストを表示するなら
SkinnedMeshRenderer[] renderers = self.GetComponentsInChildren<SkinnedMeshRenderer>();
Material[] materials = renderers.SelectMany(x=>x.sharedMaterials).Distinct().ToArray();
if (1 < renderers.Length) {
//rendererが複数有る(≒PMX)なら
//PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート
//PMDではrendererが1つしか無く、かつソート済みの為不要
System.Array.Sort(materials, (x,y)=>{
string x_name = x.name.Substring(0, x.name.IndexOf('_'));
string y_name = y.name.Substring(0, y.name.IndexOf('_'));
int x_int, y_int;
Int32.TryParse(x_name, out x_int);
Int32.TryParse(y_name, out y_int);
return x_int - y_int;
});
}
Material[] materials = GetMaterials(self);
GUIStyle style = new GUIStyle();
style.margin.left = 10;
EditorGUILayout.BeginVertical(style);
Expand Down Expand Up @@ -411,6 +419,31 @@ static Shader CreateShaderFromShaderFlag(ShaderFlag flag) {
return result;
}

/// <summary>
/// 本来の順序で材質一覧の取得
/// </summary>
/// <returns>材質一覧</returns>
/// <param name='engine'>材質を取得するMMDEngine</param>
static Material[] GetMaterials(MMDEngine engine)
{
SkinnedMeshRenderer[] renderers = engine.GetComponentsInChildren<SkinnedMeshRenderer>();
Material[] result = renderers.SelectMany(x=>x.sharedMaterials).Distinct().ToArray();
if (1 < renderers.Length) {
//rendererが複数有る(≒PMX)なら
//PMXでは名前の先頭にはマテリアルインデックスが有るのでそれを参考にソート
//PMDではrendererが1つしか無く、かつソート済みの為不要
System.Array.Sort(result, (x,y)=>{
string x_name = x.name.Substring(0, x.name.IndexOf('_'));
string y_name = y.name.Substring(0, y.name.IndexOf('_'));
int x_int, y_int;
Int32.TryParse(x_name, out x_int);
Int32.TryParse(y_name, out y_int);
return x_int - y_int;
});
}
return result;
}

[Flags]
private enum ShaderFlag {
MmdShader = 1<< 0, //MMDシェーダー
Expand Down
15 changes: 11 additions & 4 deletions Editor/MMDLoader/Private/MMDConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ private GameObject CreateGameObject_(PMDFormat format, ShaderType shader_type, b
BuildingBindpose(mesh, materials, bones);

MMDEngine engine = root_game_object_.AddComponent<MMDEngine>();
//スケール・エッジ幅
engine.scale = scale_;
engine.outline_width = default_outline_width;
engine.material_outline_widths = Enumerable.Repeat(1.0f, materials.Length).ToArray();

// IKの登録
if (use_ik_)
Expand Down Expand Up @@ -326,10 +329,11 @@ void EntryColors(Material[] mats)
mats[i].SetFloat("_Opacity", pmdMat.alpha);
mats[i].SetColor("_SpecularColor", pmdMat.specular_color);
mats[i].SetFloat("_Shininess", pmdMat.specularity);
// エッジ
const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
mats[i].SetFloat("_OutlineWidth", default_outline_width * scale_ / c_default_scale);
mats[i].SetColor("_OutlineColor", default_outline_color);

// エッジ
mats[i].SetFloat("_OutlineWidth", 0.2f); // これぐらいがいい気がする

// ここでスフィアマップ
string path = format_.folder + "/" + pmdMat.sphere_map_name;
Texture sphere_map;
Expand Down Expand Up @@ -1003,7 +1007,10 @@ private static string GetFilePathString(string src) {
.Replace("\n", string.Empty)
.Replace("\r", string.Empty);
}


static float default_outline_width = 0.2f; //標準エッジ幅
static Color default_outline_color = Color.black; //標準エッジ色

GameObject root_game_object_;
PMDFormat format_;
ShaderType shader_type_;
Expand Down
8 changes: 6 additions & 2 deletions Editor/MMDLoader/Private/PMXConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ private GameObject CreateGameObject_(PMXFormat format, bool use_rigidbody, bool
scale_ = scale;
root_game_object_ = new GameObject(format_.meta_header.name);
MMDEngine engine = root_game_object_.AddComponent<MMDEngine>(); //MMDEngine追加
//スケール・エッジ幅
engine.scale = scale_;

engine.outline_width = 1.0f;
engine.material_outline_widths = format.material_list.material.Select(x=>x.edge_size).ToArray();

MeshCreationInfo[] creation_info = CreateMeshCreationInfo(); // メッシュを作成する為の情報を作成
Mesh[] mesh = CreateMesh(creation_info); // メッシュの生成・設定
Material[][] materials = CreateMaterials(creation_info); // マテリアルの生成・設定
Expand Down Expand Up @@ -470,7 +473,8 @@ Material ConvertMaterial(PMXFormat.Material material)
result.SetColor("_SpecularColor", material.specular_color);
result.SetFloat("_Shininess", material.specularity);
// エッジ
result.SetFloat("_OutlineWidth", material.edge_size);
const float c_default_scale = 0.085f; //0.085fの時にMMDと一致する様にしているので、それ以外なら補正
result.SetFloat("_OutlineWidth", material.edge_size * scale_ / c_default_scale);
result.SetColor("_OutlineColor", material.edge_color);

// スフィアテクスチャ
Expand Down
13 changes: 5 additions & 8 deletions Resources/MMDEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
public class MMDEngine : MonoBehaviour {

public float scale = 1.0f; //読み込みスケール
public float outline_width = 0.1f;
public bool useRigidbody = false;
public int[] groupTarget; // 非衝突剛体リスト
public GameObject[] rigids; // 剛体リスト
public GameObject[] joints; // ConfigurableJointの入っているボーンのリスト

#if UNITY_EDITOR
public float outline_width; //エッジ幅係数(エディタ用)
public float[] material_outline_widths; //材質のエッジ幅(エディタ用)
#endif

// 訳があってこうなってる
public int[] ignore1;
public int[] ignore2;
Expand Down Expand Up @@ -39,12 +42,6 @@ public class MMDEngine : MonoBehaviour {
// Use this for initialization
void Start ()
{
SkinnedMeshRenderer[] renderers = GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (var m in renderers.SelectMany(x=>x.sharedMaterials))
{
m.SetFloat("_OutlineWidth", this.outline_width);
}

if (useRigidbody)
{
ignoreList = new List<int[]>();
Expand Down
11 changes: 6 additions & 5 deletions Resources/PMDMaterial/Shaders/MeshPmdMaterialVertFrag.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ struct v2f
v2f vert( appdata_base v )
{
v2f o;
float4 pos = mul( UNITY_MATRIX_MVP, v.vertex );
float width = 0.01 * _OutlineWidth;
float4 edge_pos = v.vertex + pos.w * width * float4( v.normal, 0.0 );
o.pos = mul( UNITY_MATRIX_MVP, edge_pos );
float4 pos = mul(UNITY_MATRIX_MVP, v.vertex);
float4 normal = mul(UNITY_MATRIX_MVP, float4(v.normal, 0.0));
float width = _OutlineWidth / 1024.0; //目コピ調整値(算術根拠無し)
float depth_offset = pos.z / 4194304.0; //僅かに奥に移動(floatの仮数部は23bitなので(1<<21)程度で割った値は丸めに入らないが非常に小さな値の筈)
o.pos = pos + normal * float4(width, width, 0.0, 0.0) + float4(0.0, 0.0, depth_offset, 0.0);

return o;
}
half4 frag( v2f i ) : COLOR
{
return half4( _OutlineColor.rgb, _Opacity );
return half4( _OutlineColor.rgb, _OutlineColor.a * _Opacity );
}