Modify: 닐로툰 스크립트 최신버전으로 업데이트
This commit is contained in:
parent
0405f6ccf0
commit
85a03a3cbe
@ -96,16 +96,12 @@ namespace MagicaCloth2
|
|||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
[MenuItem("Tools/Magica Cloth2/Manager information", false)]
|
[MenuItem("Tools/Magica Cloth2/Manager information", false)]
|
||||||
static void DispClothManagerInfo()
|
static async void DispClothManagerInfo()
|
||||||
{
|
{
|
||||||
if (MagicaManager.IsPlaying() == false)
|
|
||||||
{
|
|
||||||
Debug.Log("This feature is run-time only.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder allsb = new StringBuilder();
|
StringBuilder allsb = new StringBuilder();
|
||||||
|
|
||||||
|
await ClothEditorManager.InformationLog(allsb);
|
||||||
|
|
||||||
var timeManager = MagicaManager.Time;
|
var timeManager = MagicaManager.Time;
|
||||||
if (timeManager == null)
|
if (timeManager == null)
|
||||||
{
|
{
|
||||||
@ -186,8 +182,15 @@ namespace MagicaCloth2
|
|||||||
renderManager.InformationLog(allsb);
|
renderManager.InformationLog(allsb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clipboard
|
var preBuildManager = MagicaManager.PreBuild;
|
||||||
//GUIUtility.systemCopyBuffer = allsb.ToString();
|
if (preBuildManager == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("PreBuild Manager is null!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preBuildManager.InformationLog(allsb);
|
||||||
|
}
|
||||||
|
|
||||||
// file
|
// file
|
||||||
DateTime dt = DateTime.Now;
|
DateTime dt = DateTime.Now;
|
||||||
@ -197,5 +200,24 @@ namespace MagicaCloth2
|
|||||||
sw.Flush();
|
sw.Flush();
|
||||||
sw.Close();
|
sw.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================================================
|
||||||
|
// インスペクターのコンテキストメニュー
|
||||||
|
[MenuItem("CONTEXT/MagicaCloth/Rebuild InitData")]
|
||||||
|
private static void SampleMenu(MenuCommand menuCommand)
|
||||||
|
{
|
||||||
|
// 初期化データをクリアして再構築する
|
||||||
|
var cloth = menuCommand.context as MagicaCloth;
|
||||||
|
if (cloth)
|
||||||
|
{
|
||||||
|
cloth.GetSerializeData2().initData.Clear();
|
||||||
|
EditorUtility.SetDirty(cloth);
|
||||||
|
|
||||||
|
// 編集用メッシュの再構築
|
||||||
|
ClothEditorManager.RegisterComponent(cloth, GizmoType.Active, true); // 強制更新
|
||||||
|
|
||||||
|
Develop.Log($"[{cloth.name}] Initialization data rebuilt.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// Magica Cloth 2.
|
// Magica Cloth 2.
|
||||||
// Copyright (c) 2023 MagicaSoft.
|
// Copyright (c) 2023 MagicaSoft.
|
||||||
// https://magicasoft.jp
|
// https://magicasoft.jp
|
||||||
|
using Unity.Mathematics;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ namespace MagicaCloth2
|
|||||||
{
|
{
|
||||||
// ギズモカラー定義
|
// ギズモカラー定義
|
||||||
public static readonly Color ColorCollider = new Color(0.0f, 1.0f, 0.0f);
|
public static readonly Color ColorCollider = new Color(0.0f, 1.0f, 0.0f);
|
||||||
|
public static readonly Color ColorSymmetryCollider = new Color(0.0f, 1.0f, 1.0f);
|
||||||
public static readonly Color ColorNonSelectedCollider = new Color(0.5f, 0.3f, 0.0f);
|
public static readonly Color ColorNonSelectedCollider = new Color(0.5f, 0.3f, 0.0f);
|
||||||
public static readonly Color ColorSkinningBone = new Color(1.0f, 0.5f, 0.0f);
|
public static readonly Color ColorSkinningBone = new Color(1.0f, 0.5f, 0.0f);
|
||||||
public static readonly Color ColorWindZone = new Color(1f, 1f, 1f);
|
public static readonly Color ColorWindZone = new Color(1f, 1f, 1f);
|
||||||
@ -162,56 +164,142 @@ namespace MagicaCloth2
|
|||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
public static void DrawCollider(ColliderComponent collider, Quaternion camRot, bool useHandles, bool selected)
|
public static void DrawCollider(ColliderComponent collider, Quaternion camRot, bool selected)
|
||||||
{
|
{
|
||||||
if (collider == null)
|
if (collider == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var cpos = collider.transform.TransformPoint(collider.center);
|
Handles.color = selected ? ColorCollider : ColorCollider * 0.5f;
|
||||||
var crot = collider.transform.rotation;
|
|
||||||
var cscl = Vector3.one * collider.GetScale(); // スケールはx軸のみ(つまり均等スケールのみ)
|
|
||||||
|
|
||||||
|
// Main
|
||||||
|
var ct = collider.transform;
|
||||||
|
//var cpos = ct.TransformPoint(collider.center);
|
||||||
|
float3 cpos = ct.position;
|
||||||
|
quaternion crot = ct.rotation;
|
||||||
|
float3 cscl = ct.lossyScale;
|
||||||
|
// マイナススケール
|
||||||
|
float3 sclSign = math.sign(cscl);
|
||||||
|
// オフセット
|
||||||
|
cpos += math.mul(crot, collider.center * sclSign) * cscl * sclSign;
|
||||||
// カメラ回転をコライダーのローカル回転に変換
|
// カメラ回転をコライダーのローカル回転に変換
|
||||||
camRot = Quaternion.Inverse(crot) * camRot;
|
var camRotN = Quaternion.Inverse(crot) * camRot;
|
||||||
|
DrawColliderInternal(collider, camRotN, cpos, crot, cscl, 1.0f);
|
||||||
|
|
||||||
// サイズ
|
// Symmetry
|
||||||
var size = collider.GetSize();
|
// 実行時と同じ計算をして表示
|
||||||
|
ColliderSymmetryMode? smode = ColliderSymmetryMode.None;
|
||||||
if (useHandles)
|
Transform symmetryParent = null;
|
||||||
|
if (EditorApplication.isPlaying)
|
||||||
{
|
{
|
||||||
Handles.matrix = Matrix4x4.TRS(cpos, crot, cscl);
|
smode = collider.ActiveSymmetryMode;
|
||||||
Handles.color = selected ? ColorCollider : ColorCollider * 0.5f;
|
symmetryParent = collider.ActiveSymmetryTarget;
|
||||||
switch (collider.GetColliderType())
|
|
||||||
{
|
|
||||||
case ColliderManager.ColliderType.Sphere:
|
|
||||||
DrawWireSphere(Vector3.zero, Quaternion.identity, size.x, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleX_Center:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.right, Vector3.up, size.x, size.y, size.z, true, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleY_Center:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.up, Vector3.right, size.x, size.y, size.z, true, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleZ_Center:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.forward, Vector3.up, size.x, size.y, size.z, true, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleX_Start:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.right, Vector3.up, size.x, size.y, size.z, false, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleY_Start:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.up, Vector3.right, size.x, size.y, size.z, false, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.CapsuleZ_Start:
|
|
||||||
DrawWireCapsule(Vector3.zero, Quaternion.identity, Vector3.forward, Vector3.up, size.x, size.y, size.z, false, camRot, true);
|
|
||||||
break;
|
|
||||||
case ColliderManager.ColliderType.Plane:
|
|
||||||
DrawWireCube(Vector3.zero, Quaternion.identity, new Vector3(1.0f, 0.0f, 1.0f) * 1.0f, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
if (smode.HasValue == false || smode == ColliderSymmetryMode.None)
|
||||||
|
smode = collider.CalcSymmetryMode(out symmetryParent);
|
||||||
|
if (smode != ColliderSymmetryMode.None && symmetryParent)
|
||||||
{
|
{
|
||||||
|
float3 lpos = ct.localPosition;
|
||||||
|
//float3 lerot = ct.localEulerAngles;
|
||||||
|
float3 lerot = MathUtility.ToEuler(ct.localRotation);
|
||||||
|
float3 lscl = ct.localScale;
|
||||||
|
float3 center = collider.center;
|
||||||
|
switch (smode)
|
||||||
|
{
|
||||||
|
case ColliderSymmetryMode.X_Symmetry:
|
||||||
|
lpos.x = -lpos.x;
|
||||||
|
center.x = -center.x;
|
||||||
|
lerot.y = -lerot.y;
|
||||||
|
lerot.z = -lerot.z;
|
||||||
|
break;
|
||||||
|
case ColliderSymmetryMode.Y_Symmetry:
|
||||||
|
lpos.y = -lpos.y;
|
||||||
|
center.y = -center.y;
|
||||||
|
lerot.x = -lerot.x;
|
||||||
|
lerot.z = -lerot.z;
|
||||||
|
break;
|
||||||
|
case ColliderSymmetryMode.Z_Symmetry:
|
||||||
|
lpos.z = -lpos.z;
|
||||||
|
center.z = -center.z;
|
||||||
|
lerot.x = -lerot.x;
|
||||||
|
lerot.y = -lerot.y;
|
||||||
|
break;
|
||||||
|
case ColliderSymmetryMode.XYZ_Symmetry:
|
||||||
|
lpos = -lpos;
|
||||||
|
center = -center;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方向性
|
||||||
|
float direction = 1.0f;
|
||||||
|
if (collider is MagicaCapsuleCollider)
|
||||||
|
{
|
||||||
|
var ccol = collider as MagicaCapsuleCollider;
|
||||||
|
if (smode == ColliderSymmetryMode.X_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.X)
|
||||||
|
direction = -1.0f;
|
||||||
|
else if (smode == ColliderSymmetryMode.Y_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Y)
|
||||||
|
direction = -1.0f;
|
||||||
|
else if (smode == ColliderSymmetryMode.Z_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Z)
|
||||||
|
direction = -1.0f;
|
||||||
|
else if (smode == ColliderSymmetryMode.XYZ_Symmetry)
|
||||||
|
direction = -1.0f;
|
||||||
|
}
|
||||||
|
else if (collider is MagicaPlaneCollider)
|
||||||
|
{
|
||||||
|
switch (smode)
|
||||||
|
{
|
||||||
|
case ColliderSymmetryMode.Y_Symmetry:
|
||||||
|
case ColliderSymmetryMode.XYZ_Symmetry:
|
||||||
|
direction = -1.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// シンメトリーの親
|
||||||
|
float3 ppos = symmetryParent.position;
|
||||||
|
quaternion prot = symmetryParent.rotation;
|
||||||
|
float3 pscl = symmetryParent.lossyScale;
|
||||||
|
|
||||||
|
// マイナススケール
|
||||||
|
sclSign = math.sign(pscl);
|
||||||
|
float3 sclEulerSign = 1;
|
||||||
|
if (pscl.x < 0 || pscl.y < 0 || pscl.z < 0)
|
||||||
|
sclEulerSign = sclSign * -1;
|
||||||
|
|
||||||
|
// シンメトリーコライダーの姿勢
|
||||||
|
float3 wpos = MathUtility.TransformPoint(lpos, ppos, prot, pscl);
|
||||||
|
quaternion wrot = math.mul(prot, quaternion.Euler(math.radians(lerot * sclEulerSign)));
|
||||||
|
float3 wscl = pscl * lscl;
|
||||||
|
wpos += math.mul(wrot, center * sclSign) * wscl * sclSign;
|
||||||
|
|
||||||
|
// カメラ回転をコライダーのローカル回転に変換
|
||||||
|
var camRotS = Quaternion.Inverse(wrot) * camRot;
|
||||||
|
|
||||||
|
Handles.color = selected ? ColorSymmetryCollider : ColorSymmetryCollider * 0.5f;
|
||||||
|
DrawColliderInternal(collider, camRotS, wpos, wrot, wscl, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawColliderInternal(ColliderComponent collider, Quaternion camRot, Vector3 cpos, Quaternion crot, Vector3 cscl, float direction)
|
||||||
|
{
|
||||||
|
var size = collider.GetSize();
|
||||||
|
Handles.matrix = Matrix4x4.TRS(cpos, crot, cscl);
|
||||||
|
if (collider is MagicaSphereCollider)
|
||||||
|
{
|
||||||
|
DrawWireSphere(Vector3.zero, Quaternion.identity, size.x, camRot, true);
|
||||||
|
}
|
||||||
|
else if (collider is MagicaPlaneCollider)
|
||||||
|
{
|
||||||
|
DrawWireCube(Vector3.zero, Quaternion.identity, new Vector3(1.0f, 0.0f, 1.0f) * 1.0f, true);
|
||||||
|
DrawLine(Vector3.zero, Vector3.up * 0.25f * direction, true);
|
||||||
|
}
|
||||||
|
else if (collider is MagicaCapsuleCollider)
|
||||||
|
{
|
||||||
|
var c = collider as MagicaCapsuleCollider;
|
||||||
|
var ldir = c.GetLocalDir() * direction;
|
||||||
|
var lup = c.GetLocalUp();
|
||||||
|
DrawWireCapsule(Vector3.zero, Quaternion.identity, ldir, lup, size.x, size.y, size.z, c.alignedOnCenter, camRot, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,23 +388,6 @@ namespace MagicaCloth2
|
|||||||
Gizmos.matrix = Matrix4x4.identity;
|
Gizmos.matrix = Matrix4x4.identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public static void DrawWireSphere(
|
|
||||||
// Vector3 pos, Quaternion rot, Vector3 scl, float radius,
|
|
||||||
// Quaternion camRot, bool useHandles
|
|
||||||
// )
|
|
||||||
//{
|
|
||||||
// if(useHandles)
|
|
||||||
// {
|
|
||||||
// Handles.matrix = Matrix4x4.TRS(pos, rot, scl);
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ワイヤーボックスを描画する
|
/// ワイヤーボックスを描画する
|
||||||
|
|||||||
BIN
Assets/External/NiloToonURP/CHANGELOG.md
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/CHANGELOG.md
(Stored with Git LFS)
vendored
Binary file not shown.
@ -10,7 +10,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
public class NiloToonEditor_AutoGeneratePrefabVariantAndAssets : Editor
|
public class NiloToonEditor_AutoGeneratePrefabVariantAndAssets : Editor
|
||||||
{
|
{
|
||||||
[MenuItem("Window/NiloToonURP/Create Nilo Prefab Variant and Materials", priority = 0)]
|
[MenuItem("Window/NiloToonURP/[Prefab] Create NiloToon Prefab Variant and Materials", priority = 0)]
|
||||||
|
[MenuItem("Assets/NiloToon/[Prefab] Create NiloToon Prefab Variant and Materials", priority = 1100 + 0)]
|
||||||
static void CreatePrefabVariantAndCloneMaterials()
|
static void CreatePrefabVariantAndCloneMaterials()
|
||||||
{
|
{
|
||||||
// Get the selected prefab
|
// Get the selected prefab
|
||||||
@ -186,7 +187,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
EditorUtility.DisplayDialog("Success", "Prefab variant created with cloned materials.", "OK");
|
EditorUtility.DisplayDialog("Success", "Prefab variant created with cloned materials.", "OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Window/NiloToonURP/Create Nilo Prefab Variant and Materials", priority = 0, validate = true)]
|
[MenuItem("Window/NiloToonURP/[Prefab] Create NiloToon Prefab Variant and Materials", priority = 0, validate = true)]
|
||||||
|
[MenuItem("Assets/NiloToon/[Prefab] Create NiloToon Prefab Variant and Materials", priority = 1100 + 0, validate = true)]
|
||||||
public static bool ValidateCreatePrefabVariantAndCloneMaterials()
|
public static bool ValidateCreatePrefabVariantAndCloneMaterials()
|
||||||
{
|
{
|
||||||
var allselectedObjects = Selection.objects;
|
var allselectedObjects = Selection.objects;
|
||||||
|
|||||||
@ -307,45 +307,41 @@ namespace NiloToon.NiloToonURP
|
|||||||
matOriginal.shader.name.Contains("Overlay");
|
matOriginal.shader.name.Contains("Overlay");
|
||||||
bool isOutl = matOriginal.shader.name.Contains("Outline");
|
bool isOutl = matOriginal.shader.name.Contains("Outline");
|
||||||
bool isTransparentQueue = matOriginal.renderQueue > 2500;
|
bool isTransparentQueue = matOriginal.renderQueue > 2500;
|
||||||
|
bool isZWrite = matOriginal.GetFloat("_ZWrite") > 0.5f;
|
||||||
|
|
||||||
if (!isCutout && !isTransparent && !isOutl && !isTransparentQueue)
|
// if ZWrite is off, we treat the material as transparent
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Opaque;
|
if (!isCutout && !isTransparent && !isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Opaque; // 1
|
||||||
else if (!isCutout && !isTransparent && !isOutl && isTransparentQueue)
|
else if (!isCutout && !isTransparent && !isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 2
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
else if (!isCutout && !isTransparent && !isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.TransparentQueueTransparent_ZWrite; // 3
|
||||||
NiloToonSurfaceTypePreset.TransparentQueueTransparent_ZWrite;
|
else if (!isCutout && !isTransparent && !isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 4
|
||||||
else if (!isCutout && !isTransparent && isOutl && !isTransparentQueue)
|
else if (!isCutout && !isTransparent && isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Opaque_Outline; // 5
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Opaque_Outline;
|
else if (!isCutout && !isTransparent && isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 6
|
||||||
else if (!isCutout && !isTransparent && isOutl && isTransparentQueue)
|
else if (!isCutout && !isTransparent && isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite_Outline; // 7
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite_Outline;
|
else if (!isCutout && !isTransparent && isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 8
|
||||||
else if (!isCutout && isTransparent && !isOutl && !isTransparentQueue)
|
else if (!isCutout && isTransparent && !isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite; // 9
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite;
|
else if (!isCutout && isTransparent && !isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 10
|
||||||
else if (!isCutout && isTransparent && !isOutl && isTransparentQueue)
|
else if (!isCutout && isTransparent && !isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite; // 11
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent;
|
else if (!isCutout && isTransparent && !isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 12
|
||||||
else if (!isCutout && isTransparent && isOutl && !isTransparentQueue)
|
else if (!isCutout && isTransparent && isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite_Outline; // 13
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent_ZWrite_Outline;
|
else if (!isCutout && isTransparent && isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 14
|
||||||
else if (!isCutout && isTransparent && isOutl && isTransparentQueue)
|
else if (!isCutout && isTransparent && isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.TransparentQueueTransparent_ZWrite; // 15
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
else if (!isCutout && isTransparent && isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.Transparent; // 16
|
||||||
NiloToonSurfaceTypePreset.TransparentQueueTransparent_ZWrite;
|
else if ( isCutout && !isTransparent && !isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque; // 17
|
||||||
else if (isCutout && !isTransparent && !isOutl && !isTransparentQueue)
|
else if ( isCutout && !isTransparent && !isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 18
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque;
|
else if ( isCutout && !isTransparent && !isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque; // 19
|
||||||
else if (isCutout && !isTransparent && !isOutl && isTransparentQueue)
|
else if ( isCutout && !isTransparent && !isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 20
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque;
|
else if ( isCutout && !isTransparent && isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque_Outline; // 21
|
||||||
else if (isCutout && !isTransparent && isOutl && !isTransparentQueue)
|
else if ( isCutout && !isTransparent && isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 22
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutOpaque_Outline;
|
else if ( isCutout && !isTransparent && isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite_Outline; // 23
|
||||||
else if (isCutout && !isTransparent && isOutl && isTransparentQueue)
|
else if ( isCutout && !isTransparent && isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 24
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
else if ( isCutout && isTransparent && !isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite; // 25
|
||||||
NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite_Outline;
|
else if ( isCutout && isTransparent && !isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 26
|
||||||
else if (isCutout && isTransparent && !isOutl && !isTransparentQueue)
|
else if ( isCutout && isTransparent && !isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent_ZWrite; // 27
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
else if ( isCutout && isTransparent && !isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 28
|
||||||
NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite;
|
else if ( isCutout && isTransparent && isOutl && !isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent_ZWrite_Outline; // 29
|
||||||
else if (isCutout && isTransparent && !isOutl && isTransparentQueue)
|
else if ( isCutout && isTransparent && isOutl && !isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 30
|
||||||
niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent;
|
else if ( isCutout && isTransparent && isOutl && isTransparentQueue && isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite_Outline; //31
|
||||||
else if (isCutout && isTransparent && isOutl && !isTransparentQueue)
|
else if ( isCutout && isTransparent && isOutl && isTransparentQueue && !isZWrite) niloToonSurfaceTypePresetIDArray[i] = NiloToonSurfaceTypePreset.CutoutTransparent; // 32
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
|
||||||
NiloToonSurfaceTypePreset.CutoutTransparent_ZWrite_Outline;
|
|
||||||
else if (isCutout && isTransparent && isOutl && isTransparentQueue)
|
|
||||||
niloToonSurfaceTypePresetIDArray[i] =
|
|
||||||
NiloToonSurfaceTypePreset.CutoutTransparentQueueTransparent_ZWrite_Outline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// since there are many model's texture that alpha is not used for transparency(e.g. store special data that is not alpha),
|
// since there are many model's texture that alpha is not used for transparency(e.g. store special data that is not alpha),
|
||||||
@ -516,7 +512,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
};
|
};
|
||||||
string[] IsEyeBanNames = { "brown" }; // avoid "brown" treated as eye due to "brow"
|
string[] IsEyeBanNames = { "brown" }; // avoid "brown" treated as eye due to "brow"
|
||||||
|
|
||||||
string[] IsMouthTargetNames = { "mouth", "oral", "tongue", "kuchi", ".ha" };
|
string[] IsMouthTargetNames = { "mouth", "oral", "tongue", "kuchi", ".ha", "kounai", "shita" };
|
||||||
string[] IsMouthBanNames = { ".hada" };
|
string[] IsMouthBanNames = { ".hada" };
|
||||||
|
|
||||||
string[] IsTeethTargetNames = { "teeth", "tooth" };
|
string[] IsTeethTargetNames = { "teeth", "tooth" };
|
||||||
@ -540,6 +536,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
IsFaceFinalTargetNames = IsFaceFinalTargetNames.Concat(IsMouthTargetNames).ToArray();
|
IsFaceFinalTargetNames = IsFaceFinalTargetNames.Concat(IsMouthTargetNames).ToArray();
|
||||||
IsFaceFinalTargetNames = IsFaceFinalTargetNames.Concat(IsTeethTargetNames).ToArray();
|
IsFaceFinalTargetNames = IsFaceFinalTargetNames.Concat(IsTeethTargetNames).ToArray();
|
||||||
|
|
||||||
|
string[] IsFaceExactTargetNames = new string[]{ "me", "ha"};
|
||||||
|
|
||||||
string[] IsFaceFinalBanNames = new string[] { };
|
string[] IsFaceFinalBanNames = new string[] { };
|
||||||
IsFaceFinalBanNames = IsFaceFinalBanNames.Concat(IsFaceBanNames).ToArray();
|
IsFaceFinalBanNames = IsFaceFinalBanNames.Concat(IsFaceBanNames).ToArray();
|
||||||
IsFaceFinalBanNames = IsFaceFinalBanNames.Concat(IsEyeBanNames).ToArray();
|
IsFaceFinalBanNames = IsFaceFinalBanNames.Concat(IsEyeBanNames).ToArray();
|
||||||
@ -561,6 +559,9 @@ namespace NiloToon.NiloToonURP
|
|||||||
IsFaceFinalTargetNames.Where(x => x != "face" && x != "head").ToList();
|
IsFaceFinalTargetNames.Where(x => x != "face" && x != "head").ToList();
|
||||||
IsNoOutlineFinalTargetNames.Concat(IsNoOutlineTargetNames);
|
IsNoOutlineFinalTargetNames.Concat(IsNoOutlineTargetNames);
|
||||||
|
|
||||||
|
List<string> IsNoOutlineExactTargetNames = new List<string>();
|
||||||
|
IsNoOutlineExactTargetNames.Concat(IsFaceExactTargetNames);
|
||||||
|
|
||||||
List<string> IsNoOutlineFinalBanNames = IsFaceFinalBanNames.ToList();
|
List<string> IsNoOutlineFinalBanNames = IsFaceFinalBanNames.ToList();
|
||||||
IsNoOutlineFinalBanNames.Concat(IsNoOutlineBanNames);
|
IsNoOutlineFinalBanNames.Concat(IsNoOutlineBanNames);
|
||||||
|
|
||||||
@ -573,6 +574,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
isNoOutline |= NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
isNoOutline |= NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var keyword in IsNoOutlineExactTargetNames)
|
||||||
|
{
|
||||||
|
isNoOutline |= NiloToonUtils.NameEqualsKeywordIgnoreCase(mat.name, keyword);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var keyword in IsNoOutlineFinalBanNames)
|
foreach (var keyword in IsNoOutlineFinalBanNames)
|
||||||
{
|
{
|
||||||
isNoOutline &= !NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
isNoOutline &= !NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
||||||
@ -642,11 +648,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
if (originalMatClone.shader == VRMBRPMToon00Shader)
|
if (originalMatClone.shader == VRMBRPMToon00Shader)
|
||||||
{
|
{
|
||||||
const float niloToonWidthRelativeToMToon00 = 4;
|
const float niloToonWidthRelativeToMToon00 = 12; //12~18 is good
|
||||||
mat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeToMToon00);
|
mat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeToMToon00);
|
||||||
|
|
||||||
// extra check to limit any unexpected large outline width
|
// extra check to limit any unexpected large outline width
|
||||||
float maxFinalWidth = 0.6f; // 0.6 is NiloToon's default outline width
|
float maxFinalWidth = 0.5f; // 0.5 is NiloToon's default outline width
|
||||||
float finalWidth = Mathf.Min(maxFinalWidth,
|
float finalWidth = Mathf.Min(maxFinalWidth,
|
||||||
mat.GetFloat("_OutlineWidth") * niloToonWidthRelativeToMToon00);
|
mat.GetFloat("_OutlineWidth") * niloToonWidthRelativeToMToon00);
|
||||||
mat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeToMToon00);
|
mat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeToMToon00);
|
||||||
@ -662,7 +668,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
mat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeToMToon10);
|
mat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeToMToon10);
|
||||||
|
|
||||||
// extra check to limit any unexpected large outline width
|
// extra check to limit any unexpected large outline width
|
||||||
float maxFinalWidth = 0.6f; // 0.6 is NiloToon's default outline width
|
float maxFinalWidth = 0.5f; // 0.5 is NiloToon's default outline width
|
||||||
float finalWidth = Mathf.Min(maxFinalWidth,
|
float finalWidth = Mathf.Min(maxFinalWidth,
|
||||||
mat.GetFloat("_OutlineWidth") * niloToonWidthRelativeToMToon10);
|
mat.GetFloat("_OutlineWidth") * niloToonWidthRelativeToMToon10);
|
||||||
mat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeToMToon10);
|
mat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeToMToon10);
|
||||||
@ -865,6 +871,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
isFace |= NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
isFace |= NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var keyword in IsFaceExactTargetNames)
|
||||||
|
{
|
||||||
|
isFace |= NiloToonUtils.NameEqualsKeywordIgnoreCase(mat.name,keyword);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var keyword in IsFaceFinalBanNames)
|
foreach (var keyword in IsFaceFinalBanNames)
|
||||||
{
|
{
|
||||||
isFace &= !NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
isFace &= !NiloToonUtils.NameHasKeyword(mat.name, keyword);
|
||||||
@ -1377,7 +1388,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
toNiloToonMat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeTolilToon);
|
toNiloToonMat.SetFloat("_OutlineWidthExtraMultiplier", niloToonWidthRelativeTolilToon);
|
||||||
|
|
||||||
// extra check to limit any unexpected large outline width
|
// extra check to limit any unexpected large outline width
|
||||||
float maxFinalWidth = 0.6f; // 0.6 is NiloToon's default outline width
|
float maxFinalWidth = 0.5f; // 0.5 is NiloToon's default outline width
|
||||||
float finalWidth = Mathf.Min(maxFinalWidth, _OutlineWidth * niloToonWidthRelativeTolilToon);
|
float finalWidth = Mathf.Min(maxFinalWidth, _OutlineWidth * niloToonWidthRelativeTolilToon);
|
||||||
toNiloToonMat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeTolilToon);
|
toNiloToonMat.SetFloat("_OutlineWidth", finalWidth / niloToonWidthRelativeTolilToon);
|
||||||
|
|
||||||
@ -1797,7 +1808,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[MenuItem("Window/NiloToonURP/Convert Selected Materials to NiloToon", priority = 2)]
|
[MenuItem("Window/NiloToonURP/[Material] Convert Selected Materials to NiloToon", priority = 2)]
|
||||||
|
[MenuItem("Assets/NiloToon/[Material] Convert Selected Materials to NiloToon", priority = 1100 + 2)]
|
||||||
public static void ConvertSelectedMaterialsToNiloToon_Character()
|
public static void ConvertSelectedMaterialsToNiloToon_Character()
|
||||||
{
|
{
|
||||||
var allselectedObjects = Selection.objects;
|
var allselectedObjects = Selection.objects;
|
||||||
@ -1817,7 +1829,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
AutoConvertMaterialsToNiloToon(allInputMaterials);
|
AutoConvertMaterialsToNiloToon(allInputMaterials);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Window/NiloToonURP/Convert Selected Materials to NiloToon", priority = 2, validate = true)]
|
[MenuItem("Window/NiloToonURP/[Material] Convert Selected Materials to NiloToon", priority = 2, validate = true)]
|
||||||
|
[MenuItem("Assets/NiloToon/[Material] Convert Selected Materials to NiloToon", priority = 1100 + 2, validate = true)]
|
||||||
public static bool ValidateConvertSelectedMaterialsToNiloToon_Character()
|
public static bool ValidateConvertSelectedMaterialsToNiloToon_Character()
|
||||||
{
|
{
|
||||||
var allselectedObjects = Selection.objects;
|
var allselectedObjects = Selection.objects;
|
||||||
|
|||||||
@ -7,7 +7,9 @@ using System.IO;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace NiloToon.NiloToonURP
|
namespace NiloToon.NiloToonURP
|
||||||
{
|
{
|
||||||
@ -15,16 +17,30 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
private string ffmpegPath;
|
private string ffmpegPath;
|
||||||
private string inputFilePath = string.Empty;
|
private string inputFilePath = string.Empty;
|
||||||
private string customSuffix = "(BakedMotionBlur)_<fps>_<shutterspeed>"; // Custom suffix for the output file
|
private string customSuffix = "(BakedMotionBlur)_<fps>_<shutterspeed>_<codec>"; // Custom suffix for the output file
|
||||||
private int crf = 0; // Default CRF value
|
private int crf = 0; // Default CRF value (0 is lossless for CRF)
|
||||||
private List<float> fpsOptions = new List<float>(); // List of possible FPS options
|
private List<float> fpsOptions = new List<float>(); // List of possible FPS options
|
||||||
private int selectedFPSIndex = 0; // Default FPS index
|
private int selectedFPSIndex = 0; // Default FPS index
|
||||||
private float inputVideoFPS = 0.0f; // FPS of the input video
|
private float inputVideoFPS = 0.0f; // FPS of the input video
|
||||||
|
private double inputVideoDuration = 0.0; // Duration of the input video in seconds
|
||||||
|
private int totalFrames = 0; // Total number of frames in the output video
|
||||||
private float cameraExposureDuration = 1f / 48f; // 180 shutter angle in terms of 24fps
|
private float cameraExposureDuration = 1f / 48f; // 180 shutter angle in terms of 24fps
|
||||||
private float motionBlurAmount = 1;
|
private float motionBlurAmount = 1;
|
||||||
|
|
||||||
private string ffmpegArgumentsTemplate =
|
private string ffmpegArgumentsTemplate_H264 =
|
||||||
"-vf \"{0}format=yuv420p\" -r {1} -c:v libx264 -preset veryslow -crf {2} -pix_fmt yuv420p -x264opts \"keyint=12:min-keyint=1:ref=1:bframes=0:qcomp=0.8:aq-strength=0.5:direct=auto:fast-pskip=0:deblock=-2,-2\"";
|
"-vf \"{0}format=yuv420p\" -r {1} -c:v libx264 -preset veryslow -crf {2} -pix_fmt yuv420p -x264opts \"keyint=1:ref=4:bframes=0\"";
|
||||||
|
|
||||||
|
private string ffmpegArgumentsTemplate_H265 =
|
||||||
|
"-vf \"{0}format=yuv420p\" -r {1} -c:v libx265 -preset veryslow -x265-params \"crf={2}:keyint=1:no-open-gop=1\" -pix_fmt yuv420p";
|
||||||
|
|
||||||
|
private string ffmpegArgumentsTemplate_H265_10bit =
|
||||||
|
"-vf \"{0}format=yuv420p10le\" -r {1} -c:v libx265 -preset veryslow -x265-params \"crf={2}:keyint=1:no-open-gop=1\" -pix_fmt yuv420p10le";
|
||||||
|
|
||||||
|
private string ffmpegArgumentsTemplate_ProRes_422HQ =
|
||||||
|
"-vf \"{0}\" -r {1} -c:v prores_ks -profile:v 3 -pix_fmt yuv422p10le"; // ProRes 422 HQ
|
||||||
|
|
||||||
|
private string ffmpegArgumentsTemplate_ProRes =
|
||||||
|
"-vf \"{0}\" -r {1} -c:v prores_ks -profile:v 5 -pix_fmt yuv444p10le"; // ProRes 4444 XQ
|
||||||
|
|
||||||
private Process ffmpegProcess;
|
private Process ffmpegProcess;
|
||||||
private Coroutine coroutine;
|
private Coroutine coroutine;
|
||||||
@ -36,6 +52,13 @@ namespace NiloToon.NiloToonURP
|
|||||||
|
|
||||||
private Vector2 scrollPosition;
|
private Vector2 scrollPosition;
|
||||||
|
|
||||||
|
private string[] codecOptions = new string[] { "H.264", "H.265 (8-bit)", "H.265 (10-bit)", "ProRes 422 HQ", "ProRes 4444 XQ" };
|
||||||
|
private int selectedCodecIndex = 3; // Default to ProRes 422 HQ
|
||||||
|
|
||||||
|
// Added variables for logging interval and process timing
|
||||||
|
private DateTime lastLogTime = DateTime.MinValue;
|
||||||
|
private DateTime processStartTime;
|
||||||
|
|
||||||
[MenuItem("Window/NiloToonURP/MotionBlur Video Baker", priority = 10000)]
|
[MenuItem("Window/NiloToonURP/MotionBlur Video Baker", priority = 10000)]
|
||||||
public static void ShowWindow()
|
public static void ShowWindow()
|
||||||
{
|
{
|
||||||
@ -43,20 +66,44 @@ namespace NiloToon.NiloToonURP
|
|||||||
window.LoadFFmpegPath(); // Load the FFmpeg path when the window is opened
|
window.LoadFFmpegPath(); // Load the FFmpeg path when the window is opened
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ClickableLink(string text, string url)
|
||||||
|
{
|
||||||
|
GUIStyle linkStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
richText = true,
|
||||||
|
normal = { textColor = Color.cyan },
|
||||||
|
hover = { textColor = Color.cyan },
|
||||||
|
alignment = TextAnchor.MiddleLeft
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect rect = GUILayoutUtility.GetRect(new GUIContent(text), linkStyle, GUILayout.Height(20));
|
||||||
|
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
|
||||||
|
|
||||||
|
if (GUI.Button(rect, $"{text}", linkStyle))
|
||||||
|
{
|
||||||
|
Application.OpenURL(url);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||||
|
|
||||||
// 960fps will make cinemachine not working correctly, so we suggest max at 900fps
|
// 960fps may make cinemachine not working correctly, so we suggest max at 900fps
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
"[Purpose of this tool]\n" +
|
"[Purpose of this tool]\n" +
|
||||||
"Bake 480-900 fps video with zero or little motion blur -> 24/30/60 fps video with cinematic motion blur & AA produced by sub frame merging\n\n" +
|
"Import a 480-960 fps short video, bake to a 24/30/60 fps video with high-quality motion blur & AA produced by sub-frame accumulation, similar to UnrealEngine Movie Render Queue's temporal sampling AA\n\n" +
|
||||||
"[How to use?]\n" +
|
"[How to use?]\n" +
|
||||||
"1.Locate your own ffmpeg.exe (download from ffmpeg.org)\n" +
|
"1. Locate your own ffmpeg.exe (download the latest from ffmpeg.org)\n" +
|
||||||
"2.Prepare a video with 480~900FPS (e.g., Record using Unity's Recorder with a high custom FPS)\n" +
|
"2. Select a 480~960FPS video as Input Video(e.g., set NiloToonMotionBlurVolume = 0.5~0.25 intensity, then record using Unity's Recorder with 480~960 FPS into ProRes422LT or higher)\n" +
|
||||||
"3.Select that video as Input Video, wait for analysis\n" +
|
"3. Click 'Bake now!', this tool will bake motion blur & AA into a result 24/30/60 fps output video", MessageType.Info);
|
||||||
"4.(optional)Adjust other settings if needed\n" +
|
|
||||||
"5.Click 'Bake now!', this tool will bake cinematic motion blur & AA to a 24/30/60 fps output video (H.264)", MessageType.Info);
|
// add here
|
||||||
|
ClickableLink("Online Document", "https://docs.google.com/document/d/1iEh1E5xLXnXuICM0ElV3F3x_J2LND9Du2SSKzcIuPXw/edit?tab=t.0#heading=h.tkl2vd8auzt9");
|
||||||
|
ClickableLink("Download FFmpeg", "https://ffmpeg.org");
|
||||||
|
|
||||||
GUI.enabled = ffmpegProcess == null;
|
GUI.enabled = ffmpegProcess == null;
|
||||||
|
|
||||||
@ -65,7 +112,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
GUILayout.Label("FFmpeg Path", EditorStyles.boldLabel);
|
GUILayout.Label("FFmpeg Path", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
ffmpegPath = EditorGUILayout.TextField("Path",ffmpegPath);
|
ffmpegPath = EditorGUILayout.TextField("Path", ffmpegPath);
|
||||||
if (GUILayout.Button("...", GUILayout.Width(60)))
|
if (GUILayout.Button("...", GUILayout.Width(60)))
|
||||||
{
|
{
|
||||||
string selectedPath = EditorUtility.OpenFilePanel("Select FFmpeg Executable", "", "exe");
|
string selectedPath = EditorUtility.OpenFilePanel("Select FFmpeg Executable", "", "exe");
|
||||||
@ -84,21 +131,21 @@ namespace NiloToon.NiloToonURP
|
|||||||
GUILayout.Label("Input Video", EditorStyles.boldLabel);
|
GUILayout.Label("Input Video", EditorStyles.boldLabel);
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
inputFilePath = EditorGUILayout.TextField("Path",inputFilePath);
|
inputFilePath = EditorGUILayout.TextField("Path", inputFilePath);
|
||||||
if (GUILayout.Button("...", GUILayout.Width(30)) && ffmpegProcess == null)
|
if (GUILayout.Button("...", GUILayout.Width(30)) && ffmpegProcess == null)
|
||||||
{
|
{
|
||||||
string newPath = EditorUtility.OpenFilePanel("Select Input File", "", "mov,mp4");
|
string newPath = EditorUtility.OpenFilePanel("Select Input File", "", "mov,mp4");
|
||||||
if (!string.IsNullOrEmpty(newPath))
|
if (!string.IsNullOrEmpty(newPath))
|
||||||
{
|
{
|
||||||
inputFilePath = newPath;
|
inputFilePath = newPath;
|
||||||
ExtractVideoFPS(inputFilePath); // Extract the FPS of the selected video
|
ExtractVideoInfo(inputFilePath); // Extract the FPS and duration of the selected video
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
if (inputVideoFPS < 480)
|
if (inputVideoFPS < 480)
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox("Expect a video with 480~900FPS", MessageType.Info);
|
EditorGUILayout.HelpBox("Expect a video with 480~960FPS", MessageType.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display error message if input video path is invalid
|
// Display error message if input video path is invalid
|
||||||
@ -108,7 +155,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// input video fps
|
// Input Video FPS
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
if (inputVideoFPS > 0 && File.Exists(inputFilePath))
|
if (inputVideoFPS > 0 && File.Exists(inputFilePath))
|
||||||
{
|
{
|
||||||
@ -118,11 +165,14 @@ namespace NiloToon.NiloToonURP
|
|||||||
GUILayout.Space(25);
|
GUILayout.Space(25);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// output video (suffix,fps,CRF)
|
// Output Video Settings
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GUILayout.Label("Output Video", EditorStyles.boldLabel);
|
GUILayout.Label("Output Video", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
// Codec Selection
|
||||||
|
selectedCodecIndex = EditorGUILayout.Popup(new GUIContent("Codec"), selectedCodecIndex, codecOptions);
|
||||||
|
|
||||||
if (fpsOptions.Count > 0)
|
if (fpsOptions.Count > 0)
|
||||||
{
|
{
|
||||||
selectedFPSIndex = Mathf.Clamp(selectedFPSIndex, 0, fpsOptions.Count - 1);
|
selectedFPSIndex = Mathf.Clamp(selectedFPSIndex, 0, fpsOptions.Count - 1);
|
||||||
@ -130,7 +180,6 @@ namespace NiloToon.NiloToonURP
|
|||||||
if (newSelectedFPSIndex != selectedFPSIndex)
|
if (newSelectedFPSIndex != selectedFPSIndex)
|
||||||
{
|
{
|
||||||
selectedFPSIndex = newSelectedFPSIndex;
|
selectedFPSIndex = newSelectedFPSIndex;
|
||||||
|
|
||||||
UnityEngine.Debug.Log($"Selected FPS: {GetOutputFPS()}"); // Log the selected FPS
|
UnityEngine.Debug.Log($"Selected FPS: {GetOutputFPS()}"); // Log the selected FPS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,16 +189,42 @@ namespace NiloToon.NiloToonURP
|
|||||||
}
|
}
|
||||||
|
|
||||||
motionBlurAmount = EditorGUILayout.Slider("Motion Blur", motionBlurAmount, 0f, 4f);
|
motionBlurAmount = EditorGUILayout.Slider("Motion Blur", motionBlurAmount, 0f, 4f);
|
||||||
crf = EditorGUILayout.IntSlider("CRF", crf, 0, 51);
|
|
||||||
|
|
||||||
EditorGUILayout.HelpBox(
|
// CRF Slider (Only for codecs that support it)
|
||||||
"CRF (Constant Rate Factor) controls the quality of the video. Lower values mean higher quality and larger file sizes. The range is from 0 (lossless) to 51 (worst quality).",
|
if (selectedCodecIndex != 3 && selectedCodecIndex != 4) // Not ProRes
|
||||||
MessageType.Info);
|
{
|
||||||
|
crf = EditorGUILayout.IntSlider(new GUIContent("CRF", "For lossless encoding, set CRF to 0. Higher values reduce quality."), crf, 0, 51);
|
||||||
|
if (crf == 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("CRF is set to 0: Lossless encoding. This results in the highest quality and largest file size.", MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("CRF controls the quality of the video. Lower values mean higher quality and larger file sizes.", MessageType.Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customSuffix = EditorGUILayout.TextField("Suffix", customSuffix);
|
customSuffix = EditorGUILayout.TextField("Suffix", customSuffix);
|
||||||
|
|
||||||
|
// Open Destination Folder Button
|
||||||
|
GUI.enabled = !string.IsNullOrEmpty(inputFilePath) && File.Exists(inputFilePath);
|
||||||
|
if (GUILayout.Button("Open Destination Folder"))
|
||||||
|
{
|
||||||
|
string currentOutputFilePath = GenerateOutputFilePath(inputFilePath, customSuffix);
|
||||||
|
string folder = Path.GetDirectoryName(currentOutputFilePath);
|
||||||
|
if (Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
OpenFolder(folder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("Folder Not Found", "The destination folder does not exist.", "OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUI.enabled = ffmpegProcess == null;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// output video info
|
// Output Video Info
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
if (fpsOptions.Count > 0)
|
if (fpsOptions.Count > 0)
|
||||||
{
|
{
|
||||||
@ -158,30 +233,18 @@ namespace NiloToon.NiloToonURP
|
|||||||
EditorGUILayout.Space(10);
|
EditorGUILayout.Space(10);
|
||||||
EditorGUILayout.LabelField("Output info:", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField("Output info:", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"- TMix Frame Count: {currenttmixFrameCount}\n" +
|
$"- Temporal Sample(TMix) Count: {currenttmixFrameCount} (>=16 is good for cinematic output)\n" +
|
||||||
$"- Shutter Angle in terms of 24fps: {GetShutterAngleInTermsOf24fps()} degrees (~180 is a good default for cinematic output)\n" +
|
$"- Shutter Angle in terms of 24fps: {GetShutterAngleInTermsOf24fps()} degrees (~180 is a good default for cinematic output)\n" +
|
||||||
$"- Shutter Speed: {GetShutterSpeedDisplayString()} (~1/48 is a good default for cinematic output)"
|
$"- Shutter Speed: {GetShutterSpeedDisplayString()} (~1/48 is a good default for cinematic output)"
|
||||||
, MessageType.Info);
|
, MessageType.Info);
|
||||||
|
|
||||||
// check if shutter angle is too small
|
// Check if shutter angle is too small
|
||||||
if (currenttmixFrameCount < Mathf.CeilToInt(inputVideoFPS / GetOutputFPS()/ 2))
|
if (currenttmixFrameCount < Mathf.CeilToInt(inputVideoFPS / GetOutputFPS() / 2))
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"Current Shutter Angle for {GetOutputFPS()}fps is < 180, while it is not wrong, it may produce not enough motion blur"
|
$"Current Shutter Angle for {GetOutputFPS()}fps is < 180, while it is not wrong, it may produce not enough motion blur"
|
||||||
, MessageType.Warning);
|
, MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is ok to go over 360, so don't give warning.
|
|
||||||
// for example, 60fps output with 1/48th shutter speed
|
|
||||||
/*
|
|
||||||
// check if shutter angle is too big
|
|
||||||
if (currenttmixFrameCount > (inputVideoFPS / GetOutputFPS()))
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox(
|
|
||||||
$"Current Shutter Angle is too large, it may produce too much motion blur"
|
|
||||||
, MessageType.Warning);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.Space(25);
|
GUILayout.Space(25);
|
||||||
@ -189,12 +252,13 @@ namespace NiloToon.NiloToonURP
|
|||||||
EditorGUILayout.LabelField("Extra note:", EditorStyles.boldLabel);
|
EditorGUILayout.LabelField("Extra note:", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"- Make sure Project Settings > VFX > Fixed Time Step is using '1/fps of recorder' when recording\n" +
|
$"- Make sure Project Settings > VFX > Fixed Time Step is using '1/fps of recorder' when recording\n" +
|
||||||
$"- Do not record in 960fps or higher, it may break cinemachine's camera movement"
|
$"- If fps is high (e.g., 900fps or higher), it may break cinemachine's camera movement\n" +
|
||||||
|
$"- Example input video: 1440p 960fps, or 2160p 480fps"
|
||||||
, MessageType.Info);
|
, MessageType.Info);
|
||||||
|
|
||||||
GUI.enabled = true;
|
GUI.enabled = true;
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Bake button
|
// Bake Button
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Disable the "Bake Now!" button if any condition is not met
|
// Disable the "Bake Now!" button if any condition is not met
|
||||||
@ -279,6 +343,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
return (float)currenttmixFrameCount / (inputVideoFPS / 24f) * 360f;
|
return (float)currenttmixFrameCount / (inputVideoFPS / 24f) * 360f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetShutterSpeed()
|
private float GetShutterSpeed()
|
||||||
{
|
{
|
||||||
return (1f / 24f) * (GetShutterAngleInTermsOf24fps() / 360f);
|
return (1f / 24f) * (GetShutterAngleInTermsOf24fps() / 360f);
|
||||||
@ -286,17 +351,38 @@ namespace NiloToon.NiloToonURP
|
|||||||
|
|
||||||
private string GetShutterSpeedDisplayString()
|
private string GetShutterSpeedDisplayString()
|
||||||
{
|
{
|
||||||
return $"1/{1 / GetShutterSpeed()}s";
|
return $"1/{FormatNumber(1 / GetShutterSpeed())}s";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetShutterSpeedFileNameString()
|
private string GetShutterSpeedFileNameString()
|
||||||
{
|
{
|
||||||
return $"OneOver{1 / GetShutterSpeed()}s";
|
return $"OneOver{FormatNumber(1 / GetShutterSpeed())}s";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to format numbers without unnecessary trailing zeros
|
||||||
|
private string FormatNumber(double number)
|
||||||
|
{
|
||||||
|
if (number % 1 == 0)
|
||||||
|
return number.ToString("0");
|
||||||
|
else
|
||||||
|
return number.ToString("0.##");
|
||||||
|
}
|
||||||
|
|
||||||
private string GenerateOutputFilePath(string inputPath, string suffix)
|
private string GenerateOutputFilePath(string inputPath, string suffix)
|
||||||
{
|
{
|
||||||
suffix = suffix.Replace("<fps>", $"{GetOutputFPS()}fps");
|
suffix = suffix.Replace("<fps>", $"{GetOutputFPS()}fps");
|
||||||
suffix = suffix.Replace("<shutterspeed>", $"{GetShutterSpeedFileNameString()}");
|
suffix = suffix.Replace("<shutterspeed>", $"{GetShutterSpeedFileNameString()}");
|
||||||
|
|
||||||
|
// Handle codec placeholder
|
||||||
|
if (suffix.Contains("<codec>"))
|
||||||
|
{
|
||||||
|
// Get codec name and format it for filename
|
||||||
|
string codecName = codecOptions[selectedCodecIndex];
|
||||||
|
codecName = codecName.Replace(" ", "").Replace("(", "").Replace(")", "").Replace(".", "").Replace("-", "");
|
||||||
|
|
||||||
|
suffix = suffix.Replace("<codec>", codecName);
|
||||||
|
}
|
||||||
|
|
||||||
string directory = Path.GetDirectoryName(inputPath);
|
string directory = Path.GetDirectoryName(inputPath);
|
||||||
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(inputPath);
|
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(inputPath);
|
||||||
string extension = Path.GetExtension(inputPath);
|
string extension = Path.GetExtension(inputPath);
|
||||||
@ -306,30 +392,62 @@ namespace NiloToon.NiloToonURP
|
|||||||
private IEnumerator StartFFmpegProcessCoroutine(string outputFilePath, float selectedFPS)
|
private IEnumerator StartFFmpegProcessCoroutine(string outputFilePath, float selectedFPS)
|
||||||
{
|
{
|
||||||
string tmixFilters = Generate_tmixFilters(inputVideoFPS);
|
string tmixFilters = Generate_tmixFilters(inputVideoFPS);
|
||||||
string ffmpegArguments = string.Format(ffmpegArgumentsTemplate, tmixFilters, selectedFPS, crf);
|
|
||||||
|
|
||||||
|
// Record start time
|
||||||
|
processStartTime = DateTime.Now;
|
||||||
|
|
||||||
|
// Calculate totalFrames here, based on the selected output FPS and the input video duration
|
||||||
|
if (selectedFPS > 0 && inputVideoDuration > 0)
|
||||||
|
{
|
||||||
|
totalFrames = (int)(selectedFPS * inputVideoDuration);
|
||||||
|
UnityEngine.Debug.Log($"Calculated Total Output Frames (using output video FPS {selectedFPS}): {totalFrames}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
totalFrames = 0;
|
||||||
|
UnityEngine.Debug.LogError("Failed to calculate total frames due to invalid output FPS or video duration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log start of baking process with output file name
|
||||||
|
UnityEngine.Debug.Log($"Baking started. Output file: {outputFilePath}");
|
||||||
|
|
||||||
|
// Select the FFmpeg arguments template based on the selected codec
|
||||||
|
string ffmpegArgumentsTemplate = GetFFmpegArgumentsTemplate();
|
||||||
|
|
||||||
|
// Prepare the FFmpeg arguments
|
||||||
|
string ffmpegArguments = "";
|
||||||
|
|
||||||
|
if (selectedCodecIndex == 0 || selectedCodecIndex == 1 || selectedCodecIndex == 2) // H.264, H.265
|
||||||
|
{
|
||||||
|
ffmpegArguments = string.Format(ffmpegArgumentsTemplate, tmixFilters, selectedFPS, crf);
|
||||||
|
}
|
||||||
|
else if (selectedCodecIndex == 3 || selectedCodecIndex == 4) // ProRes
|
||||||
|
{
|
||||||
|
ffmpegArguments = string.Format(ffmpegArgumentsTemplate, tmixFilters, selectedFPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use '-hide_banner' to suppress unnecessary output
|
||||||
ProcessStartInfo processStartInfo = new ProcessStartInfo
|
ProcessStartInfo processStartInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = ffmpegPath,
|
FileName = ffmpegPath,
|
||||||
Arguments = $"-i \"{inputFilePath}\" {ffmpegArguments} \"{outputFilePath}\"",
|
Arguments = $"-hide_banner -i \"{inputFilePath}\" {ffmpegArguments} \"{outputFilePath}\"",
|
||||||
RedirectStandardOutput = true,
|
RedirectStandardOutput = false, // Do not redirect standard output
|
||||||
RedirectStandardError = true,
|
RedirectStandardError = true, // Redirect standard error to capture errors and progress
|
||||||
UseShellExecute = false, // must be false
|
UseShellExecute = false, // Must be false
|
||||||
CreateNoWindow = true
|
CreateNoWindow = true
|
||||||
};
|
};
|
||||||
|
|
||||||
ffmpegProcess = new Process
|
ffmpegProcess = new Process
|
||||||
{
|
{
|
||||||
StartInfo = processStartInfo
|
StartInfo = processStartInfo,
|
||||||
|
EnableRaisingEvents = true
|
||||||
};
|
};
|
||||||
ffmpegProcess.OutputDataReceived += (sender, args) => HandleFFmpegOutput(args.Data);
|
|
||||||
ffmpegProcess.ErrorDataReceived += (sender, args) => HandleFFmpegOutput(args.Data);
|
|
||||||
|
|
||||||
|
ffmpegProcess.ErrorDataReceived += FfmpegProcess_ErrorDataReceived;
|
||||||
ffmpegProcess.Start();
|
ffmpegProcess.Start();
|
||||||
ffmpegProcess.BeginOutputReadLine();
|
|
||||||
ffmpegProcess.BeginErrorReadLine();
|
ffmpegProcess.BeginErrorReadLine();
|
||||||
|
|
||||||
// Wait for the process to exit while updating the progress bar
|
// Wait for the process to exit
|
||||||
while (!ffmpegProcess.HasExited)
|
while (!ffmpegProcess.HasExited)
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return null;
|
||||||
@ -338,13 +456,233 @@ namespace NiloToon.NiloToonURP
|
|||||||
ffmpegProcess.WaitForExit();
|
ffmpegProcess.WaitForExit();
|
||||||
ffmpegProcess = null;
|
ffmpegProcess = null;
|
||||||
|
|
||||||
// Close the progress bar when the process exits
|
// Calculate elapsed time
|
||||||
EditorUtility.ClearProgressBar();
|
TimeSpan elapsedTime = DateTime.Now - processStartTime;
|
||||||
|
|
||||||
|
// Log completion message
|
||||||
|
string timeSpent = $"Time spent = {elapsedTime.Hours} hours {elapsedTime.Minutes} minutes {elapsedTime.Seconds} seconds, video completed ({Path.GetFileName(outputFilePath)}).";
|
||||||
|
UnityEngine.Debug.Log(timeSpent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FfmpegProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(e.Data))
|
||||||
|
{
|
||||||
|
string data = e.Data;
|
||||||
|
HandleFFmpegOutput(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleFFmpegOutput(string data)
|
||||||
|
{
|
||||||
|
// Parse FFmpeg output to extract meaningful information
|
||||||
|
if (IsCriticalFfmpegMessage(data))
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError("FFmpeg Error: " + data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Parse progress information
|
||||||
|
// FFmpeg outputs progress in lines like: "frame=123 fps=45 q=28.0 size=1234kB time=00:00:05.12 bitrate=1976.3kbits/s speed=1.23x"
|
||||||
|
|
||||||
|
if (data.StartsWith("frame="))
|
||||||
|
{
|
||||||
|
// Regular expression to parse the progress line
|
||||||
|
var progressMatch = Regex.Match(data, @"frame=\s*(\d+)\s.*?time=\s*(\S+)\s.*?speed=\s*([\d\.]+)x");
|
||||||
|
|
||||||
|
if (progressMatch.Success)
|
||||||
|
{
|
||||||
|
string frameStr = progressMatch.Groups[1].Value;
|
||||||
|
string timeStr = progressMatch.Groups[2].Value;
|
||||||
|
string speedStr = progressMatch.Groups[3].Value;
|
||||||
|
|
||||||
|
if (int.TryParse(frameStr, out int currentFrame))
|
||||||
|
{
|
||||||
|
float percentage = 0f;
|
||||||
|
if (totalFrames > 0)
|
||||||
|
{
|
||||||
|
percentage = (float)currentFrame / totalFrames * 100f;
|
||||||
|
percentage = Mathf.Clamp(percentage, 0f, 100f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only log if at least 2 seconds have passed since last log
|
||||||
|
if ((DateTime.Now - lastLogTime).TotalSeconds >= 2)
|
||||||
|
{
|
||||||
|
TimeSpan elapsedTime = DateTime.Now - processStartTime;
|
||||||
|
|
||||||
|
string estimatedTimeRemainingString = "Unknown";
|
||||||
|
if (percentage > 0)
|
||||||
|
{
|
||||||
|
double estimatedTotalSeconds = elapsedTime.TotalSeconds / (percentage / 100);
|
||||||
|
TimeSpan estimatedRemainingTime = TimeSpan.FromSeconds(estimatedTotalSeconds - elapsedTime.TotalSeconds);
|
||||||
|
|
||||||
|
estimatedTimeRemainingString = $"{(int)estimatedRemainingTime.TotalHours}h {estimatedRemainingTime.Minutes}m {estimatedRemainingTime.Seconds}s";
|
||||||
|
}
|
||||||
|
|
||||||
|
string elapsedTimeString = $"{(int)elapsedTime.TotalHours}h {elapsedTime.Minutes}m {elapsedTime.Seconds}s";
|
||||||
|
|
||||||
|
string logMessage = $"Frame {currentFrame}/{totalFrames} ({percentage:F1}%), Processed time: {elapsedTimeString}, Estimated time remaining: {estimatedTimeRemainingString}, Speed {speedStr}x";
|
||||||
|
|
||||||
|
UnityEngine.Debug.Log(logMessage);
|
||||||
|
|
||||||
|
lastLogTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Optionally, handle other outputs or suppress less important messages
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsCriticalFfmpegMessage(string message)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(message))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if message contains 'Error' or 'Invalid' etc.
|
||||||
|
string lowerMessage = message.ToLowerInvariant();
|
||||||
|
return lowerMessage.Contains("error") || lowerMessage.Contains("invalid") || lowerMessage.Contains("failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelFFmpegProcess()
|
||||||
|
{
|
||||||
|
if (ffmpegProcess != null && !ffmpegProcess.HasExited)
|
||||||
|
{
|
||||||
|
ffmpegProcess.Kill();
|
||||||
|
ffmpegProcess.WaitForExit(); // Ensure the process has completely exited
|
||||||
|
ffmpegProcess = null;
|
||||||
|
if (coroutine != null)
|
||||||
|
{
|
||||||
|
EditorCoroutine.StopCoroutine(coroutine);
|
||||||
|
coroutine = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnityEngine.Debug.Log("FFmpeg process cancelled.");
|
||||||
|
|
||||||
|
// Delete the incomplete output file
|
||||||
|
if (File.Exists(outputFilePath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(outputFilePath);
|
||||||
|
UnityEngine.Debug.Log("Incomplete output file deleted.");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError($"Failed to delete incomplete output file: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractVideoInfo(string videoPath)
|
||||||
|
{
|
||||||
|
inputVideoFPS = 0f;
|
||||||
|
inputVideoDuration = 0.0;
|
||||||
|
|
||||||
|
ProcessStartInfo processStartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = ffmpegPath,
|
||||||
|
Arguments = $"-hide_banner -i \"{videoPath}\"",
|
||||||
|
RedirectStandardOutput = false, // FFmpeg outputs video information to standard error stream
|
||||||
|
RedirectStandardError = true, // Redirect standard error stream
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
|
||||||
|
Process process = new Process
|
||||||
|
{
|
||||||
|
StartInfo = processStartInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
process.ErrorDataReceived += ProcessOutputHandler;
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
process.WaitForExit();
|
||||||
|
|
||||||
|
// After processing, check if Duration was successfully extracted
|
||||||
|
if (inputVideoDuration <= 0)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError("Failed to extract Duration from the input video.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessOutputHandler(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(e.Data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// UnityEngine.Debug.Log("FFmpeg Output: " + e.Data); // Optionally log output
|
||||||
|
|
||||||
|
// Extract FPS (input video FPS)
|
||||||
|
var matchFPS = Regex.Match(e.Data, @"Video:.*?(\d+(\.\d+)?) fps");
|
||||||
|
if (matchFPS.Success)
|
||||||
|
{
|
||||||
|
if (float.TryParse(matchFPS.Groups[1].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out float fps))
|
||||||
|
{
|
||||||
|
inputVideoFPS = fps;
|
||||||
|
UnityEngine.Debug.Log("Input Video FPS: " + inputVideoFPS);
|
||||||
|
UpdateFPSOptions(inputVideoFPS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract duration
|
||||||
|
var matchDuration = Regex.Match(e.Data, @"Duration: (\d+):(\d+):(\d+(\.\d+)?)");
|
||||||
|
if (matchDuration.Success)
|
||||||
|
{
|
||||||
|
int hours = int.Parse(matchDuration.Groups[1].Value);
|
||||||
|
int minutes = int.Parse(matchDuration.Groups[2].Value);
|
||||||
|
double seconds = double.Parse(matchDuration.Groups[3].Value, CultureInfo.InvariantCulture);
|
||||||
|
inputVideoDuration = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
UnityEngine.Debug.Log("Input Video Duration: " + inputVideoDuration + " seconds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFPSOptions(float inputFPS)
|
||||||
|
{
|
||||||
|
fpsOptions.Clear();
|
||||||
|
float[] supportedOutputFPS = { 23.976f, 24f, 25f, 29.97f, 30f, 48f, 50f, 59.94f, 60f, 72f, 90f, 100f, 120f, 144f, 240f };
|
||||||
|
|
||||||
|
foreach (var fps in supportedOutputFPS)
|
||||||
|
{
|
||||||
|
if (inputFPS >= fps * 2)
|
||||||
|
{
|
||||||
|
fpsOptions.Add(fps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find index of 60 fps or closest lower value if 60 is not available
|
||||||
|
int index60 = fpsOptions.FindIndex(fps => fps >= 60);
|
||||||
|
selectedFPSIndex = index60 >= 0 ? index60 : fpsOptions.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFFmpegArgumentsTemplate()
|
||||||
|
{
|
||||||
|
switch (selectedCodecIndex)
|
||||||
|
{
|
||||||
|
case 0: // H.264
|
||||||
|
return ffmpegArgumentsTemplate_H264;
|
||||||
|
case 1: // H.265 (8-bit)
|
||||||
|
return ffmpegArgumentsTemplate_H265;
|
||||||
|
case 2: // H.265 (10-bit)
|
||||||
|
return ffmpegArgumentsTemplate_H265_10bit;
|
||||||
|
case 3: // ProRes 422 HQ
|
||||||
|
return ffmpegArgumentsTemplate_ProRes_422HQ;
|
||||||
|
case 4: // ProRes 4444 XQ
|
||||||
|
return ffmpegArgumentsTemplate_ProRes;
|
||||||
|
default:
|
||||||
|
return ffmpegArgumentsTemplate_H264;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string Generate_tmixFilters(float inputVideoFPS)
|
private string Generate_tmixFilters(float inputVideoFPS)
|
||||||
{
|
{
|
||||||
int numberOfTMixFrames = Mathf.FloorToInt(inputVideoFPS * cameraExposureDuration * motionBlurAmount);
|
int numberOfTMixFrames = Mathf.FloorToInt(inputVideoFPS * cameraExposureDuration * motionBlurAmount);
|
||||||
|
|
||||||
|
// ensure at least 1 frame when motionBlurAmount is 0
|
||||||
|
numberOfTMixFrames = Mathf.Max(numberOfTMixFrames, 1);
|
||||||
|
|
||||||
currenttmixFrameCount = numberOfTMixFrames;
|
currenttmixFrameCount = numberOfTMixFrames;
|
||||||
|
|
||||||
if (currenttmixFrameCount == 0)
|
if (currenttmixFrameCount == 0)
|
||||||
@ -352,11 +690,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if METHOD1
|
#if METHOD1
|
||||||
string weightString = string.Join(" ", Enumerable.Repeat("1", numberOfTMixFrames));
|
string weightString = string.Join(" ", Enumerable.Repeat("1", numberOfTMixFrames));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if METHOD2
|
#if METHOD2
|
||||||
// [2-way expo falloff]
|
// [2-way expo falloff]
|
||||||
|
|
||||||
// Generate exponential falloff weights
|
// Generate exponential falloff weights
|
||||||
@ -376,10 +714,9 @@ namespace NiloToon.NiloToonURP
|
|||||||
|
|
||||||
string weightString = string.Join(" ", weights);
|
string weightString = string.Join(" ", weights);
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if METHOD3
|
||||||
#if METHOD3
|
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
// [1-way expo falloff]
|
// [1-way expo falloff]
|
||||||
|
|
||||||
@ -405,11 +742,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
|
|
||||||
string weightString = string.Join(" ", weights);
|
string weightString = string.Join(" ", weights);
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if METHOD4
|
#if METHOD4
|
||||||
string weightString = GenerateGaussianWeights(numberOfTMixFrames);
|
string weightString = GenerateGaussianWeights(numberOfTMixFrames);
|
||||||
#endif
|
#endif
|
||||||
return $"tmix=frames={numberOfTMixFrames}:weights='{weightString}',";
|
return $"tmix=frames={numberOfTMixFrames}:weights='{weightString}',";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,104 +780,19 @@ namespace NiloToon.NiloToonURP
|
|||||||
return string.Join(" ", scaledWeights);
|
return string.Join(" ", scaledWeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CancelFFmpegProcess()
|
// New method to open the folder directly
|
||||||
|
private void OpenFolder(string folderPath)
|
||||||
{
|
{
|
||||||
if (ffmpegProcess != null && !ffmpegProcess.HasExited)
|
#if UNITY_EDITOR_WIN
|
||||||
{
|
folderPath = folderPath.Replace('/', '\\'); // Ensure correct path separator on Windows
|
||||||
ffmpegProcess.Kill();
|
System.Diagnostics.Process.Start("explorer.exe", folderPath);
|
||||||
ffmpegProcess.WaitForExit(); // Ensure the process has completely exited
|
#elif UNITY_EDITOR_OSX
|
||||||
ffmpegProcess = null;
|
System.Diagnostics.Process.Start("open", folderPath);
|
||||||
if (coroutine != null)
|
#elif UNITY_EDITOR_LINUX
|
||||||
{
|
System.Diagnostics.Process.Start("xdg-open", folderPath);
|
||||||
EditorCoroutine.StopCoroutine(coroutine);
|
#else
|
||||||
coroutine = null;
|
Application.OpenURL("file://" + folderPath);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
EditorUtility.ClearProgressBar();
|
|
||||||
UnityEngine.Debug.Log("FFmpeg process cancelled.");
|
|
||||||
|
|
||||||
// Delete the incomplete output file
|
|
||||||
if (File.Exists(outputFilePath))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(outputFilePath);
|
|
||||||
UnityEngine.Debug.Log("Incomplete output file deleted.");
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
UnityEngine.Debug.LogError($"Failed to delete incomplete output file: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleFFmpegOutput(string data)
|
|
||||||
{
|
|
||||||
UnityEngine.Debug.Log(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractVideoFPS(string videoPath)
|
|
||||||
{
|
|
||||||
ProcessStartInfo processStartInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = ffmpegPath,
|
|
||||||
Arguments = $"-i \"{videoPath}\" -vcodec copy -f null -",
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
Process process = new Process
|
|
||||||
{
|
|
||||||
StartInfo = processStartInfo
|
|
||||||
};
|
|
||||||
|
|
||||||
process.OutputDataReceived += ProcessOutputHandler;
|
|
||||||
process.ErrorDataReceived += ProcessOutputHandler;
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
process.BeginOutputReadLine();
|
|
||||||
process.BeginErrorReadLine();
|
|
||||||
process.WaitForExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessOutputHandler(object sender, DataReceivedEventArgs e)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(e.Data))
|
|
||||||
return;
|
|
||||||
|
|
||||||
UnityEngine.Debug.Log("FFmpeg Output: " + e.Data); // Log the output to debug
|
|
||||||
|
|
||||||
// Example of how to parse the FPS from FFmpeg output
|
|
||||||
// Look for a line containing "fps" and extract the value
|
|
||||||
var match = Regex.Match(e.Data, @"(\d+(\.\d+)?) fps");
|
|
||||||
if (match.Success)
|
|
||||||
{
|
|
||||||
if (float.TryParse(match.Groups[1].Value, out float fps))
|
|
||||||
{
|
|
||||||
inputVideoFPS = fps;
|
|
||||||
UnityEngine.Debug.Log("Extracted FPS: " + inputVideoFPS); // Log the extracted FPS
|
|
||||||
UpdateFPSOptions(inputVideoFPS); // Update FPS options based on extracted FPS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateFPSOptions(float inputFPS)
|
|
||||||
{
|
|
||||||
fpsOptions.Clear();
|
|
||||||
float[] supportedOutputFPS = { 24, 25, 30, 50, 60 };
|
|
||||||
|
|
||||||
foreach (var fps in supportedOutputFPS)
|
|
||||||
{
|
|
||||||
if (inputFPS >= fps * 2)
|
|
||||||
{
|
|
||||||
fpsOptions.Add(fps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedFPSIndex = fpsOptions.Count - 1; // Set the highest FPS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -85,7 +85,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
Mesh mesh = null;
|
Mesh mesh = null;
|
||||||
switch (renderer)
|
switch (renderer)
|
||||||
{
|
{
|
||||||
case MeshRenderer mr: mesh = mr.GetComponent<MeshFilter>().sharedMesh; break;
|
case MeshRenderer mr:
|
||||||
|
MeshFilter mf = mr.GetComponent<MeshFilter>();
|
||||||
|
if(!mf) continue;
|
||||||
|
mesh = mf.sharedMesh;
|
||||||
|
break;
|
||||||
case SkinnedMeshRenderer smr: mesh = smr.sharedMesh; ; break;
|
case SkinnedMeshRenderer smr: mesh = smr.sharedMesh; ; break;
|
||||||
default:
|
default:
|
||||||
break; // do nothing if not a supported renderer(e.g. particle system's renderer)
|
break; // do nothing if not a supported renderer(e.g. particle system's renderer)
|
||||||
@ -112,7 +116,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
Mesh mesh = null;
|
Mesh mesh = null;
|
||||||
switch (renderer)
|
switch (renderer)
|
||||||
{
|
{
|
||||||
case MeshRenderer mr: mesh = mr.GetComponent<MeshFilter>().sharedMesh; break;
|
case MeshRenderer mr:
|
||||||
|
MeshFilter mf = mr.GetComponent<MeshFilter>();
|
||||||
|
if(!mf) continue;
|
||||||
|
mesh = mf.sharedMesh;
|
||||||
|
break;
|
||||||
case SkinnedMeshRenderer smr: mesh = smr.sharedMesh; break;
|
case SkinnedMeshRenderer smr: mesh = smr.sharedMesh; break;
|
||||||
default:
|
default:
|
||||||
break; // do nothing if not a supported renderer(e.g. particle system's renderer)
|
break; // do nothing if not a supported renderer(e.g. particle system's renderer)
|
||||||
@ -381,7 +389,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
public class NiloToonEditorAutoSetupCharacter
|
public class NiloToonEditorAutoSetupCharacter
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[MenuItem("Window/NiloToonURP/Convert selected GameObjects to NiloToon", priority = 1)]
|
[MenuItem("Window/NiloToonURP/[GameObject] Convert Selected GameObjects to NiloToon", priority = 1)]
|
||||||
|
[MenuItem("Assets/NiloToon/[GameObject] Convert Selected GameObjects to NiloToon", priority = 1100 + 1)]
|
||||||
public static void SetupSelectedCharacterGameObject()
|
public static void SetupSelectedCharacterGameObject()
|
||||||
{
|
{
|
||||||
var allselectedObjects = Selection.objects;
|
var allselectedObjects = Selection.objects;
|
||||||
@ -394,7 +403,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Window/NiloToonURP/Convert selected GameObjects to NiloToon", priority = 1, validate = true)]
|
[MenuItem("Window/NiloToonURP/[GameObject] Convert Selected GameObjects to NiloToon", priority = 1, validate = true)]
|
||||||
|
[MenuItem("Assets/NiloToon/[GameObject] Convert Selected GameObjects to NiloToon", priority = 1100 + 1, validate = true)]
|
||||||
public static bool ValidateSetupSelectedCharacterGameObject()
|
public static bool ValidateSetupSelectedCharacterGameObject()
|
||||||
{
|
{
|
||||||
var allselectedObjects = Selection.objects;
|
var allselectedObjects = Selection.objects;
|
||||||
|
|||||||
@ -108,6 +108,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [It seems that we can't strip a local keyword based on local keyword..?]
|
||||||
// In Unity2021.3's build, this section will incorrectly strip some keyword(e.g. _MATCAP_ADD _MATCAP_BLEND _RAMP_LIGHTING_SAMPLE_UVY_TEX _SKIN_MASK_ON _SPECULARHIGHLIGHTS),
|
// In Unity2021.3's build, this section will incorrectly strip some keyword(e.g. _MATCAP_ADD _MATCAP_BLEND _RAMP_LIGHTING_SAMPLE_UVY_TEX _SKIN_MASK_ON _SPECULARHIGHLIGHTS),
|
||||||
// we now disable this section for "Unity 2021.3 or later" temporary until bug is fixed.
|
// we now disable this section for "Unity 2021.3 or later" temporary until bug is fixed.
|
||||||
/*
|
/*
|
||||||
@ -242,7 +243,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use targetResultSetting to add keywords that we want to strip to our ignore list
|
// use targetResultSetting to add keywords that we want to strip to our ignore list
|
||||||
private static List<ShaderKeyword> GetStripKeywordList(Shader shader, NiloToonShaderStrippingSettingSO.Settings targetResultSetting)
|
private static List<ShaderKeyword> GetStripKeywordList(Shader shader,
|
||||||
|
NiloToonShaderStrippingSettingSO.Settings targetResultSetting)
|
||||||
{
|
{
|
||||||
List<ShaderKeyword> haveToStripList = new List<ShaderKeyword>();
|
List<ShaderKeyword> haveToStripList = new List<ShaderKeyword>();
|
||||||
|
|
||||||
@ -251,10 +253,12 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_DEBUG_SHADING"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_DEBUG_SHADING"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_FORCE_MINIMUM_SHADER)
|
if (!targetResultSetting.include_NILOTOON_FORCE_MINIMUM_SHADER)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_FORCE_MINIMUM_SHADER"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_FORCE_MINIMUM_SHADER"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE)
|
if (!targetResultSetting.include_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE"));
|
||||||
@ -264,10 +268,12 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE_V2"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE_V2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_RECEIVE_URP_SHADOWMAPPING)
|
if (!targetResultSetting.include_NILOTOON_RECEIVE_URP_SHADOWMAPPING)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_RECEIVE_URP_SHADOWMAPPING"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_RECEIVE_URP_SHADOWMAPPING"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_RECEIVE_SELF_SHADOW)
|
if (!targetResultSetting.include_NILOTOON_RECEIVE_SELF_SHADOW)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword("_NILOTOON_RECEIVE_SELF_SHADOW"));
|
haveToStripList.Add(new ShaderKeyword("_NILOTOON_RECEIVE_SELF_SHADOW"));
|
||||||
@ -298,15 +304,58 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_DITHER_FADEOUT"));
|
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_DITHER_FADEOUT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_DISSOLVE)
|
if (!targetResultSetting.include_NILOTOON_DISSOLVE)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_DISSOLVE"));
|
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_DISSOLVE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetResultSetting.include_NILOTOON_PERCHARACTER_BASEMAP_OVERRIDE)
|
if (!targetResultSetting.include_NILOTOON_PERCHARACTER_BASEMAP_OVERRIDE)
|
||||||
{
|
{
|
||||||
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_PERCHARACTER_BASEMAP_OVERRIDE"));
|
haveToStripList.Add(new ShaderKeyword(shader, "_NILOTOON_PERCHARACTER_BASEMAP_OVERRIDE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// [strip Fog]
|
||||||
|
// https://docs.unity3d.com/6000.2/Documentation/Manual/urp/shader-stripping-fog.html
|
||||||
|
// We forced dynamic_branch for fog in NiloToonCharacter.shader for Unity6.1 or higher, so no need to strip them now.
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "FOG_EXP"));
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "FOG_EXP2"));
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "FOG_LINEAR"));
|
||||||
|
|
||||||
|
// [strip XR]
|
||||||
|
// By default, Unity adds this set of keywords to all graphics shader programs:
|
||||||
|
// - STEREO_INSTANCING_ON
|
||||||
|
// - STEREO_MULTIVIEW_ON
|
||||||
|
// - STEREO_CUBEMAP_RENDER_ON
|
||||||
|
// - UNITY_SINGLE_PASS_STEREO
|
||||||
|
// we by default strip these keywords since most user are not using NiloToon for XR.
|
||||||
|
// XR user should enable these keyword manually
|
||||||
|
// https://docs.unity3d.com/6000.2/Documentation/Manual/shader-keywords-default.html
|
||||||
|
if (!targetResultSetting.include_STEREO_INSTANCING_ON)
|
||||||
|
{
|
||||||
|
haveToStripList.Add(new ShaderKeyword(shader, "STEREO_INSTANCING_ON")); // safe to strip
|
||||||
|
}
|
||||||
|
if (!targetResultSetting.include_STEREO_MULTIVIEW_ON)
|
||||||
|
{
|
||||||
|
haveToStripList.Add(new ShaderKeyword(shader, "STEREO_MULTIVIEW_ON")); // safe to strip
|
||||||
|
}
|
||||||
|
if (!targetResultSetting.include_STEREO_CUBEMAP_RENDER_ON)
|
||||||
|
{
|
||||||
|
haveToStripList.Add(new ShaderKeyword(shader, "STEREO_CUBEMAP_RENDER_ON")); // safe to strip
|
||||||
|
}
|
||||||
|
if (!targetResultSetting.include_UNITY_SINGLE_PASS_STEREO)
|
||||||
|
{
|
||||||
|
haveToStripList.Add(new ShaderKeyword(shader, "UNITY_SINGLE_PASS_STEREO")); // safe to strip
|
||||||
|
}
|
||||||
|
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "_RECEIVE_URP_SHADOW")); // confirm not safe to strip a local material keyword
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "_SCREENSPACE_OUTLINE")); // confirm not safe to strip a local material keyword
|
||||||
|
|
||||||
|
// [URP multi_compile]
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "_MAIN_LIGHT_SHADOWS_CASCADE")); // safe to strip?
|
||||||
|
//haveToStripList.Add(new ShaderKeyword(shader, "...")); // there are a lot of other keyword
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
return haveToStripList;
|
return haveToStripList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
using System.Collections.Generic;
|
// using System.Collections.Generic;
|
||||||
using System.IO;
|
// using System.IO;
|
||||||
using UnityEditor;
|
// using UnityEditor;
|
||||||
using UnityEditor.Build;
|
// using UnityEditor.Build;
|
||||||
using UnityEditor.Build.Reporting;
|
// using UnityEditor.Build.Reporting;
|
||||||
using UnityEngine;
|
// using UnityEngine;
|
||||||
|
|
||||||
namespace LWGUI
|
namespace LWGUI
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
/// <summary>
|
||||||
|
/// Used to exclude textures referenced by ImageDrawer in Build
|
||||||
|
/// </summary>
|
||||||
public class ExcludeFromBuild : IPreprocessBuildWithReport, IPostprocessBuildWithReport
|
public class ExcludeFromBuild : IPreprocessBuildWithReport, IPostprocessBuildWithReport
|
||||||
{
|
{
|
||||||
public static List<string> excludeAssetPaths = new List<string>();
|
public static List<string> excludeAssetPaths = new List<string>();
|
||||||
@ -106,4 +110,5 @@ namespace LWGUI
|
|||||||
OutputLogs();
|
OutputLogs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
@ -6,6 +6,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace LWGUI
|
namespace LWGUI
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to listen for Shader updates and flush the LWGUI caches
|
||||||
|
/// </summary>
|
||||||
public class ShaderModifyListener : AssetPostprocessor
|
public class ShaderModifyListener : AssetPostprocessor
|
||||||
{
|
{
|
||||||
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
|
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
|
||||||
@ -15,7 +15,8 @@ namespace LWGUI.CustomGUISample
|
|||||||
[InitializeOnLoadMethod]
|
[InitializeOnLoadMethod]
|
||||||
private static void RegisterEvent()
|
private static void RegisterEvent()
|
||||||
{
|
{
|
||||||
LWGUI.onDrawCustomFooter += DoCustomFooter;
|
// Register Event
|
||||||
|
// LWGUI.onDrawCustomFooter += DoCustomFooter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,7 +15,8 @@ namespace LWGUI.CustomGUISample
|
|||||||
[InitializeOnLoadMethod]
|
[InitializeOnLoadMethod]
|
||||||
private static void RegisterEvent()
|
private static void RegisterEvent()
|
||||||
{
|
{
|
||||||
LWGUI.onDrawCustomHeader += DoCustomHeader;
|
// Register Event
|
||||||
|
// LWGUI.onDrawCustomHeader += DoCustomHeader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace LWGUI
|
||||||
|
{
|
||||||
|
public static class CustomMaterialAssetFinder
|
||||||
|
{
|
||||||
|
public static Material FindMaterialAssetInRendererByMaterialInstance(Renderer renderer, Material materialInstance)
|
||||||
|
{
|
||||||
|
Material materialAsset = null;
|
||||||
|
|
||||||
|
// Find the material asset by name
|
||||||
|
// if (materialAsset == null)
|
||||||
|
// {
|
||||||
|
// var name = materialInstance.name.Replace(" (Instance)", "");
|
||||||
|
// var guids = AssetDatabase.FindAssets("t:Material " + name, new[] { "Assets" }).Select(guid =>
|
||||||
|
// {
|
||||||
|
// var assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||||
|
// if (string.IsNullOrEmpty(assetPath) || !assetPath.EndsWith(".mat"))
|
||||||
|
// return null;
|
||||||
|
// else
|
||||||
|
// return guid;
|
||||||
|
// }).ToArray();
|
||||||
|
//
|
||||||
|
// if (guids != null && guids.Length > 0)
|
||||||
|
// {
|
||||||
|
// var matPath = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||||
|
// Selection.activeObject = AssetDatabase.LoadAssetAtPath<Material>(matPath);
|
||||||
|
//
|
||||||
|
// if (guids.Length > 1)
|
||||||
|
// {
|
||||||
|
// Debug.LogWarning($"LWGUI: Multiple materials with the same name were found, and the first one was selected: { matPath }");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return materialAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
private static void RegisterEvent()
|
||||||
|
{
|
||||||
|
// Register Event
|
||||||
|
// Helper.onFindMaterialAssetInRendererByMaterialInstance = FindMaterialAssetInRendererByMaterialInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d476ea1a49c64eb4a29bca60d1e97c01
|
||||||
|
timeCreated: 1732872239
|
||||||
@ -177,57 +177,22 @@ namespace LWGUI
|
|||||||
// Tips: Use properties to fix null reference errors
|
// Tips: Use properties to fix null reference errors
|
||||||
|
|
||||||
private static GUIStyle _guiStyles_IconButton;
|
private static GUIStyle _guiStyles_IconButton;
|
||||||
|
public static GUIStyle guiStyles_IconButton => _guiStyles_IconButton ?? new GUIStyle(EditorStyles.iconButton) { fixedHeight = 0, fixedWidth = 0 };
|
||||||
public static GUIStyle guiStyles_IconButton
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_guiStyles_IconButton == null)
|
|
||||||
{
|
|
||||||
_guiStyles_IconButton = new GUIStyle(EditorStyles.iconButton) { fixedHeight = 0, fixedWidth = 0 };
|
|
||||||
}
|
|
||||||
return _guiStyles_IconButton;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GUIStyle _guiStyle_Foldout;
|
private static GUIStyle _guiStyle_Foldout;
|
||||||
|
public static GUIStyle guiStyle_Foldout => _guiStyle_Foldout ?? new GUIStyle(EditorStyles.miniButton)
|
||||||
public static GUIStyle guiStyle_Foldout
|
|
||||||
{
|
{
|
||||||
get
|
contentOffset = new Vector2(22, 0),
|
||||||
{
|
fixedHeight = 27,
|
||||||
if (_guiStyle_Foldout == null)
|
alignment = TextAnchor.MiddleLeft,
|
||||||
{
|
font = EditorStyles.boldLabel.font,
|
||||||
_guiStyle_Foldout =
|
fontSize = EditorStyles.boldLabel.fontSize + 1
|
||||||
new GUIStyle(EditorStyles.miniButton)
|
};
|
||||||
{
|
|
||||||
contentOffset = new Vector2(22, 0),
|
|
||||||
fixedHeight = 27,
|
|
||||||
alignment = TextAnchor.MiddleLeft,
|
|
||||||
font = EditorStyles.boldLabel.font,
|
|
||||||
fontSize = EditorStyles.boldLabel.fontSize + 1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return _guiStyle_Foldout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GUIStyle _guiStyle_Helpbox;
|
private static GUIStyle _guiStyle_Helpbox;
|
||||||
|
public static GUIStyle guiStyle_Helpbox => _guiStyle_Helpbox ?? new GUIStyle(EditorStyles.helpBox) { fontSize = 12 };
|
||||||
public static GUIStyle guiStyle_Helpbox
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_guiStyle_Helpbox == null)
|
|
||||||
{
|
|
||||||
_guiStyle_Helpbox = new GUIStyle(EditorStyles.helpBox) { fontSize = 12 };
|
|
||||||
}
|
|
||||||
return _guiStyle_Helpbox;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GUIStyle _guiStyles_ToolbarSearchTextFieldPopup;
|
private static GUIStyle _guiStyles_ToolbarSearchTextFieldPopup;
|
||||||
|
|
||||||
public static GUIStyle guiStyles_ToolbarSearchTextFieldPopup
|
public static GUIStyle guiStyles_ToolbarSearchTextFieldPopup
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -359,8 +324,10 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Texture _logo = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("26b9d845eb7b1a747bf04dc84e5bcc2c"));
|
private static Texture _logoCache;
|
||||||
private static GUIContent _logoGuiContent = new GUIContent(string.Empty, _logo,
|
private static GUIContent _logoGuiContentCache;
|
||||||
|
private static Texture _logo => _logoCache = _logoCache ?? AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("26b9d845eb7b1a747bf04dc84e5bcc2c"));
|
||||||
|
private static GUIContent _logoGuiContent => _logoGuiContentCache = _logoGuiContentCache ?? new GUIContent(string.Empty, _logo,
|
||||||
"LWGUI (Light Weight Shader GUI)\n\n"
|
"LWGUI (Light Weight Shader GUI)\n\n"
|
||||||
+ "A Lightweight, Flexible, Powerful Unity Shader GUI system.\n\n"
|
+ "A Lightweight, Flexible, Powerful Unity Shader GUI system.\n\n"
|
||||||
+ "Copyright (c) Jason Ma");
|
+ "Copyright (c) Jason Ma");
|
||||||
@ -386,23 +353,38 @@ namespace LWGUI
|
|||||||
private static Material _copiedMaterial;
|
private static Material _copiedMaterial;
|
||||||
private static List<string> _copiedProps = new List<string>();
|
private static List<string> _copiedProps = new List<string>();
|
||||||
|
|
||||||
private static Texture _iconCopy = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("9cdef444d18d2ce4abb6bbc4fed4d109"));
|
private const string _iconCopyGUID = "9cdef444d18d2ce4abb6bbc4fed4d109";
|
||||||
private static Texture _iconPaste = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("8e7a78d02e4c3574998524a0842a8ccb"));
|
private const string _iconPasteGUID = "8e7a78d02e4c3574998524a0842a8ccb";
|
||||||
private static Texture _iconSelect = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("6f44e40b24300974eb607293e4224ecc"));
|
private const string _iconSelectGUID = "6f44e40b24300974eb607293e4224ecc";
|
||||||
private static Texture _iconCheckout = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("72488141525eaa8499e65e52755cb6d0"));
|
private const string _iconCheckoutGUID = "72488141525eaa8499e65e52755cb6d0";
|
||||||
private static Texture _iconExpand = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("2382450e7f4ddb94c9180d6634c41378"));
|
private const string _iconExpandGUID = "2382450e7f4ddb94c9180d6634c41378";
|
||||||
private static Texture _iconCollapse = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("929b6e5dfacc42b429d715a3e1ca2b57"));
|
private const string _iconCollapseGUID = "929b6e5dfacc42b429d715a3e1ca2b57";
|
||||||
private static Texture _iconVisibility = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("9576e23a695b35d49a9fc55c9a948b4f"));
|
private const string _iconVisibilityGUID = "9576e23a695b35d49a9fc55c9a948b4f";
|
||||||
|
|
||||||
private static GUIContent _guiContentCopy = new GUIContent("", _iconCopy, "Copy Material Properties");
|
private const string _iconCopyTooltip = "Copy Material Properties";
|
||||||
private static GUIContent _guiContentPaste = new GUIContent("", _iconPaste, "Paste Material Properties\n\nRight-click to paste values by type.");
|
private const string _iconPasteTooltip = "Paste Material Properties\n\nRight-click to paste values by type.";
|
||||||
private static GUIContent _guiContentSelect = new GUIContent("", _iconSelect, "Select the Material Asset\n\nUsed to jump from a Runtime Material Instance to a Material Asset.");
|
private const string _iconSelectTooltip = "Select the Material Asset\n\nUsed to jump from a Runtime Material Instance to a Material Asset.";
|
||||||
private static GUIContent _guiContentChechout = new GUIContent("", _iconCheckout, "Checkout selected Material Assets");
|
private const string _iconCheckoutTooltip = "Checkout selected Material Assets";
|
||||||
private static GUIContent _guiContentExpand = new GUIContent("", _iconExpand, "Expand All Groups");
|
private const string _iconExpandTooltip = "Expand All Groups";
|
||||||
private static GUIContent _guiContentCollapse = new GUIContent("", _iconCollapse, "Collapse All Groups");
|
private const string _iconCollapseTooltip = "Collapse All Groups";
|
||||||
private static GUIContent _guiContentVisibility = new GUIContent("", _iconVisibility, "Display Mode");
|
private const string _iconVisibilityTooltip = "Display Mode";
|
||||||
|
|
||||||
|
private static GUIContent _guiContentCopyCache;
|
||||||
|
private static GUIContent _guiContentPasteCache;
|
||||||
|
private static GUIContent _guiContentSelectCache;
|
||||||
|
private static GUIContent _guiContentChechoutCache;
|
||||||
|
private static GUIContent _guiContentExpandCache;
|
||||||
|
private static GUIContent _guiContentCollapseCache;
|
||||||
|
private static GUIContent _guiContentVisibilityCache;
|
||||||
|
|
||||||
|
private static GUIContent _guiContentCopy => _guiContentCopyCache = _guiContentCopyCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconCopyGUID)), _iconCopyTooltip);
|
||||||
|
private static GUIContent _guiContentPaste => _guiContentPasteCache = _guiContentPasteCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconPasteGUID)), _iconPasteTooltip);
|
||||||
|
private static GUIContent _guiContentSelect => _guiContentSelectCache = _guiContentSelectCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconSelectGUID)), _iconSelectTooltip);
|
||||||
|
private static GUIContent _guiContentChechout => _guiContentChechoutCache = _guiContentChechoutCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconCheckoutGUID)), _iconCheckoutTooltip);
|
||||||
|
private static GUIContent _guiContentExpand => _guiContentExpandCache = _guiContentExpandCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconExpandGUID)), _iconExpandTooltip);
|
||||||
|
private static GUIContent _guiContentCollapse => _guiContentCollapseCache = _guiContentCollapseCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconCollapseGUID)), _iconCollapseTooltip);
|
||||||
|
private static GUIContent _guiContentVisibility => _guiContentVisibilityCache = _guiContentVisibilityCache ?? new GUIContent("", AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(_iconVisibilityGUID)), _iconVisibilityTooltip);
|
||||||
|
|
||||||
private static string[] _materialInstanceNameEnd = new[] { "_Instantiated (Instance)", " (Instance)", "_Instantiated" };
|
|
||||||
|
|
||||||
private enum CopyMaterialValueMask
|
private enum CopyMaterialValueMask
|
||||||
{
|
{
|
||||||
@ -547,44 +529,9 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Get Material Asset name
|
if (FindMaterialAssetByMaterialInstance(material, metaDatas, out var materialAsset))
|
||||||
var name = material.name;
|
|
||||||
foreach (var nameEnd in _materialInstanceNameEnd)
|
|
||||||
{
|
{
|
||||||
if (name.EndsWith(nameEnd))
|
Selection.activeObject = materialAsset;
|
||||||
{
|
|
||||||
name = name.Substring(0, name.Length - nameEnd.Length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get path
|
|
||||||
var guids = AssetDatabase.FindAssets("t:Material " + name);
|
|
||||||
var paths = guids.Select(((guid, i) =>
|
|
||||||
{
|
|
||||||
var filePath = AssetDatabase.GUIDToAssetPath(guid);
|
|
||||||
var fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
|
|
||||||
return (fileName == name && filePath.EndsWith(".mat")) ? filePath : null;
|
|
||||||
})).Where((s => !string.IsNullOrEmpty(s))).ToArray();
|
|
||||||
|
|
||||||
// Select Asset
|
|
||||||
if (paths.Length == 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("LWGUI: Can not find Material Assets with name: " + name);
|
|
||||||
}
|
|
||||||
else if (paths.Length > 1)
|
|
||||||
{
|
|
||||||
var str = string.Empty;
|
|
||||||
foreach (string path in paths)
|
|
||||||
{
|
|
||||||
str += "\n" + path;
|
|
||||||
}
|
|
||||||
Debug.LogWarning("LWGUI: Multiple Material Assets with the same name have been found, select only the first one:" + str);
|
|
||||||
Selection.activeObject = AssetDatabase.LoadAssetAtPath<Material>(paths[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Selection.activeObject = AssetDatabase.LoadAssetAtPath<Material>(paths[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -631,16 +578,16 @@ namespace LWGUI
|
|||||||
if (GUI.Button(buttonRect, _guiContentVisibility, Helper.guiStyles_IconButton))
|
if (GUI.Button(buttonRect, _guiContentVisibility, Helper.guiStyles_IconButton))
|
||||||
{
|
{
|
||||||
// Build Display Mode Menu Items
|
// Build Display Mode Menu Items
|
||||||
string[] displayModeMenus = new[]
|
var displayModeMenus = new[]
|
||||||
{
|
{
|
||||||
"Show All Advanced Properties (" + displayModeData.advancedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
"Show All Advanced Properties (" + displayModeData.advancedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
||||||
"Show All Hidden Properties (" + displayModeData.hiddenCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
"Show All Hidden Properties (" + displayModeData.hiddenCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
||||||
"Show Only Modified Properties (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
"Show Only Modified Properties (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
||||||
"Show Only Modified Properties by Group (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
"Show Only Modified Properties by Group (" + perMaterialData.modifiedCount + " of " + perShaderData.propStaticDatas.Count + ")",
|
||||||
};
|
};
|
||||||
bool[] enabled = new[] { true, true, true, true };
|
var enabled = new[] { true, true, true, true };
|
||||||
bool[] separator = new bool[4];
|
var separator = new bool[4];
|
||||||
int[] selected = new[]
|
var selected = new[]
|
||||||
{
|
{
|
||||||
displayModeData.showAllAdvancedProperties ? 0 : -1,
|
displayModeData.showAllAdvancedProperties ? 0 : -1,
|
||||||
displayModeData.showAllHiddenProperties ? 1 : -1,
|
displayModeData.showAllHiddenProperties ? 1 : -1,
|
||||||
@ -682,20 +629,46 @@ namespace LWGUI
|
|||||||
toolBarRect.xMin += 2;
|
toolBarRect.xMin += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Func<Renderer, Material, Material> onFindMaterialAssetInRendererByMaterialInstance;
|
||||||
|
|
||||||
|
private static bool FindMaterialAssetByMaterialInstance(Material material, LWGUIMetaDatas metaDatas, out Material materialAsset)
|
||||||
|
{
|
||||||
|
materialAsset = null;
|
||||||
|
|
||||||
|
var renderers = metaDatas.perInspectorData.materialEditor.GetMeshRenderersByMaterialEditor();
|
||||||
|
foreach (var renderer in renderers)
|
||||||
|
{
|
||||||
|
if (onFindMaterialAssetInRendererByMaterialInstance != null)
|
||||||
|
{
|
||||||
|
materialAsset = onFindMaterialAssetInRendererByMaterialInstance(renderer, material);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materialAsset == null)
|
||||||
|
{
|
||||||
|
int index = renderer.materials.ToList().FindIndex(materialInstance => materialInstance == material);
|
||||||
|
if (index >= 0 && index < renderer.sharedMaterials.Length)
|
||||||
|
{
|
||||||
|
materialAsset = renderer.sharedMaterials[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materialAsset != null && AssetDatabase.Contains(materialAsset))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.LogError("LWGUI: Can not find the Material Assets of: " + material.name);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Search Field
|
#region Search Field
|
||||||
|
|
||||||
private static readonly int s_TextFieldHash = "EditorTextField".GetHashCode();
|
private static readonly int s_TextFieldHash = "EditorTextField".GetHashCode();
|
||||||
private static readonly GUIContent[] _searchModeMenus =
|
private static readonly GUIContent[] _searchModeMenus = Enumerable.Range(0, (int)SearchMode.Num - 1).Select(i =>
|
||||||
(new GUIContent[(int)SearchMode.Num]).Select(((guiContent, i) =>
|
new GUIContent(((SearchMode)i).ToString())).ToArray();
|
||||||
{
|
|
||||||
if (i == (int)SearchMode.Num)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new GUIContent(((SearchMode)i).ToString());
|
|
||||||
})).ToArray();
|
|
||||||
|
|
||||||
/// <returns>is has changed?</returns>
|
/// <returns>is has changed?</returns>
|
||||||
public static bool DrawSearchField(Rect rect, LWGUIMetaDatas metaDatas)
|
public static bool DrawSearchField(Rect rect, LWGUIMetaDatas metaDatas)
|
||||||
@ -926,11 +899,16 @@ namespace LWGUI
|
|||||||
menus.AddSeparator("");
|
menus.AddSeparator("");
|
||||||
foreach (var activePresetData in perMaterialData.activePresetDatas)
|
foreach (var activePresetData in perMaterialData.activePresetDatas)
|
||||||
{
|
{
|
||||||
|
// Cull self
|
||||||
if (activePresetData.property == prop) continue;
|
if (activePresetData.property == prop) continue;
|
||||||
|
|
||||||
var activePreset = activePresetData.preset;
|
var activePreset = activePresetData.preset;
|
||||||
var presetAsset = perShaderData.propStaticDatas[activePresetData.property.name].propertyPresetAsset;
|
var (presetPropStaticData, presetPropDynamicData) = metaDatas.GetPropDatas(activePresetData.property);
|
||||||
var presetPropDisplayName = perShaderData.propStaticDatas[activePresetData.property.name].displayName;
|
var presetAsset = presetPropStaticData.propertyPresetAsset;
|
||||||
|
var presetPropDisplayName = presetPropStaticData.displayName;
|
||||||
|
|
||||||
|
// Cull invisible presets
|
||||||
|
if (!presetPropDynamicData.isShowing) continue;
|
||||||
|
|
||||||
if (activePreset.GetPropertyValue(prop.name) != null)
|
if (activePreset.GetPropertyValue(prop.name) != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -16,6 +16,7 @@ namespace LWGUI
|
|||||||
|
|
||||||
|
|
||||||
#region Get Prop Data
|
#region Get Prop Data
|
||||||
|
|
||||||
public PropertyStaticData GetPropStaticData(string propName) => perShaderData?.GetPropStaticData(propName);
|
public PropertyStaticData GetPropStaticData(string propName) => perShaderData?.GetPropStaticData(propName);
|
||||||
|
|
||||||
public PropertyStaticData GetPropStaticData(MaterialProperty prop) => GetPropStaticData(prop.name);
|
public PropertyStaticData GetPropStaticData(MaterialProperty prop) => GetPropStaticData(prop.name);
|
||||||
@ -27,15 +28,18 @@ namespace LWGUI
|
|||||||
public MaterialProperty GetProperty(string propName) => GetPropDynamicData(propName)?.property;
|
public MaterialProperty GetProperty(string propName) => GetPropDynamicData(propName)?.property;
|
||||||
|
|
||||||
public MaterialProperty GetDefaultProperty(string propName) => GetPropDynamicData(propName)?.defualtProperty;
|
public MaterialProperty GetDefaultProperty(string propName) => GetPropDynamicData(propName)?.defualtProperty;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Get Data Tuple
|
#region Get Data Tuple
|
||||||
|
|
||||||
// var (perShaderData, perMaterialData, perInspectorData) =
|
// var (perShaderData, perMaterialData, perInspectorData) =
|
||||||
public (PerShaderData, PerMaterialData, PerInspectorData) GetDatas() => (perShaderData, perMaterialData, perInspectorData);
|
public (PerShaderData, PerMaterialData, PerInspectorData) GetDatas() => (perShaderData, perMaterialData, perInspectorData);
|
||||||
|
|
||||||
// var (propStaticData, propDynamicData) =
|
// var (propStaticData, propDynamicData) =
|
||||||
public (PropertyStaticData, PropertyDynamicData) GetPropDatas(MaterialProperty prop) =>
|
public (PropertyStaticData, PropertyDynamicData) GetPropDatas(MaterialProperty prop) =>
|
||||||
(GetPropStaticData(prop), GetPropDynamicData(prop));
|
(GetPropStaticData(prop), GetPropDynamicData(prop));
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public MaterialProperty[] GetProps() => perMaterialData.props;
|
public MaterialProperty[] GetProps() => perMaterialData.props;
|
||||||
@ -45,12 +49,6 @@ namespace LWGUI
|
|||||||
public Shader GetShader() => perShaderData.shader;
|
public Shader GetShader() => perShaderData.shader;
|
||||||
|
|
||||||
public MaterialEditor GetMaterialEditor() => perInspectorData.materialEditor;
|
public MaterialEditor GetMaterialEditor() => perInspectorData.materialEditor;
|
||||||
|
|
||||||
public void OnValidate()
|
|
||||||
{
|
|
||||||
MaterialEditor.ApplyMaterialPropertyDrawers(GetMaterialEditor()?.targets);
|
|
||||||
MetaDataHelper.ForceUpdateMaterialsMetadataCache(GetMaterialEditor()?.targets);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MetaDataHelper
|
public class MetaDataHelper
|
||||||
@ -167,24 +165,6 @@ namespace LWGUI
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string _tooltipString = "#";
|
|
||||||
private static readonly string _helpboxString = "%";
|
|
||||||
|
|
||||||
public static string GetPropertyDisplayName(Shader shader, MaterialProperty prop)
|
|
||||||
{
|
|
||||||
var tooltipIndex = prop.displayName.IndexOf(_tooltipString, StringComparison.Ordinal);
|
|
||||||
var helpboxIndex = prop.displayName.IndexOf(_helpboxString, StringComparison.Ordinal);
|
|
||||||
var minIndex = tooltipIndex == -1 ? helpboxIndex : tooltipIndex;
|
|
||||||
if (tooltipIndex != -1 && helpboxIndex != -1)
|
|
||||||
minIndex = Mathf.Min(minIndex, helpboxIndex);
|
|
||||||
if (minIndex == -1)
|
|
||||||
return prop.displayName;
|
|
||||||
else if (minIndex == 0)
|
|
||||||
return string.Empty;
|
|
||||||
else
|
|
||||||
return prop.displayName.Substring(0, minIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool GetPropertyVisibility(MaterialProperty prop, Material material, LWGUIMetaDatas metaDatas)
|
public static bool GetPropertyVisibility(MaterialProperty prop, Material material, LWGUIMetaDatas metaDatas)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
@ -218,16 +198,14 @@ namespace LWGUI
|
|||||||
|
|
||||||
public static bool GetParentPropertyVisibility(PropertyStaticData parentPropStaticData, Material material, LWGUIMetaDatas metaDatas)
|
public static bool GetParentPropertyVisibility(PropertyStaticData parentPropStaticData, Material material, LWGUIMetaDatas metaDatas)
|
||||||
{
|
{
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if (parentPropStaticData != null
|
if (parentPropStaticData != null
|
||||||
&& (!metaDatas.GetPropStaticData(parentPropStaticData.name).isExpanding
|
&& (!metaDatas.GetPropStaticData(parentPropStaticData.name).isExpanding
|
||||||
|| !MetaDataHelper.GetPropertyVisibility(metaDatas.GetProperty(parentPropStaticData.name), material, metaDatas)))
|
|| !GetPropertyVisibility(metaDatas.GetProperty(parentPropStaticData.name), material, metaDatas)))
|
||||||
{
|
{
|
||||||
result = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +45,9 @@ namespace LWGUI
|
|||||||
|
|
||||||
public static ShaderPropertyPreset GetPresetFile(string presetFileName)
|
public static ShaderPropertyPreset GetPresetFile(string presetFileName)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(presetFileName))
|
||||||
|
return null;
|
||||||
|
|
||||||
if (!_loadedPresets.ContainsKey(presetFileName) || !_loadedPresets[presetFileName])
|
if (!_loadedPresets.ContainsKey(presetFileName) || !_loadedPresets[presetFileName])
|
||||||
ForceInit();
|
ForceInit();
|
||||||
|
|
||||||
@ -60,11 +63,10 @@ namespace LWGUI
|
|||||||
// For Developers: Call this after a material has modified in code
|
// For Developers: Call this after a material has modified in code
|
||||||
public static void ApplyPresetsInMaterial(Material material)
|
public static void ApplyPresetsInMaterial(Material material)
|
||||||
{
|
{
|
||||||
var props = MaterialEditor.GetMaterialProperties(new[] { material });
|
var props = MaterialEditor.GetMaterialProperties(new UnityEngine.Object[] { material });
|
||||||
foreach (var prop in props)
|
foreach (var prop in props)
|
||||||
{
|
{
|
||||||
List<MaterialPropertyDrawer> decoratorDrawers;
|
var drawer = ReflectionHelper.GetPropertyDrawer(material.shader, prop, out _);
|
||||||
var drawer = ReflectionHelper.GetPropertyDrawer(material.shader, prop, out decoratorDrawers);
|
|
||||||
|
|
||||||
// Apply active preset
|
// Apply active preset
|
||||||
if (drawer != null && drawer is IBasePresetDrawer)
|
if (drawer != null && drawer is IBasePresetDrawer)
|
||||||
@ -73,9 +75,8 @@ namespace LWGUI
|
|||||||
if (activePreset != null)
|
if (activePreset != null)
|
||||||
activePreset.ApplyToDefaultMaterial(material);
|
activePreset.ApplyToDefaultMaterial(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
MaterialEditor.ApplyMaterialPropertyDrawers(material);
|
UnityEditorExtension.ApplyMaterialPropertyAndDecoratorDrawers(material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,27 +2,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using LWGUI.LwguiGradientEditor;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace LWGUI
|
namespace LWGUI
|
||||||
{
|
{
|
||||||
public class RampHelper
|
public static class RampHelper
|
||||||
{
|
{
|
||||||
#region RampEditor
|
#region RampEditor
|
||||||
|
|
||||||
public static readonly string projectPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
|
public static readonly string projectPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
|
||||||
|
|
||||||
public static string lastSavePath
|
|
||||||
{
|
|
||||||
get { return EditorPrefs.GetString("LWGUI_GradientSavePath_" + Application.version, Application.dataPath); }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value.Contains(projectPath))
|
|
||||||
EditorPrefs.SetString("LWGUI_GradientSavePath_" + Application.version, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly GUIContent _iconAdd = new GUIContent(EditorGUIUtility.IconContent("d_Toolbar Plus").image, "Add"),
|
private static readonly GUIContent _iconAdd = new GUIContent(EditorGUIUtility.IconContent("d_Toolbar Plus").image, "Add"),
|
||||||
_iconEdit = new GUIContent(EditorGUIUtility.IconContent("editicon.sml").image, "Edit"),
|
_iconEdit = new GUIContent(EditorGUIUtility.IconContent("editicon.sml").image, "Edit"),
|
||||||
@ -30,22 +23,27 @@ namespace LWGUI
|
|||||||
_iconSave = new GUIContent(EditorGUIUtility.IconContent("SaveActive").image, "Save");
|
_iconSave = new GUIContent(EditorGUIUtility.IconContent("SaveActive").image, "Save");
|
||||||
|
|
||||||
public static bool RampEditor(
|
public static bool RampEditor(
|
||||||
Rect buttonRect,
|
Rect buttonRect,
|
||||||
MaterialProperty prop,
|
MaterialProperty prop,
|
||||||
SerializedProperty serializedProperty,
|
ref LwguiGradient gradient,
|
||||||
bool isLinear,
|
ColorSpace colorSpace,
|
||||||
bool isDirty,
|
LwguiGradient.ChannelMask viewChannelMask,
|
||||||
string defaultFileName,
|
LwguiGradient.GradientTimeRange timeRange,
|
||||||
string rootPath,
|
bool isDirty,
|
||||||
int defaultWidth,
|
string defaultFileName,
|
||||||
int defaultHeight,
|
string rootPath,
|
||||||
out Texture2D newTexture,
|
int defaultWidth,
|
||||||
out bool doSave,
|
int defaultHeight,
|
||||||
out bool doDiscard)
|
out bool doRegisterUndo,
|
||||||
|
out Texture2D newTexture,
|
||||||
|
out bool doSave,
|
||||||
|
out bool doDiscard
|
||||||
|
)
|
||||||
{
|
{
|
||||||
newTexture = null;
|
newTexture = null;
|
||||||
var hasChange = false;
|
var hasChange = false;
|
||||||
var shouldCreate = false;
|
var shouldCreate = false;
|
||||||
|
var doOpenWindow = false;
|
||||||
var singleButtonWidth = buttonRect.width * 0.25f;
|
var singleButtonWidth = buttonRect.width * 0.25f;
|
||||||
var editRect = new Rect(buttonRect.x + singleButtonWidth * 0, buttonRect.y, singleButtonWidth, buttonRect.height);
|
var editRect = new Rect(buttonRect.x + singleButtonWidth * 0, buttonRect.y, singleButtonWidth, buttonRect.height);
|
||||||
var saveRect = new Rect(buttonRect.x + singleButtonWidth * 1, buttonRect.y, singleButtonWidth, buttonRect.height);
|
var saveRect = new Rect(buttonRect.x + singleButtonWidth * 1, buttonRect.y, singleButtonWidth, buttonRect.height);
|
||||||
@ -53,38 +51,30 @@ namespace LWGUI
|
|||||||
var discardRect = new Rect(buttonRect.x + singleButtonWidth * 3, buttonRect.y, singleButtonWidth, buttonRect.height);
|
var discardRect = new Rect(buttonRect.x + singleButtonWidth * 3, buttonRect.y, singleButtonWidth, buttonRect.height);
|
||||||
|
|
||||||
// Edit button event
|
// Edit button event
|
||||||
var currEvent = Event.current;
|
|
||||||
if (currEvent.type == EventType.MouseDown && editRect.Contains(currEvent.mousePosition))
|
|
||||||
{
|
{
|
||||||
// if the current edited texture is null, create new one
|
|
||||||
if (prop.textureValue == null)
|
|
||||||
{
|
|
||||||
shouldCreate = true;
|
|
||||||
currEvent.Use();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Undo.RecordObject(prop.textureValue, "Edit Gradient");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gradient Editor
|
|
||||||
if (GUI.enabled)
|
|
||||||
{
|
|
||||||
var gradientPropertyRect = new Rect(editRect.x + 2, editRect.y + 2, editRect.width - 2, editRect.height - 2);
|
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
EditorGUI.PropertyField(gradientPropertyRect, serializedProperty, GUIContent.none);
|
LwguiGradientEditorHelper.GradientEditButton(editRect, _iconEdit, gradient, colorSpace, viewChannelMask, timeRange, () =>
|
||||||
|
{
|
||||||
|
// if the current edited texture is null, create new one
|
||||||
|
if (prop.textureValue == null)
|
||||||
|
{
|
||||||
|
shouldCreate = true;
|
||||||
|
Event.current.Use();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doOpenWindow = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (EditorGUI.EndChangeCheck())
|
if (EditorGUI.EndChangeCheck())
|
||||||
{
|
{
|
||||||
hasChange = true;
|
hasChange = true;
|
||||||
|
gradient = LwguiGradientWindow.instance.lwguiGradient;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Edit button overlay
|
doRegisterUndo = doOpenWindow;
|
||||||
if (currEvent.type == EventType.Repaint)
|
|
||||||
{
|
|
||||||
var isHover = editRect.Contains(currEvent.mousePosition);
|
|
||||||
(new GUIStyle("button")).Draw(editRect, _iconEdit, isHover, false, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create button
|
// Create button
|
||||||
@ -101,7 +91,7 @@ namespace LWGUI
|
|||||||
{
|
{
|
||||||
//Create texture and save PNG
|
//Create texture and save PNG
|
||||||
var saveUnityPath = absPath.Replace(projectPath, String.Empty);
|
var saveUnityPath = absPath.Replace(projectPath, String.Empty);
|
||||||
CreateAndSaveNewGradientTexture(defaultWidth, defaultHeight, saveUnityPath, isLinear);
|
CreateAndSaveNewGradientTexture(defaultWidth, defaultHeight, saveUnityPath, colorSpace == ColorSpace.Linear);
|
||||||
// VersionControlHelper.Add(saveUnityPath);
|
// VersionControlHelper.Add(saveUnityPath);
|
||||||
//Load created texture
|
//Load created texture
|
||||||
newTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(saveUnityPath);
|
newTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(saveUnityPath);
|
||||||
@ -120,10 +110,12 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save button
|
// Save button
|
||||||
var color = GUI.color;
|
{
|
||||||
if (isDirty) GUI.color = Color.yellow;
|
var color = GUI.color;
|
||||||
doSave = GUI.Button(saveRect, _iconSave);
|
if (isDirty) GUI.color = Color.yellow;
|
||||||
GUI.color = color;
|
doSave = GUI.Button(saveRect, _iconSave);
|
||||||
|
GUI.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
// Discard button
|
// Discard button
|
||||||
doDiscard = GUI.Button(discardRect, _iconDiscard);
|
doDiscard = GUI.Button(discardRect, _iconDiscard);
|
||||||
@ -133,17 +125,20 @@ namespace LWGUI
|
|||||||
|
|
||||||
public static bool HasGradient(AssetImporter assetImporter) { return assetImporter.userData.Contains("#");}
|
public static bool HasGradient(AssetImporter assetImporter) { return assetImporter.userData.Contains("#");}
|
||||||
|
|
||||||
public static Gradient GetGradientFromTexture(Texture texture, out bool isDirty, bool doReimport = false)
|
public static LwguiGradient GetGradientFromTexture(Texture texture, out bool isDirty, bool doDiscard = false, bool doRegisterUndo = false)
|
||||||
{
|
{
|
||||||
isDirty = false;
|
isDirty = false;
|
||||||
if (texture == null) return null;
|
if (texture == null) return null;
|
||||||
|
|
||||||
var assetImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));
|
var assetImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));
|
||||||
|
if (doRegisterUndo)
|
||||||
|
{
|
||||||
|
LwguiGradientWindow.RegisterRampMapUndo(texture, assetImporter);
|
||||||
|
}
|
||||||
if (assetImporter != null && HasGradient(assetImporter))
|
if (assetImporter != null && HasGradient(assetImporter))
|
||||||
{
|
{
|
||||||
GradientObject savedGradientObject, editingGradientObject;
|
isDirty = DecodeGradientFromJSON(assetImporter.userData, out var savedGradient, out var editingGradient);
|
||||||
isDirty = DecodeGradientFromJSON(assetImporter.userData, out savedGradientObject, out editingGradientObject);
|
var outGradient = doDiscard ? savedGradient : editingGradient;
|
||||||
var outGradient = doReimport ? savedGradientObject.gradient : editingGradientObject.gradient;
|
|
||||||
return outGradient;
|
return outGradient;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -156,25 +151,25 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetGradientToTexture(Texture texture, GradientObject gradientObject, bool doSaveToDisk = false)
|
public static void SetGradientToTexture(Texture texture, LwguiGradient gradient, bool doSaveToDisk = false)
|
||||||
{
|
{
|
||||||
if (texture == null || gradientObject.gradient == null) return;
|
if (texture == null || gradient == null) return;
|
||||||
|
|
||||||
var texture2D = (Texture2D)texture;
|
var texture2D = (Texture2D)texture;
|
||||||
|
var path = AssetDatabase.GetAssetPath(texture);
|
||||||
|
var assetImporter = AssetImporter.GetAtPath(path);
|
||||||
VersionControlHelper.Checkout(texture2D);
|
VersionControlHelper.Checkout(texture2D);
|
||||||
Undo.RecordObject(texture2D, "LWGUI: Set Gradient To Texture");
|
|
||||||
|
LwguiGradientWindow.RegisterRampMapUndo(texture2D, assetImporter);
|
||||||
|
|
||||||
// Save to texture
|
// Save to texture
|
||||||
var path = AssetDatabase.GetAssetPath(texture);
|
var pixels = gradient.GetPixels(texture.width, texture.height);
|
||||||
var pixels = GetPixelsFromGradient(gradientObject.gradient, texture.width, texture.height);
|
texture2D.SetPixels(pixels);
|
||||||
texture2D.SetPixels32(pixels);
|
|
||||||
texture2D.Apply();
|
texture2D.Apply();
|
||||||
|
|
||||||
// Save gradient JSON to userData
|
// Save gradient JSON to userData
|
||||||
var assetImporter = AssetImporter.GetAtPath(path);
|
DecodeGradientFromJSON(assetImporter.userData, out var savedGradient, out _);
|
||||||
GradientObject savedGradientObject, editingGradientObject;
|
assetImporter.userData = EncodeGradientToJSON(doSaveToDisk ? gradient : savedGradient, gradient);
|
||||||
DecodeGradientFromJSON(assetImporter.userData, out savedGradientObject, out editingGradientObject);
|
|
||||||
assetImporter.userData = EncodeGradientToJSON(doSaveToDisk ? gradientObject : savedGradientObject, gradientObject);
|
|
||||||
|
|
||||||
// Save texture to disk
|
// Save texture to disk
|
||||||
if (doSaveToDisk)
|
if (doSaveToDisk)
|
||||||
@ -186,39 +181,52 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string EncodeGradientToJSON(GradientObject savedGradientObject, GradientObject editingGradientObject)
|
private static string EncodeGradientToJSON(LwguiGradient savedGradient, LwguiGradient editingGradient)
|
||||||
{
|
{
|
||||||
string savedJSON = " ", editingJSON = " ";
|
string savedJSON = " ", editingJSON = " ";
|
||||||
if (savedGradientObject != null)
|
if (savedGradient != null)
|
||||||
savedJSON = EditorJsonUtility.ToJson(savedGradientObject);
|
savedJSON = EditorJsonUtility.ToJson(savedGradient);
|
||||||
if (editingGradientObject != null)
|
if (editingGradient != null)
|
||||||
editingJSON = EditorJsonUtility.ToJson(editingGradientObject);
|
editingJSON = EditorJsonUtility.ToJson(editingGradient);
|
||||||
|
|
||||||
return savedJSON + "#" + editingJSON;
|
return savedJSON + "#" + editingJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool DecodeGradientFromJSON(string json, out GradientObject savedGradientObject, out GradientObject editingGradientObject)
|
private static bool DecodeGradientFromJSON(string json, out LwguiGradient savedGradient, out LwguiGradient editingGradient)
|
||||||
{
|
{
|
||||||
|
savedGradient = new LwguiGradient();
|
||||||
|
editingGradient = new LwguiGradient();
|
||||||
|
|
||||||
|
var isLegacyJSON = json.Contains("MonoBehaviour");
|
||||||
var subJSONs = json.Split('#');
|
var subJSONs = json.Split('#');
|
||||||
savedGradientObject = ScriptableObject.CreateInstance<GradientObject>();
|
|
||||||
if (subJSONs[0] != " ")
|
// Upgrading from deprecated GradientObject to LwguiGradient
|
||||||
EditorJsonUtility.FromJsonOverwrite(subJSONs[0], savedGradientObject);
|
if (isLegacyJSON)
|
||||||
editingGradientObject = ScriptableObject.CreateInstance<GradientObject>();
|
{
|
||||||
if (subJSONs[1] != " ")
|
var savedGradientLegacy = ScriptableObject.CreateInstance<GradientObject>();
|
||||||
EditorJsonUtility.FromJsonOverwrite(subJSONs[1], editingGradientObject);
|
var editingGradientLegacy = ScriptableObject.CreateInstance<GradientObject>();
|
||||||
|
|
||||||
|
EditorJsonUtility.FromJsonOverwrite(subJSONs[0], savedGradientLegacy);
|
||||||
|
EditorJsonUtility.FromJsonOverwrite(subJSONs[1], editingGradientLegacy);
|
||||||
|
|
||||||
|
savedGradient = LwguiGradient.FromGradient(savedGradientLegacy.gradient);
|
||||||
|
editingGradient = LwguiGradient.FromGradient(editingGradientLegacy.gradient);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorJsonUtility.FromJsonOverwrite(subJSONs[0], savedGradient);
|
||||||
|
EditorJsonUtility.FromJsonOverwrite(subJSONs[1], editingGradient);
|
||||||
|
}
|
||||||
|
|
||||||
return subJSONs[0] != subJSONs[1];
|
return subJSONs[0] != subJSONs[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CreateAndSaveNewGradientTexture(int width, int height, string unityPath, bool isLinear)
|
public static bool CreateAndSaveNewGradientTexture(int width, int height, string unityPath, bool isLinear)
|
||||||
{
|
{
|
||||||
var gradientObject = ScriptableObject.CreateInstance<GradientObject>();
|
var gradient = new LwguiGradient();
|
||||||
gradientObject.gradient = new Gradient();
|
|
||||||
gradientObject.gradient.colorKeys = new[] { new GradientColorKey(Color.black, 0.0f), new GradientColorKey(Color.white, 1.0f) };
|
|
||||||
gradientObject.gradient.alphaKeys = new[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) };
|
|
||||||
|
|
||||||
var ramp = CreateGradientTexture(gradientObject.gradient, width, height);
|
var ramp = gradient.GetPreviewRampTexture(width, height, ColorSpace.Linear);
|
||||||
var png = ramp.EncodeToPNG();
|
var png = ramp.EncodeToPNG();
|
||||||
Object.DestroyImmediate(ramp);
|
|
||||||
|
|
||||||
var systemPath = projectPath + unityPath;
|
var systemPath = projectPath + unityPath;
|
||||||
File.WriteAllBytes(systemPath, png);
|
File.WriteAllBytes(systemPath, png);
|
||||||
@ -238,44 +246,18 @@ namespace LWGUI
|
|||||||
textureImporter.SetPlatformTextureSettings(platformTextureSettings);
|
textureImporter.SetPlatformTextureSettings(platformTextureSettings);
|
||||||
|
|
||||||
//Gradient data embedded in userData
|
//Gradient data embedded in userData
|
||||||
textureImporter.userData = EncodeGradientToJSON(gradientObject, gradientObject);
|
textureImporter.userData = EncodeGradientToJSON(gradient, gradient);
|
||||||
textureImporter.SaveAndReimport();
|
textureImporter.SaveAndReimport();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Texture2D CreateGradientTexture(Gradient gradient, int width, int height)
|
|
||||||
{
|
|
||||||
var ramp = new Texture2D(width, height, TextureFormat.RGBA32, true, true);
|
|
||||||
var colors = GetPixelsFromGradient(gradient, width, height);
|
|
||||||
ramp.SetPixels32(colors);
|
|
||||||
ramp.Apply();
|
|
||||||
return ramp;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Color32[] GetPixelsFromGradient(Gradient gradient, int width, int height)
|
|
||||||
{
|
|
||||||
var pixels = new Color32[width * height];
|
|
||||||
for (var x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
var delta = x / (float)width;
|
|
||||||
if (delta < 0) delta = 0;
|
|
||||||
if (delta > 1) delta = 1;
|
|
||||||
var col = gradient.Evaluate(delta);
|
|
||||||
for (int i = 0; i < height; i++)
|
|
||||||
{
|
|
||||||
pixels[x + i * width] = col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pixels;
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region RampSelector
|
#region RampSelector
|
||||||
public delegate void SwitchRampMapEvent(Texture2D selectedRamp);
|
|
||||||
|
|
||||||
public static void RampSelector(Rect rect, string rootPath, SwitchRampMapEvent switchRampMapEvent)
|
public static void RampSelector(Rect rect, string rootPath, Action<Texture2D> switchRampMapEvent)
|
||||||
{
|
{
|
||||||
var e = Event.current;
|
var e = Event.current;
|
||||||
if (e.type == UnityEngine.EventType.MouseDown && rect.Contains(e.mousePosition))
|
if (e.type == UnityEngine.EventType.MouseDown && rect.Contains(e.mousePosition))
|
||||||
@ -301,11 +283,11 @@ namespace LWGUI
|
|||||||
|
|
||||||
public class RampSelectorWindow : EditorWindow
|
public class RampSelectorWindow : EditorWindow
|
||||||
{
|
{
|
||||||
private Texture2D[] _rampMaps;
|
private Texture2D[] _rampMaps;
|
||||||
private Vector2 _scrollPosition;
|
private Vector2 _scrollPosition;
|
||||||
private RampHelper.SwitchRampMapEvent _switchRampMapEvent;
|
private Action<Texture2D> _switchRampMapEvent;
|
||||||
|
|
||||||
public static void ShowWindow(Rect rect, Texture2D[] rampMaps, RampHelper.SwitchRampMapEvent switchRampMapEvent)
|
public static void ShowWindow(Rect rect, Texture2D[] rampMaps, Action<Texture2D> switchRampMapEvent)
|
||||||
{
|
{
|
||||||
RampSelectorWindow window = ScriptableObject.CreateInstance<RampSelectorWindow>();
|
RampSelectorWindow window = ScriptableObject.CreateInstance<RampSelectorWindow>();
|
||||||
window.titleContent = new GUIContent("Ramp Selector");
|
window.titleContent = new GUIContent("Ramp Selector");
|
||||||
|
|||||||
@ -1,158 +0,0 @@
|
|||||||
// Copyright (c) Jason Ma
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace LWGUI
|
|
||||||
{
|
|
||||||
public class ReflectionHelper
|
|
||||||
{
|
|
||||||
private static Assembly UnityEditor_Assembly = Assembly.GetAssembly(typeof(Editor));
|
|
||||||
|
|
||||||
|
|
||||||
#region MaterialPropertyHandler
|
|
||||||
|
|
||||||
private static Type MaterialPropertyHandler_Type = UnityEditor_Assembly.GetType("UnityEditor.MaterialPropertyHandler");
|
|
||||||
private static MethodInfo MaterialPropertyHandler_GetHandler_Method = MaterialPropertyHandler_Type.GetMethod("GetHandler", BindingFlags.Static | BindingFlags.NonPublic);
|
|
||||||
private static PropertyInfo MaterialPropertyHandler_PropertyDrawer_Property = MaterialPropertyHandler_Type.GetProperty("propertyDrawer");
|
|
||||||
private static FieldInfo MaterialPropertyHandler_DecoratorDrawers_Field = MaterialPropertyHandler_Type.GetField("m_DecoratorDrawers", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
|
|
||||||
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop, out List<MaterialPropertyDrawer> decoratorDrawers)
|
|
||||||
{
|
|
||||||
decoratorDrawers = new List<MaterialPropertyDrawer>();
|
|
||||||
var handler = MaterialPropertyHandler_GetHandler_Method.Invoke(null, new System.Object[] { shader, prop.name });
|
|
||||||
if (handler != null && handler.GetType() == MaterialPropertyHandler_Type)
|
|
||||||
{
|
|
||||||
decoratorDrawers = MaterialPropertyHandler_DecoratorDrawers_Field.GetValue(handler) as List<MaterialPropertyDrawer>;
|
|
||||||
return MaterialPropertyHandler_PropertyDrawer_Property.GetValue(handler, null) as MaterialPropertyDrawer;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop)
|
|
||||||
{
|
|
||||||
List<MaterialPropertyDrawer> decoratorDrawers;
|
|
||||||
return GetPropertyDrawer(shader, prop, out decoratorDrawers);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region MaterialEditor
|
|
||||||
|
|
||||||
private static Type MaterialEditor_Type = typeof(MaterialEditor);
|
|
||||||
private static MethodInfo MaterialEditor_DoPowerRangeProperty_Method = MaterialEditor_Type.GetMethod("DoPowerRangeProperty", BindingFlags.Static | BindingFlags.NonPublic);
|
|
||||||
private static MethodInfo MaterialEditor_DefaultShaderPropertyInternal_Method = MaterialEditor_Type.GetMethod("DefaultShaderPropertyInternal", BindingFlags.NonPublic | BindingFlags.Instance, null,
|
|
||||||
new[] { typeof(Rect), typeof(MaterialProperty), typeof(GUIContent) }, null);
|
|
||||||
|
|
||||||
public static float DoPowerRangeProperty(Rect position, MaterialProperty prop, GUIContent label, float power)
|
|
||||||
{
|
|
||||||
return (float)MaterialEditor_DoPowerRangeProperty_Method.Invoke(null, new System.Object[] { position, prop, label, power });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DefaultShaderPropertyInternal(MaterialEditor editor, Rect position, MaterialProperty prop, GUIContent label)
|
|
||||||
{
|
|
||||||
MaterialEditor_DefaultShaderPropertyInternal_Method.Invoke(editor, new System.Object[] { position, prop, label });
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region EditorUtility
|
|
||||||
private static Type EditorUtility_Type = typeof(EditorUtility);
|
|
||||||
private static MethodInfo EditorUtility_DisplayCustomMenuWithSeparators_Method = EditorUtility_Type.GetMethod("DisplayCustomMenuWithSeparators", BindingFlags.NonPublic | BindingFlags.Static, null,
|
|
||||||
new []{typeof(Rect), typeof(string[]), typeof(bool[]), typeof(bool[]), typeof(int[]), typeof(EditorUtility.SelectMenuItemFunction), typeof(object), typeof(bool)}, null);
|
|
||||||
|
|
||||||
public static void DisplayCustomMenuWithSeparators(Rect position, string[] options, bool[] enabled, bool[] separator, int[] selected, EditorUtility.SelectMenuItemFunction callback, object userData = null, bool showHotkey = false)
|
|
||||||
{
|
|
||||||
EditorUtility_DisplayCustomMenuWithSeparators_Method.Invoke(null, new System.Object[] { position, options, enabled, separator, selected, callback, userData, showHotkey });
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region EditorGUI
|
|
||||||
|
|
||||||
private static Type EditorGUI_Type = typeof(EditorGUI);
|
|
||||||
private static PropertyInfo EditorGUI_Indent_Property = EditorGUI_Type.GetProperty("indent", BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
|
|
||||||
public static float EditorGUI_Indent { get { return (float)EditorGUI_Indent_Property.GetValue(null, null); } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region EditorGUILayout
|
|
||||||
|
|
||||||
private static Type EditorGUILayout_Type = typeof(EditorGUILayout);
|
|
||||||
private static PropertyInfo EditorGUILayout_kLabelFloatMinW_Property = EditorGUILayout_Type.GetProperty("kLabelFloatMinW", BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
|
|
||||||
public static float EditorGUILayout_kLabelFloatMinW { get { return (float)EditorGUILayout_kLabelFloatMinW_Property.GetValue(null, null); } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region MaterialEnumDrawer
|
|
||||||
|
|
||||||
// UnityEditor.MaterialEnumDrawer(string enumName)
|
|
||||||
private static System.Type[] _types;
|
|
||||||
|
|
||||||
public static System.Type[] GetAllTypes()
|
|
||||||
{
|
|
||||||
if (_types == null)
|
|
||||||
{
|
|
||||||
_types = ((IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies())
|
|
||||||
.SelectMany<Assembly, System.Type>((Func<Assembly, IEnumerable<System.Type>>)
|
|
||||||
(assembly =>
|
|
||||||
{
|
|
||||||
if (assembly == null)
|
|
||||||
return (IEnumerable<System.Type>)(new System.Type[0]);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return (IEnumerable<System.Type>)assembly.GetTypes();
|
|
||||||
}
|
|
||||||
catch (ReflectionTypeLoadException ex)
|
|
||||||
{
|
|
||||||
Debug.LogError(ex);
|
|
||||||
return (IEnumerable<System.Type>)(new System.Type[0]);
|
|
||||||
}
|
|
||||||
})).ToArray<System.Type>();
|
|
||||||
}
|
|
||||||
return _types;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region MaterialProperty.PropertyData
|
|
||||||
|
|
||||||
#if UNITY_2022_1_OR_NEWER
|
|
||||||
private static Type MaterialProperty_Type = typeof(MaterialProperty);
|
|
||||||
private static Type PropertyData_Type = MaterialProperty_Type.GetNestedType("PropertyData", BindingFlags.NonPublic);
|
|
||||||
// MergeStack(out bool lockedInChildren, out bool lockedByAncestor, out bool overriden)
|
|
||||||
private static MethodInfo PropertyData_MergeStack_Method = PropertyData_Type.GetMethod("MergeStack", BindingFlags.Static | BindingFlags.NonPublic);
|
|
||||||
// HandleApplyRevert(GenericMenu menu, bool singleEditing, UnityEngine.Object[] targets)
|
|
||||||
private static MethodInfo PropertyData_HandleApplyRevert_Method = PropertyData_Type.GetMethod("HandleApplyRevert", BindingFlags.Static | BindingFlags.NonPublic);
|
|
||||||
|
|
||||||
public static void HandleApplyRevert(GenericMenu menu, MaterialProperty prop)
|
|
||||||
{
|
|
||||||
System.Object[] parameters = new System.Object[3];
|
|
||||||
ReflectionHelper.PropertyData_MergeStack_Method.Invoke(null, parameters);
|
|
||||||
bool lockedInChildren = (bool)parameters[0];
|
|
||||||
bool lockedByAncestor = (bool)parameters[1];
|
|
||||||
bool overriden = (bool)parameters[2];
|
|
||||||
bool singleEditing = prop.targets.Length == 1;
|
|
||||||
|
|
||||||
if (overriden)
|
|
||||||
{
|
|
||||||
ReflectionHelper.PropertyData_HandleApplyRevert_Method.Invoke(null, new System.Object[]{menu, singleEditing, prop.targets});
|
|
||||||
menu.AddSeparator("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -160,7 +160,8 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Texture _icon = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("e7bc1130858d984488bca32b8512ca96"));
|
private static Texture _iconCache;
|
||||||
|
private static Texture _icon => _iconCache = _iconCache ?? AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath("e7bc1130858d984488bca32b8512ca96"));
|
||||||
|
|
||||||
public static bool DrawRevertButton(Rect rect)
|
public static bool DrawRevertButton(Rect rect)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace LWGUI
|
|||||||
{
|
{
|
||||||
public class VersionControlHelper
|
public class VersionControlHelper
|
||||||
{
|
{
|
||||||
public static bool isVCEnabled { get { return Provider.enabled && Provider.isActive; } }
|
public static bool isVCEnabled => Provider.enabled && Provider.isActive;
|
||||||
|
|
||||||
public static bool Checkout(UnityEngine.Object obj)
|
public static bool Checkout(UnityEngine.Object obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "LWGUI",
|
"name": "LWGUI",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [],
|
"references": [
|
||||||
|
"LWGUI.Runtime",
|
||||||
|
"Unity.InternalAPIEditorBridge.020"
|
||||||
|
],
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
"Editor"
|
"Editor"
|
||||||
],
|
],
|
||||||
|
|||||||
@ -132,10 +132,11 @@ namespace LWGUI
|
|||||||
|
|
||||||
private void DrawAdvancedHeader(PropertyStaticData propStaticData, MaterialProperty prop)
|
private void DrawAdvancedHeader(PropertyStaticData propStaticData, MaterialProperty prop)
|
||||||
{
|
{
|
||||||
|
EditorGUILayout.Space(3);
|
||||||
var rect = EditorGUILayout.GetControlRect();
|
var rect = EditorGUILayout.GetControlRect();
|
||||||
var revertButtonRect = RevertableHelper.SplitRevertButtonRect(ref rect);
|
var revertButtonRect = RevertableHelper.SplitRevertButtonRect(ref rect);
|
||||||
var label = string.IsNullOrEmpty(propStaticData.advancedHeaderString) ? "Advanced" : propStaticData.advancedHeaderString;
|
var label = string.IsNullOrEmpty(propStaticData.advancedHeaderString) ? "Advanced" : propStaticData.advancedHeaderString;
|
||||||
propStaticData.isExpanding = EditorGUI.Foldout(rect, propStaticData.isExpanding, label);
|
propStaticData.isExpanding = EditorGUI.Foldout(rect, propStaticData.isExpanding, label, EditorStyles.foldoutHeader);
|
||||||
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition))
|
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition))
|
||||||
propStaticData.isExpanding = !propStaticData.isExpanding;
|
propStaticData.isExpanding = !propStaticData.isExpanding;
|
||||||
RevertableHelper.DrawRevertableProperty(revertButtonRect, prop, metaDatas, true);
|
RevertableHelper.DrawRevertableProperty(revertButtonRect, prop, metaDatas, true);
|
||||||
@ -147,6 +148,9 @@ namespace LWGUI
|
|||||||
var (propStaticData, propDynamicData) = metaDatas.GetPropDatas(prop);
|
var (propStaticData, propDynamicData) = metaDatas.GetPropDatas(prop);
|
||||||
var materialEditor = metaDatas.GetMaterialEditor();
|
var materialEditor = metaDatas.GetMaterialEditor();
|
||||||
|
|
||||||
|
if (propStaticData.isAdvancedHeaderProperty)
|
||||||
|
EditorGUILayout.Space(3);
|
||||||
|
|
||||||
Helper.DrawHelpbox(propStaticData, propDynamicData);
|
Helper.DrawHelpbox(propStaticData, propDynamicData);
|
||||||
|
|
||||||
var label = new GUIContent(propStaticData.displayName, MetaDataHelper.GetPropertyTooltip(propStaticData, propDynamicData));
|
var label = new GUIContent(propStaticData.displayName, MetaDataHelper.GetPropertyTooltip(propStaticData, propDynamicData));
|
||||||
@ -181,11 +185,32 @@ namespace LWGUI
|
|||||||
MetaDataHelper.ReleaseMaterialMetadataCache(material);
|
MetaDataHelper.ReleaseMaterialMetadataCache(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after editing the material
|
public static void OnValidate(Object[] materials)
|
||||||
|
{
|
||||||
|
UnityEditorExtension.ApplyMaterialPropertyAndDecoratorDrawers(materials);
|
||||||
|
MetaDataHelper.ForceUpdateMaterialsMetadataCache(materials);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called after edit in code
|
||||||
|
public static void OnValidate(LWGUIMetaDatas metaDatas)
|
||||||
|
{
|
||||||
|
OnValidate(metaDatas?.GetMaterialEditor()?.targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called after edit or undo
|
||||||
public override void ValidateMaterial(Material material)
|
public override void ValidateMaterial(Material material)
|
||||||
{
|
{
|
||||||
base.ValidateMaterial(material);
|
base.ValidateMaterial(material);
|
||||||
metaDatas?.OnValidate();
|
// Undo
|
||||||
|
if (metaDatas == null)
|
||||||
|
{
|
||||||
|
OnValidate(new Object[] { material });
|
||||||
|
}
|
||||||
|
// Edit
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnValidate(metaDatas);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} //namespace LWGUI
|
} //namespace LWGUI
|
||||||
@ -62,10 +62,15 @@ namespace LWGUI
|
|||||||
// Get active presets
|
// Get active presets
|
||||||
foreach (var prop in props)
|
foreach (var prop in props)
|
||||||
{
|
{
|
||||||
var activePreset = perShaderData.propStaticDatas[prop.name].presetDrawer
|
var propStaticData = perShaderData.propStaticDatas[prop.name];
|
||||||
?.GetActivePreset(prop, perShaderData.propStaticDatas[prop.name].propertyPresetAsset);
|
var activePreset = propStaticData.presetDrawer?.GetActivePreset(prop, propStaticData.propertyPresetAsset);
|
||||||
if (activePreset != null)
|
if (activePreset != null
|
||||||
|
// Filter invisible preset properties
|
||||||
|
&& (propStaticData.showIfDatas.Count == 0
|
||||||
|
|| ShowIfDecorator.GetShowIfResultFromMaterial(propStaticData.showIfDatas, this.material)))
|
||||||
|
{
|
||||||
activePresetDatas.Add(new PersetDynamicData(activePreset, prop));
|
activePresetDatas.Add(new PersetDynamicData(activePreset, prop));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -85,16 +90,6 @@ namespace LWGUI
|
|||||||
var defaultProperties = MaterialEditor.GetMaterialProperties(new[] { defaultMaterial });
|
var defaultProperties = MaterialEditor.GetMaterialProperties(new[] { defaultMaterial });
|
||||||
Debug.Assert(defaultProperties.Length == props.Length);
|
Debug.Assert(defaultProperties.Length == props.Length);
|
||||||
|
|
||||||
// Override default value
|
|
||||||
for (int i = 0; i < props.Length; i++)
|
|
||||||
{
|
|
||||||
Debug.Assert(props[i].name == defaultProperties[i].name);
|
|
||||||
Debug.Assert(!propDynamicDatas.ContainsKey(props[i].name));
|
|
||||||
|
|
||||||
perShaderData.propStaticDatas[props[i].name].baseDrawers
|
|
||||||
?.ForEach(baseDrawer => baseDrawer.OverrideDefaultValue(shader, props[i], defaultProperties[i], perShaderData));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init propDynamicDatas
|
// Init propDynamicDatas
|
||||||
for (int i = 0; i < props.Length; i++)
|
for (int i = 0; i < props.Length; i++)
|
||||||
{
|
{
|
||||||
@ -132,7 +127,7 @@ namespace LWGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store Show Modified Props Only Cache
|
// Store "Show Modified Props Only" Caches
|
||||||
{
|
{
|
||||||
if (perShaderData.displayModeData.showOnlyModifiedGroups || perShaderData.displayModeData.showOnlyModifiedProperties)
|
if (perShaderData.displayModeData.showOnlyModifiedGroups || perShaderData.displayModeData.showOnlyModifiedProperties)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -31,7 +31,7 @@ namespace LWGUI
|
|||||||
public bool IsDefaultDisplayMode() { return !(showAllAdvancedProperties || showAllHiddenProperties || showOnlyModifiedProperties || showOnlyModifiedGroups); }
|
public bool IsDefaultDisplayMode() { return !(showAllAdvancedProperties || showAllHiddenProperties || showOnlyModifiedProperties || showOnlyModifiedGroups); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PropertyStaticData
|
public partial class PropertyStaticData
|
||||||
{
|
{
|
||||||
public string name = string.Empty;
|
public string name = string.Empty;
|
||||||
public string displayName = string.Empty; // Decoded displayName (Helpbox and Tooltip are encoded in displayName)
|
public string displayName = string.Empty; // Decoded displayName (Helpbox and Tooltip are encoded in displayName)
|
||||||
@ -105,6 +105,7 @@ namespace LWGUI
|
|||||||
propStaticDatas[prop.name] = propStaticData;
|
propStaticDatas[prop.name] = propStaticData;
|
||||||
|
|
||||||
// Get Drawers and Build Drawer StaticMetaData
|
// Get Drawers and Build Drawer StaticMetaData
|
||||||
|
bool hasDecodedStaticMetaData = false;
|
||||||
{
|
{
|
||||||
var drawer = ReflectionHelper.GetPropertyDrawer(shader, prop, out var decoratorDrawers);
|
var drawer = ReflectionHelper.GetPropertyDrawer(shader, prop, out var decoratorDrawers);
|
||||||
|
|
||||||
@ -116,6 +117,7 @@ namespace LWGUI
|
|||||||
{
|
{
|
||||||
propStaticData.baseDrawers = new List<IBaseDrawer>() { baseDrawer };
|
propStaticData.baseDrawers = new List<IBaseDrawer>() { baseDrawer };
|
||||||
baseDrawer.BuildStaticMetaData(shader, prop, props, propStaticData);
|
baseDrawer.BuildStaticMetaData(shader, prop, props, propStaticData);
|
||||||
|
hasDecodedStaticMetaData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoratorDrawers?.ForEach(decoratorDrawer =>
|
decoratorDrawers?.ForEach(decoratorDrawer =>
|
||||||
@ -133,7 +135,8 @@ namespace LWGUI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeMetaDataFromDisplayName(prop, propStaticData);
|
if (!hasDecodedStaticMetaData)
|
||||||
|
DecodeMetaDataFromDisplayName(prop, propStaticData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Data
|
// Check Data
|
||||||
@ -245,7 +248,7 @@ namespace LWGUI
|
|||||||
|
|
||||||
private static readonly string _helpboxSplitter = "%";
|
private static readonly string _helpboxSplitter = "%";
|
||||||
|
|
||||||
public void DecodeMetaDataFromDisplayName(MaterialProperty prop, PropertyStaticData propStaticData)
|
public static void DecodeMetaDataFromDisplayName(MaterialProperty prop, PropertyStaticData propStaticData)
|
||||||
{
|
{
|
||||||
var tooltips = prop.displayName.Split(new String[] { _tooltipSplitter }, StringSplitOptions.None);
|
var tooltips = prop.displayName.Split(new String[] { _tooltipSplitter }, StringSplitOptions.None);
|
||||||
if (tooltips.Length > 1)
|
if (tooltips.Length > 1)
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
// Copyright (c) Jason Ma
|
// Copyright (c) Jason Ma
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace LWGUI
|
namespace LWGUI
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(fileName = "LWGUI_ShaderPropertyPreset.asset", menuName = "LWGUI/Shader Property Preset")]
|
[CreateAssetMenu(fileName = "LWGUI_ShaderPropertyPreset.asset", menuName = "LWGUI/Shader Property Preset", order = 84)]
|
||||||
public class ShaderPropertyPreset : ScriptableObject
|
public class ShaderPropertyPreset : ScriptableObject
|
||||||
{
|
{
|
||||||
public enum PropertyType
|
public enum PropertyType
|
||||||
@ -75,7 +76,7 @@ namespace LWGUI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialEditor.ApplyMaterialPropertyDrawers(material);
|
UnityEditorExtension.ApplyMaterialPropertyAndDecoratorDrawers(material);
|
||||||
}
|
}
|
||||||
// is Property Primary Material
|
// is Property Primary Material
|
||||||
else if (perMaterialData != null)
|
else if (perMaterialData != null)
|
||||||
@ -145,6 +146,8 @@ namespace LWGUI
|
|||||||
public List<PropertyValue> propertyValues = new List<PropertyValue>();
|
public List<PropertyValue> propertyValues = new List<PropertyValue>();
|
||||||
public List<string> enabledKeywords = new List<string>();
|
public List<string> enabledKeywords = new List<string>();
|
||||||
public List<string> disabledKeywords = new List<string>();
|
public List<string> disabledKeywords = new List<string>();
|
||||||
|
public List<string> enabledPasses = new List<string>();
|
||||||
|
public List<string> disabledPasses = new List<string>();
|
||||||
public int renderQueue = -1;
|
public int renderQueue = -1;
|
||||||
|
|
||||||
|
|
||||||
@ -156,11 +159,15 @@ namespace LWGUI
|
|||||||
material.EnableKeyword(enabledKeyword);
|
material.EnableKeyword(enabledKeyword);
|
||||||
foreach (var disabledKeyword in disabledKeywords)
|
foreach (var disabledKeyword in disabledKeywords)
|
||||||
material.DisableKeyword(disabledKeyword);
|
material.DisableKeyword(disabledKeyword);
|
||||||
|
|
||||||
|
Helper.SetShaderPassEnabled(new Object[] { material }, enabledPasses.Select(s => s.ToUpper()).ToArray(), true);
|
||||||
|
Helper.SetShaderPassEnabled(new Object[] { material }, disabledPasses.Select(s => s.ToUpper()).ToArray(), false);
|
||||||
|
|
||||||
if (renderQueue >= 0)
|
if (renderQueue >= 0)
|
||||||
material.renderQueue = renderQueue;
|
material.renderQueue = renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToEditingMaterial(UnityEngine.Object[] materials, PerMaterialData perMaterialData)
|
public void ApplyToEditingMaterial(Object[] materials, PerMaterialData perMaterialData)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < materials.Length; i++)
|
for (int i = 0; i < materials.Length; i++)
|
||||||
{
|
{
|
||||||
@ -171,12 +178,16 @@ namespace LWGUI
|
|||||||
material.EnableKeyword(enabledKeyword);
|
material.EnableKeyword(enabledKeyword);
|
||||||
foreach (var disabledKeyword in disabledKeywords)
|
foreach (var disabledKeyword in disabledKeywords)
|
||||||
material.DisableKeyword(disabledKeyword);
|
material.DisableKeyword(disabledKeyword);
|
||||||
|
|
||||||
if (renderQueue >= 0)
|
if (renderQueue >= 0)
|
||||||
material.renderQueue = renderQueue;
|
material.renderQueue = renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Helper.SetShaderPassEnabled(materials, enabledPasses.Select(s => s.ToUpper()).ToArray(), true);
|
||||||
|
Helper.SetShaderPassEnabled(materials, disabledPasses.Select(s => s.ToUpper()).ToArray(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyKeywordsToMaterials(UnityEngine.Object[] materials)
|
public void ApplyKeywordsAndPassesToMaterials(Object[] materials)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < materials.Length; i++)
|
for (int i = 0; i < materials.Length; i++)
|
||||||
{
|
{
|
||||||
@ -186,6 +197,9 @@ namespace LWGUI
|
|||||||
foreach (var disabledKeyword in disabledKeywords)
|
foreach (var disabledKeyword in disabledKeywords)
|
||||||
material.DisableKeyword(disabledKeyword);
|
material.DisableKeyword(disabledKeyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Helper.SetShaderPassEnabled(materials, enabledPasses.Select(s => s.ToUpper()).ToArray(), true);
|
||||||
|
Helper.SetShaderPassEnabled(materials, disabledPasses.Select(s => s.ToUpper()).ToArray(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyValue GetPropertyValue(string propName)
|
public PropertyValue GetPropertyValue(string propName)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README.md
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README.md
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,9 +1,9 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: b3a047b5aeeebeb409a7ed0856959109
|
guid: 5876caab7dc67af4d8e92317782da76f
|
||||||
TextureImporter:
|
TextureImporter:
|
||||||
internalIDToNameTable: []
|
internalIDToNameTable: []
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 11
|
serializedVersion: 12
|
||||||
mipmaps:
|
mipmaps:
|
||||||
mipMapMode: 0
|
mipMapMode: 0
|
||||||
enableMipMap: 1
|
enableMipMap: 1
|
||||||
@ -20,11 +20,12 @@ TextureImporter:
|
|||||||
externalNormalMap: 0
|
externalNormalMap: 0
|
||||||
heightScale: 0.25
|
heightScale: 0.25
|
||||||
normalMapFilter: 0
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
isReadable: 0
|
isReadable: 0
|
||||||
streamingMipmaps: 0
|
streamingMipmaps: 0
|
||||||
streamingMipmapsPriority: 0
|
streamingMipmapsPriority: 0
|
||||||
vTOnly: 0
|
vTOnly: 0
|
||||||
ignoreMasterTextureLimit: 0
|
ignoreMipmapLimit: 0
|
||||||
grayScaleToAlpha: 0
|
grayScaleToAlpha: 0
|
||||||
generateCubemap: 6
|
generateCubemap: 6
|
||||||
cubemapConvolution: 0
|
cubemapConvolution: 0
|
||||||
@ -34,7 +35,7 @@ TextureImporter:
|
|||||||
textureSettings:
|
textureSettings:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
filterMode: 1
|
filterMode: 1
|
||||||
aniso: 2
|
aniso: 1
|
||||||
mipBias: 0
|
mipBias: 0
|
||||||
wrapU: 0
|
wrapU: 0
|
||||||
wrapV: 0
|
wrapV: 0
|
||||||
@ -63,10 +64,12 @@ TextureImporter:
|
|||||||
textureFormatSet: 0
|
textureFormatSet: 0
|
||||||
ignorePngGamma: 0
|
ignorePngGamma: 0
|
||||||
applyGammaDecoding: 0
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
platformSettings:
|
platformSettings:
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
buildTarget: DefaultTexturePlatform
|
buildTarget: DefaultTexturePlatform
|
||||||
maxTextureSize: 8192
|
maxTextureSize: 2048
|
||||||
resizeAlgorithm: 0
|
resizeAlgorithm: 0
|
||||||
textureFormat: -1
|
textureFormat: -1
|
||||||
textureCompression: 1
|
textureCompression: 1
|
||||||
@ -74,11 +77,12 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
buildTarget: Standalone
|
buildTarget: Standalone
|
||||||
maxTextureSize: 8192
|
maxTextureSize: 2048
|
||||||
resizeAlgorithm: 0
|
resizeAlgorithm: 0
|
||||||
textureFormat: -1
|
textureFormat: -1
|
||||||
textureCompression: 1
|
textureCompression: 1
|
||||||
@ -86,35 +90,12 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
buildTarget: iPhone
|
buildTarget: Server
|
||||||
maxTextureSize: 8192
|
maxTextureSize: 2048
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: Android
|
|
||||||
maxTextureSize: 8192
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: Windows Store Apps
|
|
||||||
maxTextureSize: 8192
|
|
||||||
resizeAlgorithm: 0
|
resizeAlgorithm: 0
|
||||||
textureFormat: -1
|
textureFormat: -1
|
||||||
textureCompression: 1
|
textureCompression: 1
|
||||||
@ -122,6 +103,7 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
spriteSheet:
|
spriteSheet:
|
||||||
@ -138,9 +120,8 @@ TextureImporter:
|
|||||||
weights: []
|
weights: []
|
||||||
secondaryTextures: []
|
secondaryTextures: []
|
||||||
nameFileIdTable: {}
|
nameFileIdTable: {}
|
||||||
spritePackingTag:
|
mipmapLimitGroupName:
|
||||||
pSDRemoveMatte: 0
|
pSDRemoveMatte: 0
|
||||||
pSDShowRemoveMatteOption: 0
|
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
|
|||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240416142736663.png
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240416142736663.png
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240716183800118.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240716183800118.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,127 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d728a6f19010f8747b8ac956860a5089
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240716184045776.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240716184045776.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,127 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 56332e65f9dc7b44f83296f4b88f0f23
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240717104144821.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240717104144821.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,123 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d09eaf1bb9d214040a6cb0d350439f7f
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMasterTextureLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240717104206365.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20240717104206365.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,123 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 43264f7caf023f740b5cc4dd66fa768b
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMasterTextureLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126105823397.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126105823397.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,153 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0b6df23f9d012a74abed6b4f422d9442
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 25
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: iPhone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: VisionOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126110012922.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126110012922.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,153 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc772ea50f72a6e44b0f6190010a6424
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 25
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: iPhone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: VisionOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126112320151.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241126112320151.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,153 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c387c6327985b4f419caee4e22ffbb9b
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 25
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: iPhone
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 1024
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 50
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 1
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: VisionOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241127180711449.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.assets/image-20241127180711449.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
@ -0,0 +1,127 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b307e0433bc4e724180c49d205d9060e
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.md
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/README_CN.md
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,5 +1,6 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: d0ddbd505f5f46444b98a9285b7cdb8a
|
guid: 9c80aad1bb2dd5348bc922988445a5fb
|
||||||
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
3
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LWGUI.Runtime.asmdef
vendored
Normal file
3
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LWGUI.Runtime.asmdef
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"name": "LWGUI.Runtime"
|
||||||
|
}
|
||||||
7
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LWGUI.Runtime.asmdef.meta
vendored
Normal file
7
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LWGUI.Runtime.asmdef.meta
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 959b4969da7632b4e9d4dc209cce9cd6
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
3
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LwguiGradient.meta
vendored
Normal file
3
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LwguiGradient.meta
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 756c9f5a40564b56bc263009a656acba
|
||||||
|
timeCreated: 1720764695
|
||||||
500
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LwguiGradient/LwguiGradient.cs
vendored
Normal file
500
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Runtime/LwguiGradient/LwguiGradient.cs
vendored
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace LWGUI.Runtime.LwguiGradient
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class LwguiGradient : IDisposable
|
||||||
|
{
|
||||||
|
#region Channel Enum
|
||||||
|
|
||||||
|
public enum Channel
|
||||||
|
{
|
||||||
|
Red = 0,
|
||||||
|
Green = 1,
|
||||||
|
Blue = 2,
|
||||||
|
Alpha = 3,
|
||||||
|
Num = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum ChannelMask
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Red = 1 << 0,
|
||||||
|
Green = 1 << 1,
|
||||||
|
Blue = 1 << 2,
|
||||||
|
Alpha = 1 << 3,
|
||||||
|
RGB = Red | Green | Blue,
|
||||||
|
All = RGB | Alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GradientTimeRange
|
||||||
|
{
|
||||||
|
One = 1,
|
||||||
|
TwentyFour = 24,
|
||||||
|
TwentyFourHundred = 2400
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasChannelMask(ChannelMask channelMaskA, ChannelMask channelMaskB) => ((uint)channelMaskA & (uint)channelMaskB) > 0;
|
||||||
|
|
||||||
|
public static bool IsChannelIndexInMask(int channelIndex, ChannelMask channelMask) => ((uint)channelMask & (uint)(1 << channelIndex)) > 0;
|
||||||
|
|
||||||
|
public static ChannelMask ChannelIndexToMask(int channelIndex) => (ChannelMask)(1 << channelIndex);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Const
|
||||||
|
|
||||||
|
public static readonly Color[] channelColors = new[] { Color.red, Color.green, Color.blue, Color.white };
|
||||||
|
public static readonly char[] channelNames = new[] { 'r', 'g', 'b', 'a' };
|
||||||
|
|
||||||
|
public static AnimationCurve defaultCurve => new (new Keyframe(0, 1).SetLinearTangentMode(), new Keyframe(1, 1).SetLinearTangentMode());
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Data
|
||||||
|
|
||||||
|
// The complete data is stored by RGBA Curves and can be converted into Texture
|
||||||
|
[SerializeField] private List<AnimationCurve> _curves;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public LwguiGradient()
|
||||||
|
{
|
||||||
|
_curves = new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
_curves.Add(defaultCurve);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient(LwguiGradient src)
|
||||||
|
{
|
||||||
|
DeepCopyFrom(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient(params Keyframe[] keys)
|
||||||
|
{
|
||||||
|
_curves = new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
_curves.Add(new AnimationCurve());
|
||||||
|
|
||||||
|
if (keys?.Length > 0)
|
||||||
|
{
|
||||||
|
AddKeys(keys, ChannelMask.All);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient(Color[] colors, float[] times)
|
||||||
|
{
|
||||||
|
_curves = new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
_curves.Add(new AnimationCurve());
|
||||||
|
|
||||||
|
if (colors == null || times == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Mathf.Min(colors.Length, times.Length); i++)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
_curves[c].AddKey(new Keyframe(times[i], colors[i][c]).SetLinearTangentMode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetLinearTangentMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient(List<AnimationCurve> inRgbaCurves) => SetRgbaCurves(inRgbaCurves);
|
||||||
|
|
||||||
|
public static LwguiGradient white
|
||||||
|
{
|
||||||
|
get => new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient gray
|
||||||
|
{
|
||||||
|
get => new (new []{Color.gray, Color.gray}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient black
|
||||||
|
{
|
||||||
|
get => new (new []{Color.black, Color.black}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient red
|
||||||
|
{
|
||||||
|
get => new (new []{Color.red, Color.red}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient green
|
||||||
|
{
|
||||||
|
get => new (new []{Color.green, Color.green}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient blue
|
||||||
|
{
|
||||||
|
get => new (new []{Color.blue, Color.blue}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient cyan
|
||||||
|
{
|
||||||
|
get => new (new []{Color.cyan, Color.cyan}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient magenta
|
||||||
|
{
|
||||||
|
get => new (new []{Color.magenta, Color.magenta}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient yellow
|
||||||
|
{
|
||||||
|
get => new (new []{Color.yellow, Color.yellow}, new []{0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public int GetValueBasedHashCode()
|
||||||
|
{
|
||||||
|
var hash = 17;
|
||||||
|
|
||||||
|
if (_curves != null)
|
||||||
|
{
|
||||||
|
foreach (var curve in _curves)
|
||||||
|
{
|
||||||
|
if (curve != null)
|
||||||
|
{
|
||||||
|
hash = hash * 23 + curve.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_curves?.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(ChannelMask channelMask = ChannelMask.All)
|
||||||
|
{
|
||||||
|
_curves ??= new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (!IsChannelIndexInMask(c, channelMask)) continue;
|
||||||
|
|
||||||
|
if (_curves.Count > c) _curves[c].keys = Array.Empty<Keyframe>();
|
||||||
|
else _curves.Add(new AnimationCurve());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeepCopyFrom(LwguiGradient src)
|
||||||
|
{
|
||||||
|
_curves ??= new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (_curves.Count == c)
|
||||||
|
_curves.Add(new AnimationCurve());
|
||||||
|
|
||||||
|
_curves[c].keys = Array.Empty<Keyframe>();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < src._curves.Count; c++)
|
||||||
|
{
|
||||||
|
foreach (var key in src._curves[c].keys)
|
||||||
|
{
|
||||||
|
_curves[c].AddKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurve(AnimationCurve curve, ChannelMask channelMask)
|
||||||
|
{
|
||||||
|
curve ??= defaultCurve;
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (!IsChannelIndexInMask(c, channelMask)) continue;
|
||||||
|
|
||||||
|
_curves[c] = curve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRgbaCurves(List<AnimationCurve> inRgbaCurves)
|
||||||
|
{
|
||||||
|
_curves = new List<AnimationCurve>();
|
||||||
|
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (inRgbaCurves?.Count > c && inRgbaCurves[c]?.keys.Length > 0)
|
||||||
|
{
|
||||||
|
_curves.Add(inRgbaCurves[c]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_curves.Add(defaultCurve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddKey(Keyframe key, ChannelMask channelMask)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (!IsChannelIndexInMask(c, channelMask))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_curves[c].AddKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddKeys(Keyframe[] keys, ChannelMask channelMask)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < keys?.Length; i++)
|
||||||
|
{
|
||||||
|
AddKey(keys[i], channelMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<AnimationCurve> rawCurves
|
||||||
|
{
|
||||||
|
get => _curves;
|
||||||
|
set => SetRgbaCurves(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationCurve redCurve
|
||||||
|
{
|
||||||
|
get => _curves[(int)Channel.Red] ?? defaultCurve;
|
||||||
|
set => SetCurve(value, ChannelMask.Red);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationCurve greenCurve
|
||||||
|
{
|
||||||
|
get => _curves[(int)Channel.Green] ?? defaultCurve;
|
||||||
|
set => SetCurve(value, ChannelMask.Green);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationCurve blueCurve
|
||||||
|
{
|
||||||
|
get => _curves[(int)Channel.Blue] ?? defaultCurve;
|
||||||
|
set => SetCurve(value, ChannelMask.Blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationCurve alphaCurve
|
||||||
|
{
|
||||||
|
get => _curves[(int)Channel.Alpha] ?? defaultCurve;
|
||||||
|
set => SetCurve(value, ChannelMask.Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Color Evaluate(float time, ChannelMask channelMask = ChannelMask.All, GradientTimeRange timeRange = GradientTimeRange.One)
|
||||||
|
{
|
||||||
|
time /= (int)timeRange;
|
||||||
|
|
||||||
|
if (channelMask == ChannelMask.Alpha)
|
||||||
|
{
|
||||||
|
var alpha = _curves[(int)Channel.Alpha].Evaluate(time);
|
||||||
|
return new Color(alpha, alpha, alpha, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Color(
|
||||||
|
IsChannelIndexInMask((int)Channel.Red, channelMask) ? _curves[(int)Channel.Red].Evaluate(time) : 0,
|
||||||
|
IsChannelIndexInMask((int)Channel.Green, channelMask) ? _curves[(int)Channel.Green].Evaluate(time) : 0,
|
||||||
|
IsChannelIndexInMask((int)Channel.Blue, channelMask) ? _curves[(int)Channel.Blue].Evaluate(time) : 0,
|
||||||
|
IsChannelIndexInMask((int)Channel.Alpha, channelMask) ? _curves[(int)Channel.Alpha].Evaluate(time) : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLinearTangentMode()
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
_curves[c].SetLinearTangents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region LwguiGradient <=> Ramp Texture
|
||||||
|
|
||||||
|
public Color[] GetPixels(int width, int height, ChannelMask channelMask = ChannelMask.All)
|
||||||
|
{
|
||||||
|
var pixels = new Color[width * height];
|
||||||
|
for (var x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
var u = x / (float)width;
|
||||||
|
var col = Evaluate(u, channelMask);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
pixels[x + i * width] = col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture2D GetPreviewRampTexture(int width = 256, int height = 1, ColorSpace colorSpace = ColorSpace.Gamma, ChannelMask channelMask = ChannelMask.All)
|
||||||
|
{
|
||||||
|
if (LwguiGradientHelper.TryGetRampPreview(this, width, height, colorSpace, channelMask, out var cachedPreview))
|
||||||
|
return cachedPreview;
|
||||||
|
|
||||||
|
var rampPreview = new Texture2D(width, height, TextureFormat.RGBA32, false, colorSpace == ColorSpace.Linear);
|
||||||
|
var pixels = GetPixels(width, height, channelMask);
|
||||||
|
rampPreview.SetPixels(pixels);
|
||||||
|
rampPreview.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
rampPreview.name = "LWGUI Gradient Preview";
|
||||||
|
rampPreview.Apply();
|
||||||
|
|
||||||
|
LwguiGradientHelper.SetRampPreview(this, width, height, colorSpace, channelMask, rampPreview);
|
||||||
|
return rampPreview;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region LwguiGradient <=> Gradient
|
||||||
|
|
||||||
|
public struct LwguiKeyframe
|
||||||
|
{
|
||||||
|
public float time;
|
||||||
|
public float value;
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
public LwguiKeyframe(float time, float value, int index)
|
||||||
|
{
|
||||||
|
this.time = time;
|
||||||
|
this.value = value;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LwguiMergedColorCurves : IDisposable
|
||||||
|
{
|
||||||
|
public List<List<LwguiKeyframe>> curves = new ();
|
||||||
|
|
||||||
|
public LwguiMergedColorCurves()
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
curves.Add(new List<LwguiKeyframe>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiMergedColorCurves(List<AnimationCurve> rgbaCurves)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
curves.Add(new List<LwguiKeyframe>());
|
||||||
|
|
||||||
|
// Get color keys
|
||||||
|
{
|
||||||
|
var timeColorDic = new Dictionary<float, List<(float value, int index)>>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num - 1; c++)
|
||||||
|
{
|
||||||
|
var keys = rgbaCurves[c].keys;
|
||||||
|
for (int j = 0; j < keys.Length; j++)
|
||||||
|
{
|
||||||
|
var keyframe = keys[j];
|
||||||
|
if (timeColorDic.ContainsKey(keyframe.time))
|
||||||
|
{
|
||||||
|
timeColorDic[keyframe.time].Add((keyframe.value, j));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeColorDic.Add(keyframe.time, new List<(float value, int index)> { (keyframe.value, j) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var kwPair in timeColorDic)
|
||||||
|
{
|
||||||
|
if (kwPair.Value.Count == (int)Channel.Num - 1)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num - 1; c++)
|
||||||
|
{
|
||||||
|
curves[c].Add(new LwguiKeyframe(kwPair.Key, kwPair.Value[c].value, kwPair.Value[c].index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get alpha keys
|
||||||
|
for (int i = 0; i < rgbaCurves[(int)Channel.Alpha].keys.Length; i++)
|
||||||
|
{
|
||||||
|
var alphaKey = rgbaCurves[(int)Channel.Alpha].keys[i];
|
||||||
|
curves[(int)Channel.Alpha].Add(new LwguiKeyframe(alphaKey.time, alphaKey.value, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiMergedColorCurves(Gradient gradient)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
curves.Add(new List<LwguiKeyframe>());
|
||||||
|
|
||||||
|
foreach (var colorKey in gradient.colorKeys)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)Channel.Num - 1; c++)
|
||||||
|
{
|
||||||
|
curves[c].Add(new LwguiKeyframe(colorKey.time, colorKey.color[c], 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var alphaKey in gradient.alphaKeys)
|
||||||
|
{
|
||||||
|
curves[(int)Channel.Alpha].Add(new LwguiKeyframe(alphaKey.time, alphaKey.alpha, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gradient ToGradient(int maxGradientKeyCount = 8) => new Gradient
|
||||||
|
{
|
||||||
|
colorKeys = curves[(int)Channel.Red].Select((keyframe, i) => new GradientColorKey(
|
||||||
|
new Color(
|
||||||
|
curves[(int)Channel.Red][i].value,
|
||||||
|
curves[(int)Channel.Green][i].value,
|
||||||
|
curves[(int)Channel.Blue][i].value),
|
||||||
|
curves[(int)Channel.Red][i].time))
|
||||||
|
.Where((key, i) => i < maxGradientKeyCount).ToArray(),
|
||||||
|
|
||||||
|
alphaKeys = curves[(int)Channel.Alpha].Select(alphaKey => new GradientAlphaKey(alphaKey.value, alphaKey.time))
|
||||||
|
.Where((key, i) => i < maxGradientKeyCount).ToArray()
|
||||||
|
};
|
||||||
|
|
||||||
|
public List<AnimationCurve> ToAnimationCurves()
|
||||||
|
{
|
||||||
|
var outCurves = new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)Channel.Num; c++)
|
||||||
|
{
|
||||||
|
var curve = new AnimationCurve();
|
||||||
|
foreach (var key in curves[c])
|
||||||
|
{
|
||||||
|
curve.AddKey(new Keyframe(key.time, key.value).SetLinearTangentMode());
|
||||||
|
}
|
||||||
|
curve.SetLinearTangents();
|
||||||
|
outCurves.Add(curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outCurves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient ToLwguiGradient()
|
||||||
|
{
|
||||||
|
return new LwguiGradient(ToAnimationCurves());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
curves?.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LwguiGradient FromGradient(Gradient gradient)
|
||||||
|
{
|
||||||
|
return new LwguiMergedColorCurves(gradient).ToLwguiGradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gradient ToGradient(int maxGradientKeyCount = 8)
|
||||||
|
{
|
||||||
|
return new LwguiMergedColorCurves(_curves).ToGradient(maxGradientKeyCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a1c1406f2f784af489fb3758fb334d07
|
||||||
|
timeCreated: 1716793021
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// Disable Keyframe.tangentMode obsolete warning
|
||||||
|
#pragma warning disable 0618
|
||||||
|
|
||||||
|
|
||||||
|
namespace LWGUI.Runtime.LwguiGradient
|
||||||
|
{
|
||||||
|
public static class LwguiGradientHelper
|
||||||
|
{
|
||||||
|
#region Extended Methods
|
||||||
|
|
||||||
|
public static Keyframe SetLinearTangentMode(this Keyframe key)
|
||||||
|
{
|
||||||
|
key.tangentMode = 69;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLinearTangents(this AnimationCurve curve)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < curve.keys.Length; i++)
|
||||||
|
{
|
||||||
|
var keyStart = curve.keys[i - 1];
|
||||||
|
var keyEnd = curve.keys[i];
|
||||||
|
float tangent = (keyEnd.value - keyStart.value) / (keyEnd.time - keyStart.time);
|
||||||
|
keyStart.outTangent = tangent;
|
||||||
|
keyEnd.inTangent = tangent;
|
||||||
|
curve.MoveKey(i - 1, keyStart);
|
||||||
|
curve.MoveKey(i, keyEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DestroyInEditorOrRuntime(this UnityEngine.Object obj)
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Object.DestroyImmediate(obj);
|
||||||
|
#else
|
||||||
|
Object.Destroy(obj);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Ramp Preview Caches
|
||||||
|
|
||||||
|
private static Dictionary<int/* LwguiGradient Value Based Hash */,
|
||||||
|
Dictionary<(int, int, ColorSpace, LwguiGradient.ChannelMask), Texture2D>> _gradientToPreviewDic;
|
||||||
|
|
||||||
|
public static bool TryGetRampPreview(LwguiGradient gradient, int width, int height, ColorSpace colorSpace, LwguiGradient.ChannelMask channelMask,
|
||||||
|
out Texture2D cachedPreview)
|
||||||
|
{
|
||||||
|
cachedPreview = _gradientToPreviewDic?.GetValueOrDefault(gradient.GetValueBasedHashCode())?.GetValueOrDefault((width, height, colorSpace, channelMask));
|
||||||
|
return cachedPreview;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetRampPreview(LwguiGradient gradient, int width, int height, ColorSpace colorSpace, LwguiGradient.ChannelMask channelMask, Texture2D newPreviewTex)
|
||||||
|
{
|
||||||
|
_gradientToPreviewDic ??= new Dictionary<int, Dictionary<(int, int, ColorSpace, LwguiGradient.ChannelMask), Texture2D>>();
|
||||||
|
var hash = gradient.GetValueBasedHashCode();
|
||||||
|
|
||||||
|
if (!_gradientToPreviewDic.ContainsKey(hash))
|
||||||
|
{
|
||||||
|
_gradientToPreviewDic[hash] = new Dictionary<(int, int, ColorSpace, LwguiGradient.ChannelMask), Texture2D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_gradientToPreviewDic[hash].ContainsKey((width, height, colorSpace, channelMask)))
|
||||||
|
{
|
||||||
|
_gradientToPreviewDic[hash][(width, height, colorSpace, channelMask)].DestroyInEditorOrRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
|
_gradientToPreviewDic[hash][(width, height, colorSpace, channelMask)] = newPreviewTex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearRampPreviewCaches()
|
||||||
|
{
|
||||||
|
if (_gradientToPreviewDic == null) return;
|
||||||
|
|
||||||
|
foreach (var paramsToPreviewTexDic in _gradientToPreviewDic.Values)
|
||||||
|
{
|
||||||
|
paramsToPreviewTexDic.Values.ToList().ForEach(previewTex => previewTex.DestroyInEditorOrRuntime());
|
||||||
|
}
|
||||||
|
_gradientToPreviewDic.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dacb09adca6c4f07b8f5fa5acdc7cbfd
|
||||||
|
timeCreated: 1720172986
|
||||||
@ -10,7 +10,7 @@ MonoBehaviour:
|
|||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: 28fbcbca3fb14507af6ed5c104c40b84, type: 3}
|
m_Script: {fileID: 11500000, guid: 28fbcbca3fb14507af6ed5c104c40b84, type: 3}
|
||||||
m_Name: LWGUI_BlendModePreset
|
m_Name: LWGUI_Preset_BlendMode
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
presets:
|
presets:
|
||||||
- presetName: Opaque
|
- presetName: Opaque
|
||||||
29
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/LWGUI_Preset_Toggle.asset
vendored
Normal file
29
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/LWGUI_Preset_Toggle.asset
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 28fbcbca3fb14507af6ed5c104c40b84, type: 3}
|
||||||
|
m_Name: LWGUI_Preset_Toggle
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
presets:
|
||||||
|
- presetName: Disable
|
||||||
|
propertyValues: []
|
||||||
|
enabledKeywords: []
|
||||||
|
disabledKeywords: []
|
||||||
|
enabledPasses: []
|
||||||
|
disabledPasses: []
|
||||||
|
renderQueue: 2000
|
||||||
|
- presetName: Enable
|
||||||
|
propertyValues: []
|
||||||
|
enabledKeywords: []
|
||||||
|
disabledKeywords: []
|
||||||
|
enabledPasses: []
|
||||||
|
disabledPasses: []
|
||||||
|
renderQueue: 2001
|
||||||
8
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/LWGUI_Preset_Toggle.asset.meta
vendored
Normal file
8
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/LWGUI_Preset_Toggle.asset.meta
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c3b3b9433213824419f41452830ee4ea
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -9,16 +9,20 @@ Material:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: LWGUI_SampleDrawer 1
|
m_Name: LWGUI_SampleDrawer 1
|
||||||
m_Shader: {fileID: 4800000, guid: 7ee048c9536c0344bb8b4860595a4d9b, type: 3}
|
m_Shader: {fileID: 4800000, guid: 7ee048c9536c0344bb8b4860595a4d9b, type: 3}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords: []
|
m_ValidKeywords: []
|
||||||
m_InvalidKeywords:
|
m_InvalidKeywords:
|
||||||
- _GROUP_ON
|
- _GROUP_ON
|
||||||
- _KEY2
|
- _KEY2
|
||||||
|
- _KEY3
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 0
|
m_EnableInstancingVariants: 0
|
||||||
m_DoubleSidedGI: 0
|
m_DoubleSidedGI: 0
|
||||||
m_CustomRenderQueue: 3000
|
m_CustomRenderQueue: 3000
|
||||||
stringTagMap: {}
|
stringTagMap: {}
|
||||||
disabledShaderPasses: []
|
disabledShaderPasses: []
|
||||||
|
m_LockedProperties:
|
||||||
m_SavedProperties:
|
m_SavedProperties:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TexEnvs:
|
m_TexEnvs:
|
||||||
|
|||||||
@ -20,12 +20,11 @@ TextureImporter:
|
|||||||
externalNormalMap: 0
|
externalNormalMap: 0
|
||||||
heightScale: 0.25
|
heightScale: 0.25
|
||||||
normalMapFilter: 0
|
normalMapFilter: 0
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 1
|
isReadable: 1
|
||||||
streamingMipmaps: 0
|
streamingMipmaps: 0
|
||||||
streamingMipmapsPriority: 0
|
streamingMipmapsPriority: 0
|
||||||
vTOnly: 0
|
vTOnly: 0
|
||||||
ignoreMipmapLimit: 0
|
ignoreMasterTextureLimit: 0
|
||||||
grayScaleToAlpha: 0
|
grayScaleToAlpha: 0
|
||||||
generateCubemap: 6
|
generateCubemap: 6
|
||||||
cubemapConvolution: 0
|
cubemapConvolution: 0
|
||||||
@ -64,7 +63,6 @@ TextureImporter:
|
|||||||
textureFormatSet: 0
|
textureFormatSet: 0
|
||||||
ignorePngGamma: 0
|
ignorePngGamma: 0
|
||||||
applyGammaDecoding: 0
|
applyGammaDecoding: 0
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
cookieLightType: 0
|
||||||
platformSettings:
|
platformSettings:
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@ -77,7 +75,6 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@ -90,7 +87,6 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@ -103,7 +99,6 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
spriteSheet:
|
spriteSheet:
|
||||||
@ -120,8 +115,9 @@ TextureImporter:
|
|||||||
weights: []
|
weights: []
|
||||||
secondaryTextures: []
|
secondaryTextures: []
|
||||||
nameFileIdTable: {}
|
nameFileIdTable: {}
|
||||||
mipmapLimitGroupName:
|
spritePackingTag:
|
||||||
pSDRemoveMatte: 0
|
pSDRemoveMatte: 0
|
||||||
userData: '{"MonoBehaviour":{"m_Enabled":true,"m_EditorHideFlags":0,"m_Name":"","m_EditorClassIdentifier":"","gradient":{"serializedVersion":"2","key0":{"r":0.0,"g":0.0,"b":0.0,"a":1.0},"key1":{"r":1.0,"g":1.0,"b":1.0,"a":1.0},"key2":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key3":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key4":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key5":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key6":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key7":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"ctime0":0,"ctime1":65535,"ctime2":0,"ctime3":0,"ctime4":0,"ctime5":0,"ctime6":0,"ctime7":0,"atime0":0,"atime1":65535,"atime2":0,"atime3":0,"atime4":0,"atime5":0,"atime6":0,"atime7":0,"m_Mode":0,"m_ColorSpace":1,"m_NumColorKeys":2,"m_NumAlphaKeys":2}}}#{"MonoBehaviour":{"m_Enabled":true,"m_EditorHideFlags":0,"m_Name":"","m_EditorClassIdentifier":"","gradient":{"serializedVersion":"2","key0":{"r":0.0,"g":0.0,"b":0.0,"a":1.0},"key1":{"r":1.0,"g":1.0,"b":1.0,"a":1.0},"key2":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key3":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key4":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key5":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key6":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"key7":{"r":0.0,"g":0.0,"b":0.0,"a":0.0},"ctime0":0,"ctime1":65535,"ctime2":0,"ctime3":0,"ctime4":0,"ctime5":0,"ctime6":0,"ctime7":0,"atime0":0,"atime1":65535,"atime2":0,"atime3":0,"atime4":0,"atime5":0,"atime6":0,"atime7":0,"m_Mode":0,"m_ColorSpace":1,"m_NumColorKeys":2,"m_NumAlphaKeys":2}}}'
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData: '{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}#{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}'
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
|
|||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/RampMap_Test.png
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/RampMap_Test.png
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
127
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/RampMap_Test.png.meta
vendored
Normal file
127
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/Test/RampMap_Test.png.meta
vendored
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1522a7c4f7317044ab912724c1594427
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 1
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: 4
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Server
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData: '{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}#{"_curves":[{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":0.0,"inSlope":0.0,"outSlope":1.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":1.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4},{"serializedVersion":"2","m_Curve":[{"serializedVersion":"3","time":0.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0},{"serializedVersion":"3","time":1.0,"value":1.0,"inSlope":0.0,"outSlope":0.0,"tangentMode":69,"weightedMode":0,"inWeight":0.0,"outWeight":0.0}],"m_PreInfinity":2,"m_PostInfinity":2,"m_RotationOrder":4}]}'
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because one or more lines are too long
@ -12,6 +12,7 @@
|
|||||||
[Main(Group1, _KEYWORD, on)] _group1 ("Group - Default Open", float) = 1
|
[Main(Group1, _KEYWORD, on)] _group1 ("Group - Default Open", float) = 1
|
||||||
[Preset(Group1, LWGUI_ShaderPropertyPreset)] _preset ("Preset Sample", float) = 0
|
[Preset(Group1, LWGUI_ShaderPropertyPreset)] _preset ("Preset Sample", float) = 0
|
||||||
[Preset(Group1, LWGUI_ShaderPropertyPreset1)] _preset1 ("Preset Sample 1", float) = 0
|
[Preset(Group1, LWGUI_ShaderPropertyPreset1)] _preset1 ("Preset Sample 1", float) = 0
|
||||||
|
[SubToggle(Group1, _, LWGUI_Preset_Toggle)] _preset_toggle ("Preset Toggle Sample", float) = 0
|
||||||
[Sub(Group1)] _float1 ("Sub Float", float) = 0
|
[Sub(Group1)] _float1 ("Sub Float", float) = 0
|
||||||
[Sub(Group1)] _vector1 ("Sub Vector", vector) = (1, 1, 1, 1)
|
[Sub(Group1)] _vector1 ("Sub Vector", vector) = (1, 1, 1, 1)
|
||||||
[Sub(Group1)] [HDR] _color1 ("Sub HDR Color", color) = (0.7, 0.7, 1, 1)
|
[Sub(Group1)] [HDR] _color1 ("Sub HDR Color", color) = (0.7, 0.7, 1, 1)
|
||||||
@ -36,7 +37,7 @@
|
|||||||
[Advanced][Tex(Group2, _AdvancedColor0)] _AdvancedTex1 ("Advanced Tex 1", 2D) = "white" { }
|
[Advanced][Tex(Group2, _AdvancedColor0)] _AdvancedTex1 ("Advanced Tex 1", 2D) = "white" { }
|
||||||
[Advanced][HideInInspector] _AdvancedColor0 ("Advanced Color 0", Color) = (1, 1, 1, 1)
|
[Advanced][HideInInspector] _AdvancedColor0 ("Advanced Color 0", Color) = (1, 1, 1, 1)
|
||||||
[AdvancedHeaderProperty][Sub(Group2)] _AdvancedFloat ("Advanced Image", float) = 0
|
[AdvancedHeaderProperty][Sub(Group2)] _AdvancedFloat ("Advanced Image", float) = 0
|
||||||
[Advanced][Image(Group2)] _AdvancedImage ("Advanced Image", 2D) = "white" { }
|
[Advanced][Image(Group2)] _AdvancedImage ("../image-20220828003810353.png", float) = 0
|
||||||
|
|
||||||
[Title(Channel Samples)]
|
[Title(Channel Samples)]
|
||||||
[Channel] _textureChannelMask ("Texture Channel Mask (Default G)", Vector) = (0, 1, 0, 0)
|
[Channel] _textureChannelMask ("Texture Channel Mask (Default G)", Vector) = (0, 1, 0, 0)
|
||||||
@ -76,6 +77,9 @@
|
|||||||
[MinMaxSlider(_rangeStart, _rangeEnd)] _minMaxSlider ("Min Max Slider (0 - 1)", Range(0.0, 1.0)) = 1.0
|
[MinMaxSlider(_rangeStart, _rangeEnd)] _minMaxSlider ("Min Max Slider (0 - 1)", Range(0.0, 1.0)) = 1.0
|
||||||
_rangeStart ("Range Start", Range(0.0, 0.5)) = 0.0
|
_rangeStart ("Range Start", Range(0.0, 0.5)) = 0.0
|
||||||
[PowerSlider(10)] _rangeEnd ("Range End PowerSlider", Range(0.5, 1.0)) = 1.0
|
[PowerSlider(10)] _rangeEnd ("Range End PowerSlider", Range(0.5, 1.0)) = 1.0
|
||||||
|
|
||||||
|
[Title(Button Samples)]
|
||||||
|
[Button(_)] _button0 ("URL Button@URL:https://github.com/JasonMa0012/LWGUI@C# Button@C#:LWGUI.ButtonDrawer.TestMethod(1234, abcd)", Float) = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
|
|
||||||
[Main(Preset, _, on, off)] _PresetGroup ("Preset Samples", float) = 0
|
[Main(Preset, _, on, off)] _PresetGroup ("Preset Samples", float) = 0
|
||||||
[Preset(Preset, LWGUI_BlendModePreset)] _BlendMode ("Blend Mode Preset", float) = 0
|
[Preset(Preset, LWGUI_Preset_BlendMode)] _BlendMode ("Blend Mode Preset", float) = 0
|
||||||
[SubEnum(Preset, UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
|
[SubEnum(Preset, UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
|
||||||
[SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _SrcBlend ("SrcBlend", Float) = 1
|
[SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _SrcBlend ("SrcBlend", Float) = 1
|
||||||
[SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _DstBlend ("DstBlend", Float) = 0
|
[SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _DstBlend ("DstBlend", Float) = 0
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 6ea7dfa994ebd3c42aed7934d8377314
|
guid: 56e3a65fe6e61904a94a3cd1ea19a8ee
|
||||||
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 76783890193e4d1aaab781515ec60548
|
||||||
|
timeCreated: 1720764555
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
[System.AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
|
||||||
|
public sealed class LwguiGradientUsageAttribute : PropertyAttribute
|
||||||
|
{
|
||||||
|
public ColorSpace colorSpace;
|
||||||
|
public LwguiGradient.ChannelMask viewChannelMask;
|
||||||
|
public LwguiGradient.GradientTimeRange timeRange;
|
||||||
|
|
||||||
|
public LwguiGradientUsageAttribute(ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One)
|
||||||
|
{
|
||||||
|
this.colorSpace = colorSpace;
|
||||||
|
this.viewChannelMask = viewChannelMask;
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[CustomPropertyDrawer(typeof(LwguiGradientUsageAttribute))]
|
||||||
|
internal sealed class LwguiGradientUsageDrawer : LwguiGradientPropertyDrawer
|
||||||
|
{
|
||||||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
var colorUsage = (LwguiGradientUsageAttribute)attribute;
|
||||||
|
|
||||||
|
colorSpace = colorUsage.colorSpace;
|
||||||
|
viewChannelMask = colorUsage.viewChannelMask;
|
||||||
|
timeRange = colorUsage.timeRange;
|
||||||
|
base.OnGUI(position, property, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[CustomPropertyDrawer(typeof(LwguiGradient))]
|
||||||
|
public class LwguiGradientPropertyDrawer : PropertyDrawer
|
||||||
|
{
|
||||||
|
public ColorSpace colorSpace = ColorSpace.Gamma;
|
||||||
|
public LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All;
|
||||||
|
public LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One;
|
||||||
|
|
||||||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var gradient = (LwguiGradient)fieldInfo.GetValue(property.serializedObject.targetObject);
|
||||||
|
LwguiGradientEditorHelper.GradientField(position, label, property, gradient, colorSpace, viewChannelMask, timeRange);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9672b824fb314326a5fd4078a7068d89
|
||||||
|
timeCreated: 1716793950
|
||||||
@ -0,0 +1,851 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
public class LwguiGradientEditor
|
||||||
|
{
|
||||||
|
private class CurveSelectionInfo
|
||||||
|
{
|
||||||
|
public List<AnimationCurve> selectedAnimationCurves;
|
||||||
|
public Vector4 selectedVectorValue = Vector4.negativeInfinity;
|
||||||
|
public float selectedFloatValue = float.NegativeInfinity;
|
||||||
|
public float selectedTime = float.NegativeInfinity;
|
||||||
|
public bool isOnlyColorKeySelected;
|
||||||
|
public LwguiGradient.LwguiMergedColorCurves mergedCurves;
|
||||||
|
|
||||||
|
public bool hasMixedTime;
|
||||||
|
public bool hasMixedFloatValue; // Selected multiple keys with different values in a same Curve
|
||||||
|
public bool hasMixedColorValue; // Selected multiple color keys with different values in the RGB Curves
|
||||||
|
public List<bool> hasMixedChannelValue = Enumerable.Repeat(false, (int)LwguiGradient.Channel.Num).ToList();
|
||||||
|
|
||||||
|
public CurveSelectionInfo(CurveEditor curveEditor)
|
||||||
|
{
|
||||||
|
selectedAnimationCurves = new List<AnimationCurve>();
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
|
||||||
|
selectedAnimationCurves.Add(new AnimationCurve());
|
||||||
|
|
||||||
|
if (curveEditor?.selectedCurves is { Count: > 0 })
|
||||||
|
{
|
||||||
|
foreach (var curveSelection in curveEditor.selectedCurves.Where(selection => selection != null))
|
||||||
|
{
|
||||||
|
var channelID = curveSelection.curveID;
|
||||||
|
var key = curveEditor.GetKeyframeFromSelection(curveSelection);
|
||||||
|
selectedAnimationCurves[channelID].AddKey(key);
|
||||||
|
|
||||||
|
if (selectedTime != float.NegativeInfinity && selectedTime != key.time)
|
||||||
|
hasMixedTime = true;
|
||||||
|
selectedTime = key.time;
|
||||||
|
|
||||||
|
if (selectedVectorValue[channelID] != Vector4.negativeInfinity[channelID] && selectedVectorValue[channelID] != key.value)
|
||||||
|
hasMixedChannelValue[channelID] = true;
|
||||||
|
selectedVectorValue[channelID] = key.value;
|
||||||
|
|
||||||
|
if (selectedFloatValue != float.NegativeInfinity && selectedFloatValue != key.value)
|
||||||
|
hasMixedFloatValue = true;
|
||||||
|
selectedFloatValue = key.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (selectedVectorValue[i] == Vector4.negativeInfinity[i])
|
||||||
|
selectedVectorValue[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedFloatValue == float.NegativeInfinity)
|
||||||
|
selectedFloatValue = 0;
|
||||||
|
|
||||||
|
mergedCurves = new LwguiGradient.LwguiMergedColorCurves(selectedAnimationCurves);
|
||||||
|
|
||||||
|
var noAlphaKeySelected = mergedCurves.curves[(int)LwguiGradient.Channel.Alpha].Count == 0;
|
||||||
|
hasMixedColorValue = noAlphaKeySelected && hasMixedChannelValue. Where((_, c) => c < (int)LwguiGradient.Channel.Alpha).Any(b => b);
|
||||||
|
isOnlyColorKeySelected = noAlphaKeySelected && selectedAnimationCurves.Where((_, c) => c < (int)LwguiGradient.Channel.Alpha).All(curve => curve.length == mergedCurves.curves[(int)LwguiGradient.Channel.Red].Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mergedCurves = new LwguiGradient.LwguiMergedColorCurves();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI Layout
|
||||||
|
|
||||||
|
private bool _useSignalLineEditField => _position.width > 1150;
|
||||||
|
|
||||||
|
private float _gradientEditorHeisht => _useSignalLineEditField ? 160 : 160 + _editFieldHeight;
|
||||||
|
private float _margin => 8;
|
||||||
|
private float _editFieldHeight => EditorGUIUtility.singleLineHeight; // 18
|
||||||
|
private float _editFieldMarginsHeight => _margin * (_useSignalLineEditField ? 2 : 3);
|
||||||
|
private float _gradientAndSwatchHeight => _gradientEditorHeisht - _margin - _editFieldMarginsHeight - _editFieldHeight - _secondEditFieldRect.height;
|
||||||
|
private float _swatchHeisht => _gradientAndSwatchHeight * 0.15f;
|
||||||
|
private float _alphaGradientHeisht => _rgbGradientHeisht * 0.5f;
|
||||||
|
private float _rgbGradientHeisht => (_gradientAndSwatchHeight - _swatchHeisht * 2) * 0.66666f;
|
||||||
|
|
||||||
|
private Rect _gradientEditorRect => new Rect(0, 0, _position.width, _gradientEditorHeisht);
|
||||||
|
private Rect _editFieldRect => new Rect(_curveEditor.leftmargin, _margin, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _editFieldHeight);
|
||||||
|
private Rect _secondEditFieldRect => _useSignalLineEditField ? Rect.zero : new Rect(_curveEditor.leftmargin, _margin * 2 + _editFieldHeight, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _editFieldHeight);
|
||||||
|
private Rect _alphaSwatchesRect => new Rect(_curveEditor.leftmargin, _editFieldMarginsHeight + _editFieldHeight + _secondEditFieldRect.height, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _swatchHeisht);
|
||||||
|
private Rect _rgbSwatchesRect => new Rect(_curveEditor.leftmargin, _editFieldMarginsHeight + _editFieldHeight + _secondEditFieldRect.height + _swatchHeisht + _alphaGradientHeisht + _rgbGradientHeisht, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _swatchHeisht);
|
||||||
|
private Rect _alphaGradientRect => new Rect(_curveEditor.leftmargin, _editFieldMarginsHeight + _editFieldHeight + _secondEditFieldRect.height + _swatchHeisht, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _alphaGradientHeisht);
|
||||||
|
private Rect _rgbGradientRect => new Rect(_curveEditor.leftmargin, _editFieldMarginsHeight + _editFieldHeight + _secondEditFieldRect.height + _swatchHeisht + _alphaGradientHeisht, _position.width - _curveEditor.leftmargin - _curveEditor.rightmargin, _rgbGradientHeisht);
|
||||||
|
|
||||||
|
private Rect _curveEditorRect => new Rect(0, _gradientEditorHeisht, _position.width, _position.height - _gradientEditorHeisht);
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly GUIContent[] s_XYZWLabels = {EditorGUIUtility.TextContent("R"), EditorGUIUtility.TextContent("G"), EditorGUIUtility.TextContent("B"), EditorGUIUtility.TextContent("A")};
|
||||||
|
|
||||||
|
|
||||||
|
private static GUIStyle _style_PopupCurveEditorBackground;
|
||||||
|
public static GUIStyle style_PopupCurveEditorBackground => _style_PopupCurveEditorBackground ??= "PopupCurveEditorBackground";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Math
|
||||||
|
|
||||||
|
private const float TOLERANCE = 0.00001f;
|
||||||
|
|
||||||
|
private static bool Equal(float a, float b) => Math.Abs(a - b) < TOLERANCE;
|
||||||
|
|
||||||
|
private static bool Equal(GradientEditor.Swatch a, GradientEditor.Swatch b) =>
|
||||||
|
a == b
|
||||||
|
|| (a != null && b != null && a.m_Time == b.m_Time && a.m_Value == b.m_Value && a.m_IsAlpha == b.m_IsAlpha);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
#region Inputs
|
||||||
|
|
||||||
|
private Rect _position;
|
||||||
|
internal LwguiGradient lwguiGradient;
|
||||||
|
internal ColorSpace colorSpace;
|
||||||
|
internal LwguiGradient.ChannelMask viewChannelMask;
|
||||||
|
internal LwguiGradient.GradientTimeRange gradientTimeRange;
|
||||||
|
private Action<LwguiGradient> _onChange;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private GradientEditor _gradientEditor;
|
||||||
|
private CurveEditor _curveEditor;
|
||||||
|
private bool _viewSettingschanged;
|
||||||
|
private bool _curveEditorContextMenuChanged;
|
||||||
|
private bool _changed;
|
||||||
|
private bool _lastChanged;
|
||||||
|
|
||||||
|
#region Gradient Editor
|
||||||
|
|
||||||
|
private static readonly string[] timeRangeMenuNames = new string[] { "0-1", "0-24", "0-2400" };
|
||||||
|
private static readonly List<LwguiGradient.GradientTimeRange> timeRangeMenuValues = new () { LwguiGradient.GradientTimeRange.One, LwguiGradient.GradientTimeRange.TwentyFour, LwguiGradient.GradientTimeRange.TwentyFourHundred };
|
||||||
|
|
||||||
|
private GradientEditor.Swatch _selectedGradientKey
|
||||||
|
{
|
||||||
|
get => _gradientEditor.GetSelectedSwatch();
|
||||||
|
set => _gradientEditor.SetSelectedSwatch(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GradientEditor.Swatch _lastSelectedGradientKey;
|
||||||
|
private GradientEditor.Swatch _deletedGradientKey;
|
||||||
|
|
||||||
|
private List<GradientEditor.Swatch> _gradientRGBSwatches => _gradientEditor.GetRGBdSwatches();
|
||||||
|
private List<GradientEditor.Swatch> _gradientAlphaSwatches => _gradientEditor.GetAlphaSwatches();
|
||||||
|
private int _lastGradientRGBSwatchesCount;
|
||||||
|
private int _lastGradientAlphaSwatchesCount;
|
||||||
|
|
||||||
|
private float _lastEditingTime = float.NegativeInfinity;
|
||||||
|
|
||||||
|
private static bool _isAddGradientKeyFailure;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Curve Editor
|
||||||
|
|
||||||
|
private List<CurveSelection> _selectedCurves
|
||||||
|
{
|
||||||
|
get => _curveEditor.selectedCurves;
|
||||||
|
set => _curveEditor.selectedCurves = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Keyframe> _deletedCurveKeys;
|
||||||
|
|
||||||
|
private bool _shouldSyncSelectionFromCurveToGradient;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Gradient Editor
|
||||||
|
|
||||||
|
private void InitGradientEditor(bool force = false)
|
||||||
|
{
|
||||||
|
if (_gradientEditor != null && !force) return;
|
||||||
|
|
||||||
|
var lastSelectedGradientKey = _gradientEditor != null && _selectedGradientKey != null ? new GradientEditor.Swatch(_selectedGradientKey.m_Time, _selectedGradientKey.m_Value, _selectedGradientKey.m_IsAlpha) : null;
|
||||||
|
|
||||||
|
var lwguiMergedCurves = new LwguiGradient.LwguiMergedColorCurves(lwguiGradient.rawCurves);
|
||||||
|
_gradientEditor ??= new GradientEditor();
|
||||||
|
_gradientEditor.Init(lwguiMergedCurves.ToGradient(ReflectionHelper.maxGradientKeyCount), 1024, colorSpace == ColorSpace.Linear, colorSpace);
|
||||||
|
|
||||||
|
// When Curve has only one key, Gradient Editor will automatically add a key
|
||||||
|
{
|
||||||
|
void FixAutoAddedGradientKey(List<GradientEditor.Swatch> swatches, LwguiGradient.Channel channel)
|
||||||
|
{
|
||||||
|
if (swatches.Count == 2 && lwguiMergedCurves.curves[(int)channel].Count == 1)
|
||||||
|
{
|
||||||
|
swatches.Clear();
|
||||||
|
var curveKey = lwguiMergedCurves.curves[(int)channel][0];
|
||||||
|
swatches.Add(channel == LwguiGradient.Channel.Alpha
|
||||||
|
? new GradientEditor.Swatch(curveKey.time, new Color(curveKey.value, curveKey.value, curveKey.value, curveKey.value), true)
|
||||||
|
: new GradientEditor.Swatch(curveKey.time, new Color(
|
||||||
|
lwguiMergedCurves.curves[(int)LwguiGradient.Channel.Red][0].value,
|
||||||
|
lwguiMergedCurves.curves[(int)LwguiGradient.Channel.Green][0].value,
|
||||||
|
lwguiMergedCurves.curves[(int)LwguiGradient.Channel.Blue][0].value,
|
||||||
|
1), false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FixAutoAddedGradientKey(_gradientRGBSwatches, LwguiGradient.Channel.Red);
|
||||||
|
FixAutoAddedGradientKey(_gradientAlphaSwatches, LwguiGradient.Channel.Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep selected key
|
||||||
|
if (lastSelectedGradientKey != null)
|
||||||
|
{
|
||||||
|
_selectedGradientKey = (lastSelectedGradientKey.m_IsAlpha ? _gradientAlphaSwatches : _gradientRGBSwatches)
|
||||||
|
.Find(swatch => Equal(swatch.m_Time, lastSelectedGradientKey.m_Time));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_selectedGradientKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGradientEditorGUI()
|
||||||
|
{
|
||||||
|
OnGradientEditFieldGUI();
|
||||||
|
|
||||||
|
EditorGUI.DrawPreviewTexture(_alphaGradientRect, lwguiGradient.GetPreviewRampTexture(1024, 1, colorSpace, LwguiGradient.ChannelMask.Alpha & viewChannelMask));
|
||||||
|
EditorGUI.DrawPreviewTexture(_rgbGradientRect, lwguiGradient.GetPreviewRampTexture(1024, 1, colorSpace, LwguiGradient.ChannelMask.RGB & viewChannelMask));
|
||||||
|
|
||||||
|
// Swatch Array
|
||||||
|
{
|
||||||
|
PrepareSyncSelectionFromGradientToCurve();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
ShowGradientSwatchArray(_alphaSwatchesRect, _gradientAlphaSwatches, LwguiGradient.ChannelMask.Alpha);
|
||||||
|
ShowGradientSwatchArray(_rgbSwatchesRect, _gradientRGBSwatches, LwguiGradient.ChannelMask.RGB);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
ApplyGradientChangesToCurve();
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncSelectionFromGradientToCurveWithoutChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGradientEditFieldGUI()
|
||||||
|
{
|
||||||
|
// Prevent interrupting mouse drag event
|
||||||
|
if (Event.current.type is EventType.MouseDrag or EventType.MouseDown or EventType.MouseMove or EventType.MouseUp
|
||||||
|
&& (!_editFieldRect.Contains(Event.current.mousePosition)
|
||||||
|
&& !_secondEditFieldRect.Contains(Event.current.mousePosition)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
float space = 20;
|
||||||
|
float vectorValueWidth = 270;
|
||||||
|
float locationWidth = 70;
|
||||||
|
float locationTextWidth = 35;
|
||||||
|
float alphaOrColorTextWidth = 40;
|
||||||
|
float colorSpaceTextWidth = 87;
|
||||||
|
float colorSpaceToggleWidth = 16;
|
||||||
|
float channelsTextWidth = 60;
|
||||||
|
float channelsMenuWidth = 85;
|
||||||
|
float timeRangeTextWidth = 75;
|
||||||
|
float timeRangeMenuWidth = 70;
|
||||||
|
|
||||||
|
Rect rect = _editFieldRect;
|
||||||
|
|
||||||
|
// Color Space
|
||||||
|
{
|
||||||
|
rect.x = rect.xMax - colorSpaceToggleWidth - colorSpaceTextWidth;
|
||||||
|
rect.width = colorSpaceTextWidth + colorSpaceToggleWidth;
|
||||||
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
|
EditorGUIUtility.labelWidth = colorSpaceTextWidth;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
colorSpace = EditorGUI.Toggle(rect, "sRGB Preview", colorSpace == ColorSpace.Gamma) ? ColorSpace.Gamma : ColorSpace.Linear;
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_viewSettingschanged = true;
|
||||||
|
InitGradientEditor(true);
|
||||||
|
}
|
||||||
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// View Channel Mask
|
||||||
|
{
|
||||||
|
rect.x -= space + channelsMenuWidth + channelsTextWidth;
|
||||||
|
rect.width = channelsMenuWidth + channelsTextWidth;
|
||||||
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
|
EditorGUIUtility.labelWidth = channelsTextWidth;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
viewChannelMask = (LwguiGradient.ChannelMask)EditorGUI.EnumFlagsField(rect, "Channels", viewChannelMask);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_viewSettingschanged = true;
|
||||||
|
InitGradientEditor(true);
|
||||||
|
InitCurveEditor(true);
|
||||||
|
}
|
||||||
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gradient Time Range
|
||||||
|
{
|
||||||
|
rect.x -= space + timeRangeMenuWidth + timeRangeTextWidth;
|
||||||
|
rect.width = timeRangeMenuWidth + timeRangeTextWidth;
|
||||||
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
|
EditorGUIUtility.labelWidth = timeRangeTextWidth;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
|
||||||
|
gradientTimeRange = timeRangeMenuValues[EditorGUI.Popup(rect, "Time Range", timeRangeMenuValues.IndexOf(gradientTimeRange), timeRangeMenuNames)];
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_viewSettingschanged = true;
|
||||||
|
InitGradientEditor(true);
|
||||||
|
InitCurveEditor(true);
|
||||||
|
}
|
||||||
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key edit field (GradientEditor.OnGUI())
|
||||||
|
if (_selectedCurves is { Count: > 0 })
|
||||||
|
{
|
||||||
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
|
var showMixedValue = EditorGUI.showMixedValue;
|
||||||
|
var selectionInfo = new CurveSelectionInfo(_curveEditor);
|
||||||
|
|
||||||
|
// Time
|
||||||
|
{
|
||||||
|
if (_useSignalLineEditField)
|
||||||
|
{
|
||||||
|
rect.x -= space + locationTextWidth + locationWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect = _secondEditFieldRect;
|
||||||
|
rect.x = rect.xMax - (locationTextWidth + locationWidth);
|
||||||
|
}
|
||||||
|
rect.width = locationTextWidth + locationWidth;
|
||||||
|
EditorGUIUtility.labelWidth = locationTextWidth;
|
||||||
|
EditorGUI.showMixedValue = selectionInfo.hasMixedTime;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var newTime = EditorGUI.FloatField(rect, "Time", selectionInfo.selectedTime * (int)gradientTimeRange) / (int)gradientTimeRange;
|
||||||
|
// When two keys have the same time, they will be merged, so avoid modifying the time in real time and only apply the changes at the end of the change
|
||||||
|
var hasChange = EditorGUI.EndChangeCheck();
|
||||||
|
if (hasChange) _lastEditingTime = newTime;
|
||||||
|
if (_lastEditingTime != selectionInfo.selectedTime
|
||||||
|
&& _lastEditingTime != float.NegativeInfinity
|
||||||
|
// End editing text
|
||||||
|
&& (EditorGUI.IsEditingTextField() && Event.current.keyCode is KeyCode.Return or KeyCode.KeypadEnter
|
||||||
|
// Mouse drag
|
||||||
|
|| !EditorGUI.IsEditingTextField() && hasChange))
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
_curveEditor.SetSelectedKeyPositions(Mathf.Clamp01(_lastEditingTime), 0, true, false);
|
||||||
|
InitGradientEditor(true);
|
||||||
|
SyncSelectionFromCurveToGradient(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vector Value
|
||||||
|
{
|
||||||
|
rect.x -= space + vectorValueWidth;
|
||||||
|
rect.width = vectorValueWidth;
|
||||||
|
// EditorGUI.VectorField()
|
||||||
|
{
|
||||||
|
int channelCount = (int)LwguiGradient.Channel.Num;
|
||||||
|
float w = (rect.width - (channelCount - 1) * EditorGUI.kSpacingSubLabel) / channelCount;
|
||||||
|
Rect nr = new Rect(rect) {width = w};
|
||||||
|
int l = EditorGUI.indentLevel;
|
||||||
|
EditorGUI.indentLevel = 0;
|
||||||
|
for (int c = 0; c < channelCount; c++)
|
||||||
|
{
|
||||||
|
EditorGUIUtility.labelWidth = EditorGUI.GetLabelWidth(s_XYZWLabels[c], 0);
|
||||||
|
EditorGUI.showMixedValue = selectionInfo.hasMixedChannelValue[c];
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var newValue = EditorGUI.FloatField(nr, s_XYZWLabels[c], selectionInfo.selectedVectorValue[c]);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
// Apply a curve's modification
|
||||||
|
foreach (var selection in _selectedCurves.Where(selection => selection.curveID == c))
|
||||||
|
{
|
||||||
|
var cw = _curveEditor.animationCurves[selection.curveID];
|
||||||
|
var key = cw.curve.keys[selection.key];
|
||||||
|
key.value = newValue;
|
||||||
|
cw.MoveKey(selection.key, ref key);
|
||||||
|
cw.changed = true;
|
||||||
|
AnimationUtility.UpdateTangentsFromMode(cw.curve);
|
||||||
|
}
|
||||||
|
_curveEditor.InvalidateSelectionBounds();
|
||||||
|
InitGradientEditor(true);
|
||||||
|
SyncSelectionFromCurveToGradient(true);
|
||||||
|
}
|
||||||
|
nr.x += w + EditorGUI.kSpacingSubLabel;
|
||||||
|
}
|
||||||
|
EditorGUI.indentLevel = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alpha or Color field
|
||||||
|
{
|
||||||
|
rect = new Rect(_editFieldRect.x, rect.y, rect.x - _editFieldRect.x - space, rect.height);
|
||||||
|
EditorGUIUtility.labelWidth = alphaOrColorTextWidth;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
if (selectionInfo.isOnlyColorKeySelected)
|
||||||
|
{
|
||||||
|
EditorGUI.showMixedValue = selectionInfo.hasMixedColorValue;
|
||||||
|
var newColorValue = new Vector4(selectionInfo.selectedVectorValue.x, selectionInfo.selectedVectorValue.y, selectionInfo.selectedVectorValue.z, 1);
|
||||||
|
newColorValue = EditorGUI.ColorField(rect, new GUIContent("Value"), newColorValue, true, false, colorSpace == ColorSpace.Linear);
|
||||||
|
newColorValue.w = selectionInfo.selectedVectorValue.w;
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
// Use EventCommandNames.ColorPickerChanged event to avoid ShowSwatchArray() Errors
|
||||||
|
Event.current.Use();
|
||||||
|
// Apply RGB curve's modification
|
||||||
|
foreach (var selection in _selectedCurves.Where(selection => selection.curveID < (int)LwguiGradient.Channel.Alpha))
|
||||||
|
{
|
||||||
|
var channelID = selection.curveID;
|
||||||
|
var cw = _curveEditor.animationCurves[channelID];
|
||||||
|
var key = cw.curve.keys[selection.key];
|
||||||
|
key.value = newColorValue[channelID];
|
||||||
|
cw.MoveKey(selection.key, ref key);
|
||||||
|
cw.changed = true;
|
||||||
|
AnimationUtility.UpdateTangentsFromMode(cw.curve);
|
||||||
|
}
|
||||||
|
_curveEditor.InvalidateSelectionBounds();
|
||||||
|
InitGradientEditor(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUI.showMixedValue = selectionInfo.hasMixedFloatValue;
|
||||||
|
var newValue = EditorGUI.IntSlider(rect, "Value", (int)(selectionInfo.selectedFloatValue * 255), 0, 255) / 255f;
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
_curveEditor.SetSelectedKeyPositions(0, newValue, false, true);
|
||||||
|
InitGradientEditor(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
|
EditorGUI.showMixedValue = showMixedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowGradientSwatchArray(Rect rect, List<GradientEditor.Swatch> swatches, LwguiGradient.ChannelMask drawingChannelMask)
|
||||||
|
{
|
||||||
|
// GradientEditor.ShowSwatchArray()
|
||||||
|
ReflectionHelper.GradientEditor_SetStyles();
|
||||||
|
|
||||||
|
_isAddGradientKeyFailure = false;
|
||||||
|
_gradientEditor.ShowSwatchArray(rect, (viewChannelMask & drawingChannelMask) != drawingChannelMask ? new List<GradientEditor.Swatch>() : swatches, drawingChannelMask == LwguiGradient.ChannelMask.Alpha);
|
||||||
|
|
||||||
|
// Since the maximum number of Gradient Keys is hard-coded in the engine, keys that exceed the limit can only be displayed and edited in the Curve Editor
|
||||||
|
if (_isAddGradientKeyFailure)
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
float mouseSwatchTime = _gradientEditor.GetTime((Event.current.mousePosition.x - rect.x) / rect.width);
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (!LwguiGradient.IsChannelIndexInMask(c, drawingChannelMask))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var curveSelection = _curveEditor.AddKeyAtTime(_curveEditor.animationCurves[c], mouseSwatchTime);
|
||||||
|
_curveEditor.AddSelection(curveSelection);
|
||||||
|
}
|
||||||
|
_curveEditor.InvalidateSelectionBounds();
|
||||||
|
_selectedGradientKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyGradientChangesToCurve()
|
||||||
|
{
|
||||||
|
var selectedKeyEqual = _selectedGradientKey == _lastSelectedGradientKey || Equal(_selectedGradientKey, _lastSelectedGradientKey);
|
||||||
|
var rgbKeyCountEqual = _gradientRGBSwatches.Count == _lastGradientRGBSwatchesCount;
|
||||||
|
var alphaKeyCountEqual = _gradientAlphaSwatches.Count == _lastGradientAlphaSwatchesCount;
|
||||||
|
var addRGBKey = _gradientRGBSwatches.Count > _lastGradientRGBSwatchesCount;
|
||||||
|
var addAlphaKey = _gradientAlphaSwatches.Count > _lastGradientAlphaSwatchesCount;
|
||||||
|
var delRGBKey = _gradientRGBSwatches.Count < _lastGradientRGBSwatchesCount;
|
||||||
|
var delAlphaKey = _gradientAlphaSwatches.Count < _lastGradientAlphaSwatchesCount;
|
||||||
|
|
||||||
|
if (selectedKeyEqual && rgbKeyCountEqual && alphaKeyCountEqual)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change time or value
|
||||||
|
if ((!selectedKeyEqual && rgbKeyCountEqual && alphaKeyCountEqual)
|
||||||
|
// Del a key
|
||||||
|
|| (delRGBKey || delAlphaKey))
|
||||||
|
{
|
||||||
|
foreach (var curveSelection in _selectedCurves.Where(selection => LwguiGradient.IsChannelIndexInMask(selection.curveID, viewChannelMask)))
|
||||||
|
{
|
||||||
|
var cw = _curveEditor.animationCurves[curveSelection.curveID];
|
||||||
|
var selectedKey = cw.curve.keys[curveSelection.key];
|
||||||
|
if (rgbKeyCountEqual && alphaKeyCountEqual)
|
||||||
|
{
|
||||||
|
var newKey = selectedKey;
|
||||||
|
|
||||||
|
// Change a key time
|
||||||
|
if (_selectedGradientKey.m_Time != _lastSelectedGradientKey.m_Time)
|
||||||
|
{
|
||||||
|
newKey.time = _selectedGradientKey.m_Time;
|
||||||
|
}
|
||||||
|
// Change a key value
|
||||||
|
else if (_selectedGradientKey.m_Value != _lastSelectedGradientKey.m_Value)
|
||||||
|
{
|
||||||
|
newKey.value = _selectedGradientKey.m_IsAlpha ? _selectedGradientKey.m_Value.r : _selectedGradientKey.m_Value[curveSelection.curveID];
|
||||||
|
}
|
||||||
|
newKey = CheckNewKeyTime(cw, newKey, selectedKey.time);
|
||||||
|
curveSelection.key = cw.MoveKey(curveSelection.key, ref newKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Mouse drag out of the swatch rect, save the key
|
||||||
|
if (_selectedGradientKey != null)
|
||||||
|
{
|
||||||
|
_deletedGradientKey = new GradientEditor.Swatch(_selectedGradientKey.m_Time, _selectedGradientKey.m_Value, _selectedGradientKey.m_IsAlpha);
|
||||||
|
_deletedCurveKeys ??= new List<Keyframe>(new Keyframe[(int)LwguiGradient.Channel.Num]);
|
||||||
|
_deletedCurveKeys[curveSelection.curveID] = selectedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Del a key
|
||||||
|
cw.curve.RemoveKey(curveSelection.key);
|
||||||
|
}
|
||||||
|
AnimationUtility.UpdateTangentsFromMode(cw.curve);
|
||||||
|
cw.changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delRGBKey || delAlphaKey)
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var curveSelections = new List<CurveSelection>();
|
||||||
|
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (!LwguiGradient.IsChannelIndexInMask(c, viewChannelMask))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add a RGB Key
|
||||||
|
if ((c < (int)LwguiGradient.Channel.Alpha && addRGBKey)
|
||||||
|
// Add an Alpha Key
|
||||||
|
|| (c == (int)LwguiGradient.Channel.Alpha && addAlphaKey))
|
||||||
|
{
|
||||||
|
var cw = _curveEditor.animationCurves[c];
|
||||||
|
|
||||||
|
// Mouse drag back to the swatch rect, restore the key
|
||||||
|
if (_deletedGradientKey != null && _deletedCurveKeys != null
|
||||||
|
&& _selectedGradientKey?.m_Value == _deletedGradientKey?.m_Value
|
||||||
|
&& _selectedGradientKey?.m_IsAlpha == _deletedGradientKey?.m_IsAlpha)
|
||||||
|
{
|
||||||
|
var deletedKey = _deletedCurveKeys[c];
|
||||||
|
var newKey = deletedKey;
|
||||||
|
newKey.time = _selectedGradientKey.m_Time;
|
||||||
|
newKey = CheckNewKeyTime(cw, newKey, deletedKey.time);
|
||||||
|
var addedKeyIndex = cw.AddKey(newKey);
|
||||||
|
curveSelections.Add(new CurveSelection(c, addedKeyIndex, CurveSelection.SelectionType.Key));
|
||||||
|
}
|
||||||
|
// Add a new key
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var curveSelection = _curveEditor.AddKeyAtTime(cw, _selectedGradientKey.m_Time);
|
||||||
|
curveSelections.Add(curveSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
cw.selected = CurveWrapper.SelectionMode.Selected;
|
||||||
|
cw.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_deletedGradientKey = null;
|
||||||
|
_deletedCurveKeys = null;
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
curveSelections.ForEach(selection => _curveEditor.AddSelection(selection));
|
||||||
|
InitGradientEditor(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_curveEditor.InvalidateSelectionBounds();
|
||||||
|
InitCurveEditor(true);
|
||||||
|
|
||||||
|
// Cannot overlap with the Time of an existing Key when adding or moving Keys
|
||||||
|
Keyframe CheckNewKeyTime(CurveWrapper cw, Keyframe newKey, float oldKeyTime = 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sameTimeKey = cw.curve.keys.First(keyframe => keyframe.time == newKey.time);
|
||||||
|
if (newKey.time > oldKeyTime)
|
||||||
|
newKey.time += 0.00001f;
|
||||||
|
else
|
||||||
|
newKey.time -= 0.00001f;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException) { }
|
||||||
|
|
||||||
|
return newKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareSyncSelectionFromGradientToCurve()
|
||||||
|
{
|
||||||
|
_lastSelectedGradientKey = _selectedGradientKey != null ? new GradientEditor.Swatch(_selectedGradientKey.m_Time, _selectedGradientKey.m_Value, _selectedGradientKey.m_IsAlpha) : null;
|
||||||
|
_lastGradientRGBSwatchesCount = _gradientRGBSwatches.Count;
|
||||||
|
_lastGradientAlphaSwatchesCount = _gradientAlphaSwatches.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SyncSelectionFromGradientToCurveWithoutChanges()
|
||||||
|
{
|
||||||
|
// Only detect when switching selected Key without modifying it
|
||||||
|
if (!_gradientEditorRect.Contains(Event.current.mousePosition)
|
||||||
|
// || Event.current.type != EventType.MouseDown
|
||||||
|
|| _changed
|
||||||
|
|| _lastChanged
|
||||||
|
|| Equal(_lastSelectedGradientKey, _selectedGradientKey))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_selectedGradientKey == null)
|
||||||
|
{
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get selected gradient key index
|
||||||
|
var selectedGradientKeyIndexes = Enumerable.Repeat(-1, (int)LwguiGradient.Channel.Num).ToArray();
|
||||||
|
|
||||||
|
if (_selectedGradientKey.m_IsAlpha)
|
||||||
|
{
|
||||||
|
selectedGradientKeyIndexes[(int)LwguiGradient.Channel.Alpha] = _gradientAlphaSwatches.FindIndex(swatch => swatch == _selectedGradientKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num - 1; c++)
|
||||||
|
{
|
||||||
|
selectedGradientKeyIndexes[c] = _gradientRGBSwatches.FindIndex(swatch => swatch == _selectedGradientKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get curve key index
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
var lwguiMergedCurves = new LwguiGradient.LwguiMergedColorCurves(lwguiGradient.rawCurves);
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
|
||||||
|
{
|
||||||
|
if (selectedGradientKeyIndexes[c] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var curveKeyIndex = lwguiMergedCurves.curves[c][selectedGradientKeyIndexes[c]].index;
|
||||||
|
_selectedCurves.Add(new CurveSelection(c, curveKeyIndex));
|
||||||
|
}
|
||||||
|
_curveEditor.InvalidateSelectionBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Curve Editor
|
||||||
|
|
||||||
|
private void InitCurveEditor(bool force = false)
|
||||||
|
{
|
||||||
|
if (_curveEditor != null && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var firstOpenWindow = _curveEditor == null;
|
||||||
|
_curveEditor = CurveEditorWindow.instance.GetCurveEditor();
|
||||||
|
|
||||||
|
var cws = new CurveWrapper[(int)LwguiGradient.Channel.Num];
|
||||||
|
for (int c = 0; c < (int)LwguiGradient.Channel.Num; c++)
|
||||||
|
{
|
||||||
|
var curve = lwguiGradient.rawCurves[c];
|
||||||
|
var cw = new CurveWrapper();
|
||||||
|
cw.id = c;
|
||||||
|
if (LwguiGradient.IsChannelIndexInMask(c, viewChannelMask))
|
||||||
|
{
|
||||||
|
cw.color = LwguiGradient.channelColors[c];
|
||||||
|
cw.renderer = new NormalCurveRenderer(curve);
|
||||||
|
cw.renderer.SetWrap(curve.preWrapMode, curve.postWrapMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cw.renderer = new NormalCurveRenderer(new AnimationCurve());
|
||||||
|
}
|
||||||
|
cws[c] = cw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_curveEditor.animationCurves = cws;
|
||||||
|
_curveEditor.curvesUpdated = () =>
|
||||||
|
{
|
||||||
|
_curveEditorContextMenuChanged = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
SyncCurveEditorRect();
|
||||||
|
|
||||||
|
if (firstOpenWindow)
|
||||||
|
{
|
||||||
|
_curveEditor.Frame(new Bounds(new Vector2(0.5f, 0.5f), Vector2.one), true, true);
|
||||||
|
_curveEditor.SelectNone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCurveEditorGUI()
|
||||||
|
{
|
||||||
|
GUI.Label(_curveEditorRect, GUIContent.none, style_PopupCurveEditorBackground);
|
||||||
|
EditorGUI.DrawRect(new Rect(_curveEditorRect.x, _curveEditorRect.y, _curveEditorRect.width, 1), new Color(0.5f, 0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
PrepareSyncSelectionFromCurveToGradient();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
_curveEditor.OnGUI();
|
||||||
|
bool curveEditorChanged = EditorGUI.EndChangeCheck() || _curveEditorContextMenuChanged;
|
||||||
|
_changed |= curveEditorChanged;
|
||||||
|
if (curveEditorChanged)
|
||||||
|
{
|
||||||
|
InitGradientEditor(true);
|
||||||
|
foreach (var cw in _curveEditor.animationCurves)
|
||||||
|
{
|
||||||
|
cw.changed = false;
|
||||||
|
}
|
||||||
|
_curveEditorContextMenuChanged = false;
|
||||||
|
}
|
||||||
|
SyncSelectionFromCurveToGradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SyncCurveEditorRect()
|
||||||
|
{
|
||||||
|
_curveEditor.rect = _curveEditorRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareSyncSelectionFromCurveToGradient()
|
||||||
|
{
|
||||||
|
// var eventType = Event.current.GetTypeForControl(GUIUtility.GetControlID(897560, FocusType.Passive)); // CurveEditor.SelectPoints()
|
||||||
|
var eventType = Event.current.type;
|
||||||
|
|
||||||
|
if (_curveEditorRect.Contains(Event.current.mousePosition)
|
||||||
|
&& eventType is EventType.MouseDown or EventType.MouseDrag)
|
||||||
|
_shouldSyncSelectionFromCurveToGradient = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SyncSelectionFromCurveToGradient(bool force = false)
|
||||||
|
{
|
||||||
|
if (!_shouldSyncSelectionFromCurveToGradient && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_shouldSyncSelectionFromCurveToGradient = false;
|
||||||
|
_selectedGradientKey = null;
|
||||||
|
|
||||||
|
var selectedGradientKeys = new List<GradientEditor.Swatch>();
|
||||||
|
var mergedCurves = new CurveSelectionInfo(_curveEditor).mergedCurves;
|
||||||
|
|
||||||
|
FindSelectedGradientKey((int)LwguiGradient.Channel.Red, _gradientRGBSwatches);
|
||||||
|
FindSelectedGradientKey((int)LwguiGradient.Channel.Alpha, _gradientAlphaSwatches);
|
||||||
|
|
||||||
|
// Sync selection to Gradient Editor only when single selection
|
||||||
|
if (selectedGradientKeys.Count == 1)
|
||||||
|
_selectedGradientKey = selectedGradientKeys[0];
|
||||||
|
return;
|
||||||
|
|
||||||
|
void FindSelectedGradientKey(int channel, List<GradientEditor.Swatch> list)
|
||||||
|
{
|
||||||
|
foreach (var lwguiKeyframe in mergedCurves.curves[channel])
|
||||||
|
{
|
||||||
|
if (selectedGradientKeys.Count > 1) return;
|
||||||
|
|
||||||
|
var key = list.Find(swatch => Equal(swatch.m_Time, lwguiKeyframe.time));
|
||||||
|
if (key != null)
|
||||||
|
selectedGradientKeys.Add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
public void Init(Rect position, LwguiGradient gradient, ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One, Action<LwguiGradient> onChange = null)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
this._position = position;
|
||||||
|
this.lwguiGradient = gradient;
|
||||||
|
this.colorSpace = colorSpace;
|
||||||
|
this.viewChannelMask = viewChannelMask;
|
||||||
|
this.gradientTimeRange = timeRange;
|
||||||
|
this._onChange = onChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGUI(Rect position)
|
||||||
|
{
|
||||||
|
if (lwguiGradient == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Debug.Log(JsonUtility.ToJson(lwguiGradient));
|
||||||
|
|
||||||
|
this._position = position;
|
||||||
|
|
||||||
|
InitGradientEditor();
|
||||||
|
InitCurveEditor();
|
||||||
|
|
||||||
|
// Gradient Editor
|
||||||
|
OnGradientEditorGUI();
|
||||||
|
|
||||||
|
// Curve Editor
|
||||||
|
SyncCurveEditorRect();
|
||||||
|
OnCurveEditorGUI();
|
||||||
|
|
||||||
|
_lastChanged = _changed;
|
||||||
|
_changed = false;
|
||||||
|
|
||||||
|
if (_lastChanged)
|
||||||
|
{
|
||||||
|
if (!EditorApplication.isPlaying)
|
||||||
|
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
|
||||||
|
|
||||||
|
GUI.changed = true;
|
||||||
|
_onChange?.Invoke(lwguiGradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_viewSettingschanged)
|
||||||
|
{
|
||||||
|
_viewSettingschanged = false;
|
||||||
|
GUI.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
lwguiGradient = null;
|
||||||
|
_gradientEditor = null;
|
||||||
|
_curveEditor?.OnDisable();
|
||||||
|
_curveEditor = null;
|
||||||
|
_lastChanged = false;
|
||||||
|
_lastEditingTime = float.NegativeInfinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CheckAddGradientKeyFailureLog(string logString, string stackTrace, LogType type)
|
||||||
|
{
|
||||||
|
if (type == LogType.Warning
|
||||||
|
&& logString == "Max " + ReflectionHelper.maxGradientKeyCount + " color keys and " + ReflectionHelper.maxGradientKeyCount + " alpha keys are allowed in a gradient.")
|
||||||
|
{
|
||||||
|
_isAddGradientKeyFailure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a472009f0e9429c8d503438262f3d34
|
||||||
|
timeCreated: 1720769127
|
||||||
@ -0,0 +1,195 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
public static class LwguiGradientEditorHelper
|
||||||
|
{
|
||||||
|
private static readonly int s_LwguiGradientHash = "s_LwguiGradientHash".GetHashCode();
|
||||||
|
private static int s_LwguiGradientID;
|
||||||
|
|
||||||
|
// GradientEditor.DrawGradientWithBackground()
|
||||||
|
public static void DrawGradientWithBackground(Rect position, LwguiGradient gradient, ColorSpace colorSpace, LwguiGradient.ChannelMask viewChannelMask)
|
||||||
|
{
|
||||||
|
Texture2D gradientTexture = gradient.GetPreviewRampTexture(256, 1, colorSpace, viewChannelMask);
|
||||||
|
Rect r2 = new Rect(position.x + 1, position.y + 1, position.width - 2, position.height - 2);
|
||||||
|
|
||||||
|
// Background checkers
|
||||||
|
Texture2D backgroundTexture = GradientEditor.GetBackgroundTexture();
|
||||||
|
Rect texCoordsRect = new Rect(0, 0, r2.width / backgroundTexture.width, r2.height / backgroundTexture.height);
|
||||||
|
GUI.DrawTextureWithTexCoords(r2, backgroundTexture, texCoordsRect, false);
|
||||||
|
|
||||||
|
// Outline for Gradinet Texture, used to be Frame over texture.
|
||||||
|
// LWGUI: GUI.Box() will cause subsequent attributes to be unable to be selected
|
||||||
|
// GUI.Box(position, GUIContent.none);
|
||||||
|
|
||||||
|
// Gradient texture
|
||||||
|
Color oldColor = GUI.color;
|
||||||
|
GUI.color = Color.white; //Dont want the Playmode tint to be applied to gradient textures.
|
||||||
|
if (gradientTexture != null)
|
||||||
|
GUI.DrawTexture(r2, gradientTexture, ScaleMode.StretchToFill, true);
|
||||||
|
GUI.color = oldColor;
|
||||||
|
|
||||||
|
// HDR label
|
||||||
|
// float maxColorComponent = GetMaxColorComponent(gradient);
|
||||||
|
// if (maxColorComponent > 1.0f)
|
||||||
|
// {
|
||||||
|
// GUI.Label(new Rect(position.x, position.y, position.width - 3, position.height), "HDR", EditorStyles.centeredGreyMiniLabel);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DrawGradientWithSeparateAlphaChannel(Rect position, LwguiGradient gradient, ColorSpace colorSpace, LwguiGradient.ChannelMask viewChannelMask)
|
||||||
|
{
|
||||||
|
if (!LwguiGradient.HasChannelMask(viewChannelMask, LwguiGradient.ChannelMask.Alpha) || viewChannelMask == LwguiGradient.ChannelMask.Alpha)
|
||||||
|
{
|
||||||
|
DrawGradientWithBackground(position, gradient, colorSpace, viewChannelMask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var r2 = new Rect(position.x + 1, position.y + 1, position.width - 2, position.height - 2);
|
||||||
|
var rgbRect = new Rect(r2.x, r2.y, r2.width, r2.height * 0.8f);
|
||||||
|
var alphaRect = new Rect(rgbRect.x, rgbRect.yMax, r2.width, r2.height * 0.2f);
|
||||||
|
|
||||||
|
var rgbTexture = gradient.GetPreviewRampTexture(256, 1, colorSpace, viewChannelMask ^ LwguiGradient.ChannelMask.Alpha);
|
||||||
|
var alphaTexture = gradient.GetPreviewRampTexture(256, 1, colorSpace, LwguiGradient.ChannelMask.Alpha);
|
||||||
|
|
||||||
|
Color oldColor = GUI.color;
|
||||||
|
GUI.color = Color.white; //Dont want the Playmode tint to be applied to gradient textures.
|
||||||
|
GUI.DrawTexture(rgbRect, rgbTexture, ScaleMode.StretchToFill, false);
|
||||||
|
GUI.DrawTexture(alphaRect, alphaTexture, ScaleMode.StretchToFill, false);
|
||||||
|
GUI.color = oldColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GradientField(Rect position, GUIContent label, LwguiGradient gradient,
|
||||||
|
ColorSpace colorSpace = ColorSpace.Gamma,
|
||||||
|
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
|
||||||
|
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One,
|
||||||
|
Action onOpenWindow = null)
|
||||||
|
{
|
||||||
|
int id = GUIUtility.GetControlID(s_LwguiGradientHash, FocusType.Keyboard, position);
|
||||||
|
var rect = EditorGUI.PrefixLabel(position, id, label);
|
||||||
|
var evt = Event.current;
|
||||||
|
|
||||||
|
|
||||||
|
// internal static Gradient DoGradientField(Rect position, int id, Gradient value, SerializedProperty property, bool hdr, ColorSpace space)
|
||||||
|
switch (evt.GetTypeForControl(id))
|
||||||
|
{
|
||||||
|
case EventType.MouseDown:
|
||||||
|
if (rect.Contains(evt.mousePosition))
|
||||||
|
{
|
||||||
|
if (evt.button == 0)
|
||||||
|
{
|
||||||
|
s_LwguiGradientID = id;
|
||||||
|
GUIUtility.keyboardControl = id;
|
||||||
|
LwguiGradientWindow.Show(gradient, colorSpace, viewChannelMask, timeRange, GUIView.current);
|
||||||
|
onOpenWindow?.Invoke();
|
||||||
|
GUIUtility.ExitGUI();
|
||||||
|
}
|
||||||
|
else if (evt.button == 1)
|
||||||
|
{
|
||||||
|
// if (property != null)
|
||||||
|
// GradientContextMenu.Show(property.Copy());
|
||||||
|
// // TODO: make work for Gradient value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.KeyDown:
|
||||||
|
if (GUIUtility.keyboardControl == id && (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter))
|
||||||
|
{
|
||||||
|
evt.Use();
|
||||||
|
LwguiGradientWindow.Show(gradient, colorSpace, viewChannelMask, timeRange, GUIView.current);
|
||||||
|
onOpenWindow?.Invoke();
|
||||||
|
GUIUtility.ExitGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EventType.Repaint:
|
||||||
|
DrawGradientWithSeparateAlphaChannel(rect, gradient, colorSpace, viewChannelMask);
|
||||||
|
break;
|
||||||
|
case EventType.ExecuteCommand:
|
||||||
|
// When drawing the modifying Gradient Field and it has changed
|
||||||
|
if ((GUIUtility.keyboardControl == id || s_LwguiGradientID == id)
|
||||||
|
&& (evt.commandName is LwguiGradientWindow.LwguiGradientChangedCommand))
|
||||||
|
{
|
||||||
|
GUI.changed = true;
|
||||||
|
LwguiGradientHelper.ClearRampPreviewCaches();
|
||||||
|
HandleUtility.Repaint();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EventType.ValidateCommand:
|
||||||
|
// Sync Undo/Redo result to editor window
|
||||||
|
if (s_LwguiGradientID == id && evt.commandName == "UndoRedoPerformed")
|
||||||
|
{
|
||||||
|
LwguiGradientWindow.UpdateCurrentGradient(gradient);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lwgui Gradient Field with full Undo/Redo/ContextMenu functions
|
||||||
|
public static void GradientField(Rect position, GUIContent label, SerializedProperty property, LwguiGradient gradient,
|
||||||
|
ColorSpace colorSpace = ColorSpace.Gamma,
|
||||||
|
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
|
||||||
|
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One)
|
||||||
|
{
|
||||||
|
label = EditorGUI.BeginProperty(position, label, property);
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
|
||||||
|
GradientField(position, label, gradient, colorSpace, viewChannelMask, timeRange,
|
||||||
|
() => LwguiGradientWindow.RegisterSerializedObjectUndo(property.serializedObject.targetObject));
|
||||||
|
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
GUI.changed = true;
|
||||||
|
LwguiGradientWindow.RegisterSerializedObjectUndo(property.serializedObject.targetObject);
|
||||||
|
}
|
||||||
|
EditorGUI.EndProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool GradientEditButton(Rect position, GUIContent icon, LwguiGradient gradient,
|
||||||
|
ColorSpace colorSpace = ColorSpace.Gamma,
|
||||||
|
LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All,
|
||||||
|
LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One,
|
||||||
|
Func<bool> shouldOpenWindowAfterClickingEvent = null)
|
||||||
|
{
|
||||||
|
int id = GUIUtility.GetControlID(s_LwguiGradientHash, FocusType.Keyboard, position);
|
||||||
|
var evt = Event.current;
|
||||||
|
|
||||||
|
// When drawing the modifying Gradient Field and it has changed
|
||||||
|
if ((GUIUtility.keyboardControl == id || s_LwguiGradientID == id)
|
||||||
|
&& evt.GetTypeForControl(id) == EventType.ExecuteCommand
|
||||||
|
&& evt.commandName == LwguiGradientWindow.LwguiGradientChangedCommand)
|
||||||
|
{
|
||||||
|
GUI.changed = true;
|
||||||
|
HandleUtility.Repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync Undo/Redo result to editor window
|
||||||
|
if (s_LwguiGradientID == id
|
||||||
|
&& evt.commandName == "UndoRedoPerformed")
|
||||||
|
{
|
||||||
|
LwguiGradientWindow.UpdateCurrentGradient(gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open editor window
|
||||||
|
var clicked = ReflectionHelper.GUI_Button(position, id, icon, GUI.skin.button);
|
||||||
|
if (clicked)
|
||||||
|
{
|
||||||
|
if (shouldOpenWindowAfterClickingEvent == null || shouldOpenWindowAfterClickingEvent.Invoke())
|
||||||
|
{
|
||||||
|
s_LwguiGradientID = id;
|
||||||
|
GUIUtility.keyboardControl = id;
|
||||||
|
LwguiGradientWindow.Show(gradient, colorSpace, viewChannelMask, timeRange, GUIView.current);
|
||||||
|
GUIUtility.ExitGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clicked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 016014c82cb94b5d9f271b1b06986541
|
||||||
|
timeCreated: 1720424032
|
||||||
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
[ExcludeFromPreset]
|
||||||
|
class LwguiGradientPresetLibrary : PresetLibrary
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
List<LwguiGradientPreset> m_Presets = new List<LwguiGradientPreset>();
|
||||||
|
|
||||||
|
public override int Count()
|
||||||
|
{
|
||||||
|
return m_Presets.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object GetPreset(int index)
|
||||||
|
{
|
||||||
|
return m_Presets[index].lwguiGradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add(object presetObject, string presetName)
|
||||||
|
{
|
||||||
|
LwguiGradient gradient = presetObject as LwguiGradient;
|
||||||
|
if (gradient == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Wrong type used in LwguiGradientPresetLibrary");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Presets.Add(new LwguiGradientPreset(new LwguiGradient(gradient), presetName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Replace(int index, object newPresetObject)
|
||||||
|
{
|
||||||
|
LwguiGradient gradient = newPresetObject as LwguiGradient;
|
||||||
|
if (gradient == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Wrong type used in LwguiGradientPresetLibrary");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Presets[index].lwguiGradient = new LwguiGradient(gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Remove(int index)
|
||||||
|
{
|
||||||
|
m_Presets.RemoveAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Move(int index, int destIndex, bool insertAfterDestIndex)
|
||||||
|
{
|
||||||
|
PresetLibraryHelpers.MoveListItem(m_Presets, index, destIndex, insertAfterDestIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Rect rect, int index)
|
||||||
|
{
|
||||||
|
Draw(rect, m_Presets[index].lwguiGradient, ColorSpace.Gamma, LwguiGradient.ChannelMask.All);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(Rect rect, object presetObject)
|
||||||
|
{
|
||||||
|
Draw(rect, presetObject as LwguiGradient, ColorSpace.Gamma, LwguiGradient.ChannelMask.All);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(Rect rect, LwguiGradient gradient, ColorSpace colorSpace, LwguiGradient.ChannelMask viewChannelMask)
|
||||||
|
{
|
||||||
|
if (gradient == null)
|
||||||
|
return;
|
||||||
|
LwguiGradientEditorHelper.DrawGradientWithSeparateAlphaChannel(rect, gradient, colorSpace, viewChannelMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetName(int index)
|
||||||
|
{
|
||||||
|
return m_Presets[index].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetName(int index, string presetName)
|
||||||
|
{
|
||||||
|
m_Presets[index].name = presetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[System.Serializable]
|
||||||
|
class LwguiGradientPreset
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
string m_Name;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
LwguiGradient m_LwguiGradient;
|
||||||
|
|
||||||
|
public LwguiGradientPreset(LwguiGradient preset, string presetName)
|
||||||
|
{
|
||||||
|
lwguiGradient = preset;
|
||||||
|
name = presetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LwguiGradient lwguiGradient
|
||||||
|
{
|
||||||
|
get => m_LwguiGradient;
|
||||||
|
set => m_LwguiGradient = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string name
|
||||||
|
{
|
||||||
|
get => m_Name;
|
||||||
|
set => m_Name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6aa6b41078c94b978a355082d28769f0
|
||||||
|
timeCreated: 1721013180
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(LwguiGradientPresetLibrary))]
|
||||||
|
internal class LwguiGradientPresetLibraryEditor : Editor
|
||||||
|
{
|
||||||
|
private GenericPresetLibraryInspector<LwguiGradientPresetLibrary> m_GenericPresetLibraryInspector;
|
||||||
|
|
||||||
|
public void OnEnable()
|
||||||
|
{
|
||||||
|
m_GenericPresetLibraryInspector = new GenericPresetLibraryInspector<LwguiGradientPresetLibrary>(target, "Lwgui Gradient Preset Library", OnEditButtonClicked)
|
||||||
|
{
|
||||||
|
presetSize = new Vector2(72, 16),
|
||||||
|
lineSpacing = 4f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDestroy()
|
||||||
|
{
|
||||||
|
m_GenericPresetLibraryInspector?.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
m_GenericPresetLibraryInspector.itemViewMode = PresetLibraryEditorState.GetItemViewMode("LwguiGradient"); // ensure in-sync
|
||||||
|
m_GenericPresetLibraryInspector?.OnInspectorGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEditButtonClicked(string libraryPath)
|
||||||
|
{
|
||||||
|
LwguiGradientWindow.Show(new LwguiGradient());
|
||||||
|
LwguiGradientWindow.instance.currentPresetLibrary = libraryPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c5050da63672448d8f12cf3c82e12a6a
|
||||||
|
timeCreated: 1721013226
|
||||||
@ -0,0 +1,318 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using LWGUI.Runtime.LwguiGradient;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace LWGUI.LwguiGradientEditor
|
||||||
|
{
|
||||||
|
internal class PresetLibraryLwguiGradientEditor : PresetLibraryEditor<LwguiGradientPresetLibrary>
|
||||||
|
{
|
||||||
|
public PresetLibraryLwguiGradientEditor(ScriptableObjectSaveLoadHelper<LwguiGradientPresetLibrary> helper,
|
||||||
|
PresetLibraryEditorState state,
|
||||||
|
Action<int, object> itemClickedCallback
|
||||||
|
) : base(helper, state, itemClickedCallback)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public ColorSpace colorSpace { get; set; }
|
||||||
|
public LwguiGradient.ChannelMask viewChannelMask { get; set; }
|
||||||
|
|
||||||
|
protected override void DrawPreset(PresetLibrary lib, Rect rect, object presetObject)
|
||||||
|
{
|
||||||
|
((LwguiGradientPresetLibrary)lib).Draw(rect, presetObject as LwguiGradient, colorSpace, viewChannelMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LwguiGradientWindow : EditorWindow
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
private static LwguiGradientWindow _lwguiGradientWindow;
|
||||||
|
public const string presetsEditorPrefID = "LwguiGradient";
|
||||||
|
|
||||||
|
private LwguiGradientEditor _lwguiGradientEditor;
|
||||||
|
private PresetLibraryLwguiGradientEditor _lwguiGradientLibraryEditor;
|
||||||
|
[SerializeField] private PresetLibraryEditorState _LwguiGradientLibraryEditorState;
|
||||||
|
|
||||||
|
[NonSerialized] public LwguiGradient lwguiGradient;
|
||||||
|
[NonSerialized] public ColorSpace colorSpace;
|
||||||
|
[NonSerialized] public LwguiGradient.ChannelMask viewChannelMask;
|
||||||
|
[NonSerialized] public LwguiGradient.GradientTimeRange gradientTimeRange;
|
||||||
|
|
||||||
|
private GUIView _viewToUpdate;
|
||||||
|
private Action<LwguiGradient> _onChange;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GUI Layout
|
||||||
|
|
||||||
|
private static readonly Vector2 _minWindowSize = new (750, 500);
|
||||||
|
private static readonly float _presetLibraryHeight = 100;
|
||||||
|
private Rect _gradientEditorRect => new Rect(0, 0, position.width, position.height - _presetLibraryHeight);
|
||||||
|
private Rect _presetLibraryRect => new Rect(0, position.height - _presetLibraryHeight, position.width, _presetLibraryHeight);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static LwguiGradientWindow instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!_lwguiGradientWindow)
|
||||||
|
Debug.LogError("Lwgui Gradient Window not initalized, did you call Show first?");
|
||||||
|
return _lwguiGradientWindow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string currentPresetLibrary
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Init(false);
|
||||||
|
return _lwguiGradientLibraryEditor.currentLibraryWithoutExtension;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Init(false);
|
||||||
|
_lwguiGradientLibraryEditor.currentLibraryWithoutExtension = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool visible => _lwguiGradientWindow != null;
|
||||||
|
|
||||||
|
public void Init(bool force = true, bool forceRecreate = false)
|
||||||
|
{
|
||||||
|
if (_lwguiGradientEditor == null || force || forceRecreate)
|
||||||
|
{
|
||||||
|
if (_lwguiGradientEditor == null || forceRecreate)
|
||||||
|
{
|
||||||
|
_lwguiGradientEditor = new LwguiGradientEditor();
|
||||||
|
}
|
||||||
|
_lwguiGradientEditor.Init(_gradientEditorRect, lwguiGradient, colorSpace, viewChannelMask, gradientTimeRange, _onChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_LwguiGradientLibraryEditorState == null || forceRecreate)
|
||||||
|
{
|
||||||
|
_LwguiGradientLibraryEditorState = new PresetLibraryEditorState(presetsEditorPrefID);
|
||||||
|
_LwguiGradientLibraryEditorState.TransferEditorPrefsState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lwguiGradientLibraryEditor == null || force || forceRecreate)
|
||||||
|
{
|
||||||
|
if (_lwguiGradientLibraryEditor == null || forceRecreate)
|
||||||
|
{
|
||||||
|
var saveLoadHelper = new ScriptableObjectSaveLoadHelper<LwguiGradientPresetLibrary>("lwguigradients", SaveType.Text);
|
||||||
|
_lwguiGradientLibraryEditor = new PresetLibraryLwguiGradientEditor(saveLoadHelper, _LwguiGradientLibraryEditorState, PresetClickedCallback);
|
||||||
|
UpdatePresetLibraryViewSettings();
|
||||||
|
}
|
||||||
|
_lwguiGradientLibraryEditor.showHeader = true;
|
||||||
|
_lwguiGradientLibraryEditor.minMaxPreviewHeight = new Vector2(14f, 14f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdatePresetLibraryViewSettings()
|
||||||
|
{
|
||||||
|
_lwguiGradientLibraryEditor.colorSpace = _lwguiGradientEditor.colorSpace;
|
||||||
|
_lwguiGradientLibraryEditor.viewChannelMask = _lwguiGradientEditor.viewChannelMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to modify the LwguiGradient value externally, such as: Undo/Redo/Select Preset
|
||||||
|
public static void UpdateCurrentGradient(LwguiGradient newGradient, bool doDeepCopy = false)
|
||||||
|
{
|
||||||
|
if (_lwguiGradientWindow == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (doDeepCopy)
|
||||||
|
{
|
||||||
|
_lwguiGradientWindow.lwguiGradient.DeepCopyFrom(newGradient);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_lwguiGradientWindow.lwguiGradient = newGradient;
|
||||||
|
}
|
||||||
|
// Debug.Log("Update");
|
||||||
|
_lwguiGradientWindow.Init();
|
||||||
|
_lwguiGradientWindow.Repaint();
|
||||||
|
GUI.changed = true;
|
||||||
|
LwguiGradientHelper.ClearRampPreviewCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LwguiGradientWindow GetWindow(bool focus = true) => (LwguiGradientWindow)GetWindow(typeof(LwguiGradientWindow), true, "LWGUI Gradient Editor", focus);
|
||||||
|
|
||||||
|
internal static void Show(LwguiGradient gradient, ColorSpace colorSpace = ColorSpace.Gamma, LwguiGradient.ChannelMask viewChannelMask = LwguiGradient.ChannelMask.All, LwguiGradient.GradientTimeRange timeRange = LwguiGradient.GradientTimeRange.One, GUIView viewToUpdate = null, Action<LwguiGradient> onChange = null)
|
||||||
|
{
|
||||||
|
if (_lwguiGradientWindow == null)
|
||||||
|
{
|
||||||
|
_lwguiGradientWindow = GetWindow();
|
||||||
|
_lwguiGradientWindow.minSize = _minWindowSize;
|
||||||
|
_lwguiGradientWindow.RegisterEvents();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_lwguiGradientWindow = GetWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
_lwguiGradientWindow.lwguiGradient = gradient;
|
||||||
|
_lwguiGradientWindow.colorSpace = colorSpace;
|
||||||
|
_lwguiGradientWindow.viewChannelMask = viewChannelMask;
|
||||||
|
_lwguiGradientWindow.gradientTimeRange = timeRange;
|
||||||
|
_lwguiGradientWindow._viewToUpdate = viewToUpdate;
|
||||||
|
_lwguiGradientWindow._onChange = onChange;
|
||||||
|
|
||||||
|
_lwguiGradientWindow.Init();
|
||||||
|
_lwguiGradientWindow.Show();
|
||||||
|
// window.ShowAuxWindow();
|
||||||
|
|
||||||
|
LwguiGradientHelper.ClearRampPreviewCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CloseWindow()
|
||||||
|
{
|
||||||
|
if (_lwguiGradientWindow == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lwguiGradientWindow.UnregisterEvents();
|
||||||
|
_lwguiGradientWindow.Close();
|
||||||
|
// GUIUtility.ExitGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RepaintWindow()
|
||||||
|
{
|
||||||
|
if (_lwguiGradientWindow == null)
|
||||||
|
return;
|
||||||
|
_lwguiGradientWindow.Repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterSerializedObjectUndo(Object targetObject)
|
||||||
|
{
|
||||||
|
Undo.RegisterCompleteObjectUndo(targetObject, "Lwgui Gradient Editor");
|
||||||
|
EditorUtility.SetDirty(targetObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterRampMapUndo(Object texture, Object assetImporter)
|
||||||
|
{
|
||||||
|
Undo.RecordObjects(new Object[]{ texture, assetImporter }, "Set Lwgui Gradient To Texture");
|
||||||
|
EditorUtility.SetDirty(texture);
|
||||||
|
EditorUtility.SetDirty(assetImporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
if (lwguiGradient == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Init(false);
|
||||||
|
|
||||||
|
// Separator
|
||||||
|
EditorGUI.DrawRect(new Rect(_presetLibraryRect.x, _presetLibraryRect.y - 1, _presetLibraryRect.width, 1), new Color(0, 0, 0, 0.3f));
|
||||||
|
EditorGUI.DrawRect(new Rect(_presetLibraryRect.x, _presetLibraryRect.y, _presetLibraryRect.width, 1), new Color(1, 1, 1, 0.1f));
|
||||||
|
|
||||||
|
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
_lwguiGradientEditor.OnGUI(_gradientEditorRect);
|
||||||
|
_lwguiGradientLibraryEditor.OnGUI(_presetLibraryRect, lwguiGradient);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
LwguiGradientHelper.ClearRampPreviewCaches();
|
||||||
|
UpdatePresetLibraryViewSettings();
|
||||||
|
SendEvent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string LwguiGradientChangedCommand = "LwguiGradientChanged";
|
||||||
|
|
||||||
|
void SendEvent(bool exitGUI)
|
||||||
|
{
|
||||||
|
if (_viewToUpdate != null)
|
||||||
|
{
|
||||||
|
Event e = EditorGUIUtility.CommandEvent(LwguiGradientChangedCommand);
|
||||||
|
Repaint();
|
||||||
|
_viewToUpdate.SendEvent(e);
|
||||||
|
if (exitGUI)
|
||||||
|
GUIUtility.ExitGUI();
|
||||||
|
}
|
||||||
|
if (_onChange != null)
|
||||||
|
{
|
||||||
|
_onChange(lwguiGradient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
Application.logMessageReceived += LwguiGradientEditor.CheckAddGradientKeyFailureLog;
|
||||||
|
hideFlags = HideFlags.DontSave;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
Application.logMessageReceived -= LwguiGradientEditor.CheckAddGradientKeyFailureLog;
|
||||||
|
|
||||||
|
_LwguiGradientLibraryEditorState?.TransferEditorPrefsState(false);
|
||||||
|
|
||||||
|
UnregisterEvents();
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
UnregisterEvents();
|
||||||
|
_lwguiGradientLibraryEditor?.UnloadUsedLibraries();
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Clear()
|
||||||
|
{
|
||||||
|
_lwguiGradientEditor = null;
|
||||||
|
_lwguiGradientWindow = null;
|
||||||
|
_lwguiGradientLibraryEditor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterEvents()
|
||||||
|
{
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
Undo.undoRedoEvent += OnUndoPerformed;
|
||||||
|
#endif
|
||||||
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnregisterEvents()
|
||||||
|
{
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
Undo.undoRedoEvent -= OnUndoPerformed;
|
||||||
|
#endif
|
||||||
|
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Call Backs
|
||||||
|
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
private void OnUndoPerformed(in UndoRedoInfo info)
|
||||||
|
{
|
||||||
|
// Debug.Log("Init");
|
||||||
|
_lwguiGradientWindow.Init();
|
||||||
|
_lwguiGradientWindow.Repaint();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void OnPlayModeStateChanged(PlayModeStateChange state)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetClickedCallback(int clickCount, object presetObject)
|
||||||
|
{
|
||||||
|
LwguiGradient gradient = presetObject as LwguiGradient;
|
||||||
|
if (gradient == null)
|
||||||
|
Debug.LogError("Incorrect object passed " + presetObject);
|
||||||
|
|
||||||
|
UpdateCurrentGradient(gradient, true);
|
||||||
|
// UnityEditorInternal.GradientPreviewCache.ClearCache();
|
||||||
|
// LwguiGradientHelper.ClearRampPreviewCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 097db44e7f52445b80daf9c3c3e9f26b
|
||||||
|
timeCreated: 1716795885
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/README.md
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/README.md
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
7
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/README.md.meta
vendored
Normal file
7
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/README.md.meta
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5d0d1d146a4108b4ebb49ce891131f50
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
242
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/ReflectionHelper.cs
vendored
Normal file
242
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/UnityEditorExtension/ReflectionHelper.cs
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace LWGUI
|
||||||
|
{
|
||||||
|
public static class ReflectionHelper
|
||||||
|
{
|
||||||
|
#region MaterialPropertyHandler
|
||||||
|
|
||||||
|
private static readonly Type MaterialPropertyHandler_Type = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.MaterialPropertyHandler");
|
||||||
|
private static readonly MethodInfo MaterialPropertyHandler_GetHandler_Method = MaterialPropertyHandler_Type.GetMethod("GetHandler", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
private static readonly PropertyInfo MaterialPropertyHandler_PropertyDrawer_Property = MaterialPropertyHandler_Type.GetProperty("propertyDrawer");
|
||||||
|
private static readonly FieldInfo MaterialPropertyHandler_DecoratorDrawers_Field = MaterialPropertyHandler_Type.GetField("m_DecoratorDrawers", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
|
||||||
|
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop, out List<MaterialPropertyDrawer> decoratorDrawers)
|
||||||
|
{
|
||||||
|
decoratorDrawers = new List<MaterialPropertyDrawer>();
|
||||||
|
var handler = MaterialPropertyHandler_GetHandler_Method.Invoke(null, new object[] { shader, prop.name });
|
||||||
|
if (handler != null && handler.GetType() == MaterialPropertyHandler_Type)
|
||||||
|
{
|
||||||
|
decoratorDrawers = MaterialPropertyHandler_DecoratorDrawers_Field.GetValue(handler) as List<MaterialPropertyDrawer>;
|
||||||
|
return MaterialPropertyHandler_PropertyDrawer_Property.GetValue(handler, null) as MaterialPropertyDrawer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop)
|
||||||
|
{
|
||||||
|
return GetPropertyDrawer(shader, prop, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region MaterialEditor
|
||||||
|
|
||||||
|
public static float DoPowerRangeProperty(Rect position, MaterialProperty prop, GUIContent label, float power)
|
||||||
|
{
|
||||||
|
return MaterialEditor.DoPowerRangeProperty(position, prop, label, power);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DefaultShaderPropertyInternal(this MaterialEditor editor, Rect position, MaterialProperty prop, GUIContent label)
|
||||||
|
{
|
||||||
|
editor.DefaultShaderPropertyInternal(position, prop, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Renderer> GetMeshRenderersByMaterialEditor(this MaterialEditor materialEditor)
|
||||||
|
{
|
||||||
|
var outRenderers = new List<Renderer>();
|
||||||
|
|
||||||
|
// MaterialEditor.ShouldEditorBeHidden()
|
||||||
|
PropertyEditor property = materialEditor.propertyViewer as PropertyEditor;
|
||||||
|
if (property)
|
||||||
|
{
|
||||||
|
GameObject gameObject = property.tracker.activeEditors[0].target as GameObject;
|
||||||
|
if (gameObject)
|
||||||
|
{
|
||||||
|
outRenderers.AddRange(gameObject.GetComponents<MeshRenderer>());
|
||||||
|
outRenderers.AddRange(gameObject.GetComponents<SkinnedMeshRenderer>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outRenderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region EditorUtility
|
||||||
|
|
||||||
|
public static void DisplayCustomMenuWithSeparators(Rect position, string[] options, bool[] enabled, bool[] separator, int[] selected, EditorUtility.SelectMenuItemFunction callback, object userData = null, bool showHotkey = false)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayCustomMenuWithSeparators(position, options, enabled, separator, selected, callback, userData, showHotkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region EditorGUI
|
||||||
|
|
||||||
|
public static float EditorGUI_Indent => EditorGUI.indentLevel;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region EditorGUILayout
|
||||||
|
|
||||||
|
public static float EditorGUILayout_kLabelFloatMinW => EditorGUILayout.kLabelFloatMinW;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region MaterialEnumDrawer
|
||||||
|
|
||||||
|
// UnityEditor.MaterialEnumDrawer(string enumName)
|
||||||
|
private static Type[] _types;
|
||||||
|
|
||||||
|
public static Type[] GetAllTypes()
|
||||||
|
{
|
||||||
|
if (_types == null)
|
||||||
|
{
|
||||||
|
_types = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
|
.SelectMany(assembly =>
|
||||||
|
{
|
||||||
|
if (assembly == null)
|
||||||
|
return Type.EmptyTypes;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return assembly.GetTypes();
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException ex)
|
||||||
|
{
|
||||||
|
Debug.LogError(ex);
|
||||||
|
return Type.EmptyTypes;
|
||||||
|
}
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _types;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region MaterialProperty.PropertyData
|
||||||
|
|
||||||
|
#if UNITY_2022_1_OR_NEWER
|
||||||
|
private static readonly Type MaterialProperty_Type = typeof(MaterialProperty);
|
||||||
|
private static readonly Type PropertyData_Type = MaterialProperty_Type.GetNestedType("PropertyData", BindingFlags.NonPublic);
|
||||||
|
private static readonly MethodInfo PropertyData_MergeStack_Method = PropertyData_Type.GetMethod("MergeStack", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
private static readonly MethodInfo PropertyData_HandleApplyRevert_Method = PropertyData_Type.GetMethod("HandleApplyRevert", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
public static void HandleApplyRevert(GenericMenu menu, MaterialProperty prop)
|
||||||
|
{
|
||||||
|
var parameters = new object[3];
|
||||||
|
PropertyData_MergeStack_Method.Invoke(null, parameters);
|
||||||
|
var overriden = (bool)parameters[2];
|
||||||
|
var singleEditing = prop.targets.Length == 1;
|
||||||
|
|
||||||
|
if (overriden)
|
||||||
|
{
|
||||||
|
PropertyData_HandleApplyRevert_Method.Invoke(null, new object[] { menu, singleEditing, prop.targets });
|
||||||
|
menu.AddSeparator("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GUI
|
||||||
|
|
||||||
|
private static readonly MethodInfo gui_Button_Method = typeof(GUI).GetMethod("Button", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
public static bool GUI_Button(Rect position, int id, GUIContent content, GUIStyle style)
|
||||||
|
{
|
||||||
|
return (bool)gui_Button_Method.Invoke(null, new object[] { position, id, content, style });
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GradientEditor
|
||||||
|
|
||||||
|
private static readonly FieldInfo k_MaxNumKeys_Field = typeof(GradientEditor).GetField("k_MaxNumKeys", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
public static readonly int maxGradientKeyCount = (int)k_MaxNumKeys_Field.GetValue(null);
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly FieldInfo m_SelectedSwatch_Field = typeof(GradientEditor).GetField("m_SelectedSwatch", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static GradientEditor.Swatch GetSelectedSwatch(this GradientEditor gradientEditor)
|
||||||
|
{
|
||||||
|
return m_SelectedSwatch_Field.GetValue(gradientEditor) as GradientEditor.Swatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetSelectedSwatch(this GradientEditor gradientEditor, GradientEditor.Swatch swatch)
|
||||||
|
{
|
||||||
|
m_SelectedSwatch_Field.SetValue(gradientEditor, swatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly FieldInfo m_RGBSwatches_Field = typeof(GradientEditor).GetField("m_RGBSwatches", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static List<GradientEditor.Swatch> GetRGBdSwatches(this GradientEditor gradientEditor)
|
||||||
|
{
|
||||||
|
return m_RGBSwatches_Field.GetValue(gradientEditor) as List<GradientEditor.Swatch>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly FieldInfo m_AlphaSwatches_Field = typeof(GradientEditor).GetField("m_AlphaSwatches", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static List<GradientEditor.Swatch> GetAlphaSwatches(this GradientEditor gradientEditor)
|
||||||
|
{
|
||||||
|
return m_AlphaSwatches_Field.GetValue(gradientEditor) as List<GradientEditor.Swatch>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static object s_Styles_Value;
|
||||||
|
private static readonly FieldInfo s_Styles_Field = typeof(GradientEditor).GetField("s_Styles", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
public static void GradientEditor_SetStyles()
|
||||||
|
{
|
||||||
|
s_Styles_Value ??= Activator.CreateInstance(typeof(GradientEditor).GetNestedType("Styles", BindingFlags.NonPublic));
|
||||||
|
s_Styles_Field.SetValue(null, s_Styles_Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly MethodInfo ShowSwatchArray_Method = typeof(GradientEditor)
|
||||||
|
.GetMethod("ShowSwatchArray", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Rect), typeof(List<GradientEditor.Swatch>), typeof(bool) }, null);
|
||||||
|
|
||||||
|
internal static void ShowSwatchArray(this GradientEditor gradientEditor, Rect position, List<GradientEditor.Swatch> swatches, bool isAlpha)
|
||||||
|
{
|
||||||
|
ShowSwatchArray_Method.Invoke(gradientEditor, new object[] { position, swatches, isAlpha });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly MethodInfo GetTime_Method = typeof(GradientEditor).GetMethod("GetTime", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static float GetTime(this GradientEditor gradientEditor, float actualTime)
|
||||||
|
{
|
||||||
|
return (float)GetTime_Method.Invoke(gradientEditor, new object[] { actualTime });
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CurveEditor
|
||||||
|
|
||||||
|
private static readonly FieldInfo m_CurveEditor_Field = typeof(CurveEditorWindow).GetField("m_CurveEditor", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static CurveEditor GetCurveEditor(this CurveEditorWindow curveEditorWindow)
|
||||||
|
{
|
||||||
|
return m_CurveEditor_Field.GetValue(curveEditorWindow) as CurveEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly MethodInfo AddKeyAtTime_Method = typeof(CurveEditor).GetMethod("AddKeyAtTime", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
internal static CurveSelection AddKeyAtTime(this CurveEditor curveEditor, CurveWrapper cw, float time)
|
||||||
|
{
|
||||||
|
return AddKeyAtTime_Method.Invoke(curveEditor, new object[] { cw, time }) as CurveSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Unity.InternalAPIEditorBridge.020",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"LWGUI.Runtime"
|
||||||
|
],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d40b1b73ac7645c43af711c92abd00b3
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) Jason Ma
|
||||||
|
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace LWGUI
|
||||||
|
{
|
||||||
|
public static class UnityEditorExtension
|
||||||
|
{
|
||||||
|
|
||||||
|
#region MaterialEditor
|
||||||
|
|
||||||
|
// For Developers: Call this after a material has modified in code
|
||||||
|
public static void ApplyMaterialPropertyAndDecoratorDrawers(Material material)
|
||||||
|
{
|
||||||
|
var objs = new Object[] { material };
|
||||||
|
ApplyMaterialPropertyAndDecoratorDrawers(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called after edit or undo
|
||||||
|
public static void ApplyMaterialPropertyAndDecoratorDrawers(Object[] targets)
|
||||||
|
{
|
||||||
|
if (!EditorMaterialUtility.disableApplyMaterialPropertyDrawers)
|
||||||
|
{
|
||||||
|
if (targets == null || targets.Length == 0)
|
||||||
|
return;
|
||||||
|
var target = targets[0] as Material;
|
||||||
|
if (target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var shader = target.shader;
|
||||||
|
string[] propNames = MaterialEditor.GetMaterialPropertyNames(targets);
|
||||||
|
for (int i = 0; i < propNames.Length; i++)
|
||||||
|
{
|
||||||
|
var prop = MaterialEditor.GetMaterialProperty(targets, i);
|
||||||
|
var drawer = ReflectionHelper.GetPropertyDrawer(shader, prop, out var decoratorDrawers);
|
||||||
|
|
||||||
|
if (drawer != null)
|
||||||
|
{
|
||||||
|
drawer.Apply(prop);
|
||||||
|
}
|
||||||
|
if (decoratorDrawers != null)
|
||||||
|
{
|
||||||
|
foreach (var decoratorDrawer in decoratorDrawers)
|
||||||
|
{
|
||||||
|
decoratorDrawer.Apply(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c461331302de45948d270b0842238473
|
||||||
|
timeCreated: 1726212440
|
||||||
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/package.json
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/Editor/ShaderGUI/LWGUI-main/package.json
(Stored with Git LFS)
vendored
Binary file not shown.
@ -18,9 +18,11 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
messages.Add("- Like URP14's Bloom but with more controls.\n" +
|
messages.Add("- Similar to URP's Bloom but with more controls\n" +
|
||||||
"- Can supplement or replace URP's Bloom.\n" +
|
"- Great for preventing character become over bloom\n" +
|
||||||
"* This Bloom is slower than URP's Bloom (GPU)");
|
"- Allows different setting for Character & non-Character pixels\n" +
|
||||||
|
"- Can supplement or replace URP's Bloom\n" +
|
||||||
|
"* This Bloom is slower than URP's Bloom (GPU), only recommended for PC/Console");
|
||||||
|
|
||||||
messages.Add(IsPostProcessMessage);
|
messages.Add(IsPostProcessMessage);
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace NiloToon.NiloToonURP
|
|||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
messages.Add(
|
messages.Add(
|
||||||
"- Great for helping NiloToon characters blend into any environment\n" +
|
"- Great for helping NiloToon characters to blend into any environment\n" +
|
||||||
"- Great for artist-controlled lighting and rim light on NiloToon characters");
|
"- Great for artist-controlled lighting and rim light on NiloToon characters");
|
||||||
|
|
||||||
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
||||||
|
|||||||
@ -19,10 +19,10 @@ namespace NiloToon.NiloToonURP
|
|||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
messages.Add(
|
messages.Add(
|
||||||
"Make NiloToon characters convert all received additional light into rim light.\n" +
|
"- Converts all received additional light into rim light for NiloToon characters\n" +
|
||||||
"Useful if you want characters to receive many bright additional lights,\n" +
|
"- Useful if you want characters to receive many bright additional lights,\n" +
|
||||||
"yet maintain a pleasing lighting effect, without becoming overly bright or unappealing.\n" +
|
" yet maintain a pleasing lighting effect, without becoming overly bright or unappealing.\n" +
|
||||||
"(e.g., ideal for concert stage live performances or cinematic cut scenes)"
|
"- Ideal for concert stage live performances or cinematic cut scenes"
|
||||||
);
|
);
|
||||||
|
|
||||||
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
||||||
|
|||||||
@ -18,6 +18,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
|
messages.Add("- For extra color control of NiloToon_Environment shader\n" +
|
||||||
|
"- Or for debug which material is using NiloToon_Environment shader" );
|
||||||
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
|
|||||||
30
Assets/External/NiloToonURP/Editor/Volume/NiloToonMotionBlurVolumeEditor.cs
vendored
Normal file
30
Assets/External/NiloToonURP/Editor/Volume/NiloToonMotionBlurVolumeEditor.cs
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NiloToon.NiloToonURP;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Rendering;
|
||||||
|
|
||||||
|
namespace NiloToon.NiloToonURP
|
||||||
|
{
|
||||||
|
[CanEditMultipleObjects]
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
[CustomEditor(typeof(NiloToonMotionBlurVolume))]
|
||||||
|
#else
|
||||||
|
[VolumeComponentEditor(typeof(NiloToonMotionBlurVolume))]
|
||||||
|
#endif
|
||||||
|
public class NiloToonMotionBlurVolumeEditor : NiloToonVolumeComponentEditor<NiloToonMotionBlurVolume>
|
||||||
|
{
|
||||||
|
// Override GetHelpBoxContent to provide specific help box content
|
||||||
|
protected override List<string> GetHelpBoxContent()
|
||||||
|
{
|
||||||
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
|
messages.Add(
|
||||||
|
"[Requires Unity2022.3 or above]\n" +
|
||||||
|
"- Cinematic object motion blur, usually used for character dance animations in music videos (MVs). It is better than URP's object motion blur but comes with a much higher GPU cost.\n" +
|
||||||
|
"- Recommended for PC/Console only");
|
||||||
|
messages.Add(IsPostProcessMessage);
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/External/NiloToonURP/Editor/Volume/NiloToonMotionBlurVolumeEditor.cs.meta
vendored
Normal file
11
Assets/External/NiloToonURP/Editor/Volume/NiloToonMotionBlurVolumeEditor.cs.meta
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2706839ba1d17584890ca7454f75e0ce
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -18,7 +18,12 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
messages.Add(NonPostProcess_NotAffectPerformance_Message);
|
messages.Add(
|
||||||
|
"- For producing NiloToon Character or Environment's screen space outline\n" +
|
||||||
|
"- Requires enabling 'Enable ScreenSpace Outline' in NiloToonAllInOne renderer feature\n" +
|
||||||
|
"- Requires temporal AA like TAA/STP/DLSS/XeSS/FSR... to produce stable result");
|
||||||
|
|
||||||
|
messages.Add(NonPostProcess_MayAffectPerformance_Message);
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,9 @@ namespace NiloToon.NiloToonURP
|
|||||||
List<string> messages = new List<string>();
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
messages.Add(
|
messages.Add(
|
||||||
"- If overridden, will use settings here instead of NiloToonAllInOneRendererFeature.\n" +
|
"- Great for controlling NiloToon characters' shadow results (e.g., shadow tint color)\n" +
|
||||||
"- If not overridden, will use NiloToonAllInOneRendererFeature's settings.");
|
"- When overridden, uses settings from here instead of NiloToonAllInOneRendererFeature\n" +
|
||||||
|
"- When not overridden, uses NiloToonAllInOneRendererFeature's settings");
|
||||||
|
|
||||||
messages.Add(NonPostProcess_MayAffectPerformance_Message);
|
messages.Add(NonPostProcess_MayAffectPerformance_Message);
|
||||||
|
|
||||||
|
|||||||
BIN
Assets/External/NiloToonURP/NiloToonURP user document.pdf
(Stored with Git LFS)
vendored
BIN
Assets/External/NiloToonURP/NiloToonURP user document.pdf
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a0890936ec94ed749881904e977d840d
|
guid: faa27ea2c11a8a34a99a3c5a2288129b
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user