Files
Fishing2/Packages/com.jbooth.microsplat.mesh-workflow/ObjectShader/Scripts/Editor/MicroSplatShaderObjectGUI.cs
2025-06-04 09:09:39 +08:00

232 lines
10 KiB
C#

//////////////////////////////////////////////////////
// MicroSplat
// Copyright (c) Jason Booth
//////////////////////////////////////////////////////
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using JBooth.MicroSplat;
#if __MICROSPLAT__
public class MicroSplatShaderObjectGUI : ShaderGUI
{
MicroSplatShaderGUI.MicroSplatCompiler compiler = new MicroSplatShaderGUI.MicroSplatCompiler ();
static GUIContent CAlphaMode = new GUIContent ("Mode", "Rendering Mode");
static GUIContent CStandardDiffuse = new GUIContent ("Albedo", "Albedo texture");
static GUIContent CStandardNormal = new GUIContent ("Normal", "Normal Map");
static GUIContent CStandardNormalStrength = new GUIContent ("Normal Strength", "Strength of normal map");
static GUIContent CStandardDetailPacked = new GUIContent ("Detail Packed", "Detail with diffuse in R, normal in G/A, and smoothness in B");
static GUIContent CStandardEmission = new GUIContent ("Emission", "Emissive texture");
static GUIContent CStandardSpecular = new GUIContent ("Specular", "Specular Texture");
static GUIContent CStandardPackedMap = new GUIContent ("Mask Map", "(R) Metallic, (G) Occlusion, (B) Detail Mask (A) Smoothness");
static GUIContent CStandardDetailUVScale = new GUIContent ("Detail UV Scale/Offset", "Scale and offset for UVs on the detail textures");
static GUIContent CStandardMetallic = new GUIContent ("Metallic", "Metallic value");
static GUIContent CStandardSmoothness = new GUIContent ("Smoothness", "Smoothness value");
static GUIContent CStandardDetailAlbedoStrength = new GUIContent ("Detail Albedo Strength", "Strength of detail albedo");
static GUIContent CStandardDetailSmoothnessStrength = new GUIContent ("Detail Smoothness Strength", "Strength of detail smoothness");
static GUIContent CStandardDetailNormalScale = new GUIContent ("Detail Normal Strength", "Strength of detail normal");
static GUIContent CAlphaThreshold = new GUIContent ("Cutout Threshold", "Alpha values below this level get clipped");
public enum AlphaMode
{
Opaque,
Cutout,
}
bool oldEnabled = false;
bool BeginDrawKeywordToggle(Material mat, string keyword)
{
oldEnabled = GUI.enabled;
bool on = mat.IsKeywordEnabled (keyword);
var newOn = EditorGUILayout.Toggle (on, GUILayout.Width (22));
if (newOn != on)
{
if (newOn)
mat.EnableKeyword (keyword);
else
mat.DisableKeyword (keyword);
}
GUI.enabled = newOn;
return newOn;
}
void EndDrawKeywordToggle()
{
GUI.enabled = oldEnabled;
}
public override void OnGUI (MaterialEditor materialEditor, MaterialProperty [] props)
{
var targetMat = materialEditor.target as Material;
compiler.Init ();
var path = AssetDatabase.GetAssetPath (targetMat.shader);
path = path.Replace ("_objects.shader", ".mat");
path = path.Replace("_objects.surfshader", ".mat");
var sourceMat = AssetDatabase.LoadAssetAtPath<Material> (path);
if (sourceMat == null)
{
EditorGUILayout.HelpBox ("Source Material not found at path : " + path + "\nMost like you renamed either the material or shader in your MicroSplatData directory", MessageType.Error);
return;
}
var keywords = MicroSplatUtilities.FindOrCreateKeywords (sourceMat);
MicroSplatKeywords fakeKeywords = MicroSplatKeywords.CreateInstance<MicroSplatKeywords> ();
fakeKeywords.keywords = new List<string> (keywords.keywords);
MicroSplatObjectShaderModule.ModifyKeywords (fakeKeywords.keywords);
MicroSplatShaderGUI shaderGUI = new MicroSplatShaderGUI ();
// gui for the regular shader part
if (MicroSplatUtilities.DrawRollup ("Standard Material"))
{
using (new GUILayout.VerticalScope (GUI.skin.box))
{
AlphaMode mode = AlphaMode.Opaque;
if (targetMat.IsKeywordEnabled ("_OBJECTSHADERALPHACLIP"))
mode = AlphaMode.Cutout;
var newMode = (AlphaMode)EditorGUILayout.EnumPopup (CAlphaMode, mode);
if (newMode != mode)
{
if (newMode == AlphaMode.Cutout)
{
targetMat.EnableKeyword ("_OBJECTSHADERALPHACLIP");
}
else
{
targetMat.DisableKeyword ("_OBJECTSHADERALPHACLIP");
}
}
if (targetMat.HasProperty ("_ObjectShaderDiffuse"))
{
EditorGUILayout.BeginHorizontal ();
materialEditor.TexturePropertySingleLine (CStandardDiffuse, shaderGUI.FindProp ("_ObjectShaderDiffuse", props));
var colorProp = shaderGUI.FindProp ("_ObjectShaderDiffuseTint", props);
var c = colorProp.colorValue;
var nc = EditorGUILayout.ColorField (c, GUILayout.Width (60));
if (c != nc)
{
colorProp.colorValue = nc;
}
EditorGUILayout.EndHorizontal ();
if (newMode == AlphaMode.Cutout)
{
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderAlphaClipThreshold", props), CAlphaThreshold.text);
}
materialEditor.TexturePropertySingleLine (CStandardNormal, shaderGUI.FindProp ("_ObjectShaderNormal", props));
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderNormalScale", props), CStandardNormalStrength.text);
EditorGUILayout.BeginHorizontal ();
bool enabled = BeginDrawKeywordToggle (targetMat, "_OBJECTSHADERPACKEDMAP");
MicroSplatUtilities.WarnLinear (shaderGUI.FindProp ("_ObjectShaderPackedMap", props).textureValue as Texture2D);
materialEditor.TexturePropertySingleLine (CStandardPackedMap, shaderGUI.FindProp ("_ObjectShaderPackedMap", props));
EditorGUILayout.EndHorizontal ();
EndDrawKeywordToggle ();
if (!enabled)
{
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderMetallic", props), CStandardMetallic.text);
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderSmoothness", props), CStandardSmoothness.text);
}
}
EditorGUILayout.BeginHorizontal ();
BeginDrawKeywordToggle (targetMat, "_OBJECTSHADEREMISSION");
materialEditor.TexturePropertySingleLine (CStandardEmission, shaderGUI.FindProp ("_ObjectShaderEmission", props));
EditorGUILayout.EndHorizontal ();
EndDrawKeywordToggle ();
materialEditor.ShaderProperty (shaderGUI.FindProp ("_ObjectShaderUVScaleOffset", props), "UV Scale/Offset");
if (keywords.IsKeywordEnabled ("_USESPECULARWORKFLOW"))
{
EditorGUILayout.BeginHorizontal ();
BeginDrawKeywordToggle (targetMat, "_OBJECTSHADERSPECULAR");
materialEditor.TexturePropertySingleLine (CStandardSpecular, shaderGUI.FindProp ("_ObjectShaderSpecular", props));
EditorGUILayout.EndHorizontal ();
EndDrawKeywordToggle ();
}
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
EditorGUILayout.BeginHorizontal ();
BeginDrawKeywordToggle (targetMat, "_OBJECTSHADERDETAILPACKED");
MicroSplatUtilities.WarnLinear (shaderGUI.FindProp ("_ObjectShaderDetailNormal", props).textureValue as Texture2D);
materialEditor.TexturePropertySingleLine (CStandardDetailPacked, shaderGUI.FindProp ("_ObjectShaderDetailNormal", props));
EditorGUILayout.EndHorizontal ();
materialEditor.ShaderProperty (shaderGUI.FindProp ("_ObjectShaderDetailUVScaleOffset", props), CStandardDetailUVScale);
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderDetailAlbedoStrength", props), CStandardDetailAlbedoStrength.text);
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderDetailNormalScale", props), CStandardDetailNormalScale.text);
materialEditor.RangeProperty (shaderGUI.FindProp ("_ObjectShaderDetailSmoothnessStrength", props), CStandardDetailSmoothnessStrength.text);
EndDrawKeywordToggle ();
}
}
if (GUILayout.Button ("Sync from Source Mat") && sourceMat.shader != null)
{
// because the build in copy properties is not addative, but wipes existing data..
int count = ShaderUtil.GetPropertyCount (sourceMat.shader);
for (int i = 0; i < count; ++i)
{
var t = ShaderUtil.GetPropertyType (sourceMat.shader, i);
var name = ShaderUtil.GetPropertyName (sourceMat.shader, i);
switch (t)
{
case ShaderUtil.ShaderPropertyType.Range:
case ShaderUtil.ShaderPropertyType.Float:
if (targetMat.HasProperty (name)) { targetMat.SetFloat (name, sourceMat.GetFloat (name)); }
break;
case ShaderUtil.ShaderPropertyType.Color:
if (targetMat.HasProperty (name)) { targetMat.SetColor (name, sourceMat.GetColor (name)); }
break;
case ShaderUtil.ShaderPropertyType.Vector:
if (targetMat.HasProperty (name)) { targetMat.SetVector (name, sourceMat.GetVector (name)); }
break;
case ShaderUtil.ShaderPropertyType.TexEnv:
if (targetMat.HasProperty (name)) { targetMat.SetTexture (name, sourceMat.GetTexture (name)); }
break;
}
}
}
// gui for the rest..
foreach (var e in compiler.extensions)
{
e.Unpack (fakeKeywords.keywords.ToArray());
}
using (new GUILayout.VerticalScope (MicroSplatUtilities.boxStyle))
{
foreach (var e in compiler.extensions)
{
e.DrawShaderGUI (shaderGUI, fakeKeywords, targetMat, materialEditor, props);
}
}
Object.DestroyImmediate (fakeKeywords);
}
}
#endif