shader修改

This commit is contained in:
tianmo committed 2026-10-12 11:13:18 +08:00
1 parent 5bf02177df
commit ae5c4212dc
16 files changed
+725 -25

No files matched your search

+102
View File
@@ -99,3 +99,105 @@ public class UIMaskChannel : UIMaskEnumDrawer
// 下拉框的值本身就是要采样的通道号,无需同步到别的属性
}
}
// 通用模块:粒子自定义数据通道下拉框(shader 里写 [CustomDataChannel])
// 选项 9 项:null / Custom1.xyzw / Custom2.xyzw;值 0=null,1~4=Custom1,5~8=Custom2
// 右侧会提示该通道是否已被同一材质上的其它参数占用
//(约定:属性名里含 "CustomChannel" 的都会被统计,以后新增参数只要按这个命名即可自动纳入)
// shader 侧配套函数:CustomDataChannelValue(custom1, custom2, channel) → 取对应通道的值
public class CustomDataChannel : MaterialPropertyDrawer
{
private static readonly string[] Items =
{
"null",
"Custom1.x", "Custom1.y", "Custom1.z", "Custom1.w",
"Custom2.x", "Custom2.y", "Custom2.z", "Custom2.w"
};
private const float HintWidth = 150f;
public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor)
{
Rect popupRect = new Rect(position.x, position.y, Mathf.Max(60f, position.width - HintWidth - 4f), position.height);
Rect hintRect = new Rect(position.xMax - HintWidth, position.y, HintWidth, position.height);
int index = Mathf.Clamp(Mathf.RoundToInt(prop.floatValue), 0, Items.Length - 1);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
index = EditorGUI.Popup(popupRect, label, index, Items);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
prop.floatValue = index;
}
bool occupied;
string hint = DescribeOccupation(editor, prop, index, out occupied);
var hintContent = new GUIContent(hint, "数据来自粒子系统的「自定义数据」模块;"
+ "还需要在粒子渲染器的「自定义顶点流」里按 UV、Custom1.xyzw、Custom2.xyzw 的顺序勾选对应通道。");
Color oldColor = GUI.color;
if (index == 0)
{
GUI.color = new Color(0.7f, 0.7f, 0.7f);
}
else
{
GUI.color = occupied ? new Color(1f, 0.72f, 0.25f) : new Color(0.55f, 0.85f, 0.55f);
}
EditorGUI.LabelField(hintRect, hintContent, EditorStyles.miniLabel);
GUI.color = oldColor;
}
private static string DescribeOccupation(MaterialEditor editor, MaterialProperty prop, int index, out bool occupied)
{
occupied = false;
if (index == 0)
{
return "未使用";
}
var material = editor.targets.Length > 0 ? editor.targets[0] as Material : null;
if (material == null)
{
return string.Empty;
}
Shader shader = material.shader;
int count = ShaderUtil.GetPropertyCount(shader);
var owners = new System.Collections.Generic.List<string>();
for (int i = 0; i < count; i++)
{
string name = ShaderUtil.GetPropertyName(shader, i);
if (name == prop.name || !name.Contains("CustomChannel"))
{
continue;
}
if (!material.HasProperty(name) || Mathf.RoundToInt(material.GetFloat(name)) != index)
{
continue;
}
string description = ShaderUtil.GetPropertyDescription(shader, i);
owners.Add(string.IsNullOrEmpty(description) ? name : description);
}
if (owners.Count == 0)
{
return "未占用";
}
occupied = true;
return owners.Count == 1
? "已被 " + owners[0] + " 占用"
: "已被 " + owners[0] + " 等 " + owners.Count + " 处占用";
}
}