Browse Source

True Shadow

master
laurids 3 years ago
parent
commit
914100b0a4
130 changed files with 5769 additions and 28 deletions
  1. +53
    -15
      Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab
  2. +40
    -12
      Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab
  3. +8
    -0
      Assets/Le Tai's Asset.meta
  4. +8
    -0
      Assets/Le Tai's Asset/TrueShadow.meta
  5. +13
    -0
      Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef
  6. +7
    -0
      Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef.meta
  7. BIN
      Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf
  8. +7
    -0
      Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf.meta
  9. +1
    -0
      Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt
  10. +7
    -0
      Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt.meta
  11. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources.meta
  12. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders.meta
  13. +103
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader
  14. +9
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader.meta
  15. +61
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader
  16. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader.meta
  17. +59
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader
  18. +9
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader.meta
  19. +69
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader
  20. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader.meta
  21. +54
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader
  22. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader.meta
  23. +56
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader
  24. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader.meta
  25. +54
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader
  26. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader.meta
  27. +54
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader
  28. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader.meta
  29. +62
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc
  30. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc.meta
  31. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts.meta
  32. +78
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs
  33. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs.meta
  34. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor.meta
  35. +33
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs
  36. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs.meta
  37. +59
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs
  38. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs.meta
  39. +67
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs
  40. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs.meta
  41. +184
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs
  42. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs.meta
  43. +16
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef
  44. +7
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef.meta
  45. +104
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs
  46. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs.meta
  47. +19
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs
  48. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs.meta
  49. +62
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs
  50. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs.meta
  51. +87
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs
  52. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs.meta
  53. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures.meta
  54. BIN
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png
  55. +130
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png.meta
  56. BIN
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png
  57. +130
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png.meta
  58. BIN
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png
  59. +130
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png.meta
  60. BIN
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png
  61. +130
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png.meta
  62. BIN
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png
  63. +128
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png.meta
  64. +104
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs
  65. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs.meta
  66. +22
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs
  67. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs.meta
  68. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects.meta
  69. +9
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs
  70. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs.meta
  71. +15
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs
  72. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs.meta
  73. +104
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs
  74. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs.meta
  75. +110
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs
  76. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs.meta
  77. +37
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs
  78. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs.meta
  79. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper.meta
  80. +138
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs
  81. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs.meta
  82. +69
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs
  83. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs.meta
  84. +242
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs
  85. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs.meta
  86. +40
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs
  87. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs.meta
  88. +312
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs
  89. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs.meta
  90. +76
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs
  91. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs.meta
  92. +189
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs
  93. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs.meta
  94. +139
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs
  95. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs.meta
  96. +193
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs
  97. +11
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs.meta
  98. +8
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Structure.meta
  99. +42
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs
  100. +3
    -0
      Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs.meta

+ 53
- 15
Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab View File

@ -60,6 +60,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.25490198, b: 0.14509805, a: 0.62352943}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -85,7 +86,7 @@ GameObject:
- component: {fileID: 2845208572781105551}
- component: {fileID: 6883330568249547342}
- component: {fileID: 7197385088179281400}
- component: {fileID: 5556159197701511021}
- component: {fileID: 3216987783940624451}
m_Layer: 5
m_Name: FactionIcon
m_TagString: Untagged
@ -135,6 +136,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -149,7 +151,7 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &5556159197701511021
--- !u!114 &3216987783940624451
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -158,12 +160,25 @@ MonoBehaviour:
m_GameObject: {fileID: 1004975018085727846}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.6431373}
m_EffectDistance: {x: 1, y: -1}
m_UseGraphicAlpha: 1
size: 3.48
spread: 0.916
offsetAngle: 90
offsetDistance: 8
offset: {x: 0, y: 0}
color: {r: 0, g: 0, b: 0, a: 1}
inset: 0
blendMode: 0
useCasterAlpha: 1
ignoreCasterColor: 0
colorBleedMode: 0
shadowAsSibling: 0
cutout: 0
baked: 0
modifiedFromInspector: 0
bakedShadows: []
--- !u!1 &1425561383975781025
GameObject:
m_ObjectHideFlags: 0
@ -224,6 +239,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.25490198, b: 0.14509805, a: 0.62352943}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -298,6 +314,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -348,7 +365,7 @@ RectTransform:
- {fileID: 1577843074573127529}
- {fileID: 5933915466098524944}
m_Father: {fileID: 7384831771431062766}
m_RootOrder: 1
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@ -526,6 +543,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0.8901961, b: 0.5686275, a: 0.62352943}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -600,6 +618,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -674,6 +693,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -699,7 +719,7 @@ GameObject:
- component: {fileID: 7493439069602050584}
- component: {fileID: 8817467615109816757}
- component: {fileID: 8517481495962601137}
- component: {fileID: 8442851035215243681}
- component: {fileID: 5092933628985013823}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
@ -719,7 +739,7 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 7384831771431062766}
m_RootOrder: 0
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@ -749,6 +769,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.688, g: 0.688, b: 0.688, a: 1}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -767,7 +788,7 @@ MonoBehaviour:
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: MENAXURIE
--- !u!114 &8442851035215243681
--- !u!114 &5092933628985013823
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -776,12 +797,25 @@ MonoBehaviour:
m_GameObject: {fileID: 3536075192841412823}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414}
m_EffectDistance: {x: 2, y: -2}
m_UseGraphicAlpha: 1
size: 3.48
spread: 0.916
offsetAngle: 90
offsetDistance: 8
offset: {x: 0, y: 0}
color: {r: 0, g: 0, b: 0, a: 1}
inset: 0
blendMode: 0
useCasterAlpha: 1
ignoreCasterColor: 0
colorBleedMode: 0
shadowAsSibling: 0
cutout: 0
baked: 0
modifiedFromInspector: 0
bakedShadows: []
--- !u!1 &4082808148708746503
GameObject:
m_ObjectHideFlags: 0
@ -842,6 +876,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -916,6 +951,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0.8901961, b: 0.5686275, a: 0.62352943}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -1027,6 +1063,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -1146,8 +1183,8 @@ RectTransform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 7493439069602050584}
- {fileID: 3206999086042524838}
- {fileID: 7493439069602050584}
- {fileID: 6852626612145593344}
m_Father: {fileID: 0}
m_RootOrder: 0
@ -1314,6 +1351,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0.64446914, b: 0.2688679, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:


+ 40
- 12
Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab View File

@ -11,7 +11,7 @@ GameObject:
- component: {fileID: 7541130419680964749}
- component: {fileID: 7541130419680964747}
- component: {fileID: 7541130419680964746}
- component: {fileID: 6281905439376641608}
- component: {fileID: 5485887525763253888}
m_Layer: 5
m_Name: PlanetIndicatorDistrictSymbol
m_TagString: Untagged
@ -62,6 +62,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -76,7 +77,7 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &6281905439376641608
--- !u!114 &5485887525763253888
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -85,12 +86,25 @@ MonoBehaviour:
m_GameObject: {fileID: 7541130419680964748}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414}
m_EffectDistance: {x: 1, y: -1}
m_UseGraphicAlpha: 1
size: 3.48
spread: 0.916
offsetAngle: 90
offsetDistance: 8
offset: {x: 0, y: 0}
color: {r: 0, g: 0, b: 0, a: 1}
inset: 0
blendMode: 0
useCasterAlpha: 1
ignoreCasterColor: 0
colorBleedMode: 0
shadowAsSibling: 0
cutout: 0
baked: 0
modifiedFromInspector: 0
bakedShadows: []
--- !u!1 &8644822413282706300
GameObject:
m_ObjectHideFlags: 0
@ -102,7 +116,7 @@ GameObject:
- component: {fileID: 5640206779338511740}
- component: {fileID: 8489971881928985428}
- component: {fileID: 2380150125148524420}
- component: {fileID: 7035351003660383945}
- component: {fileID: 1054513047492580219}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
@ -152,6 +166,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@ -166,7 +181,7 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &7035351003660383945
--- !u!114 &1054513047492580219
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -175,9 +190,22 @@ MonoBehaviour:
m_GameObject: {fileID: 8644822413282706300}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414}
m_EffectDistance: {x: 0.5, y: -0.5}
m_UseGraphicAlpha: 1
size: 3.48
spread: 0.916
offsetAngle: 90
offsetDistance: 8
offset: {x: 0, y: 0}
color: {r: 0, g: 0, b: 0, a: 1}
inset: 0
blendMode: 0
useCasterAlpha: 1
ignoreCasterColor: 0
colorBleedMode: 0
shadowAsSibling: 0
cutout: 0
baked: 0
modifiedFromInspector: 0
bakedShadows: []

+ 8
- 0
Assets/Le Tai's Asset.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e65753410138a4801a6caf79d625ccd1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 345755c04661c49208b308ceef47c557
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 13
- 0
Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef View File

@ -0,0 +1,13 @@
{
"name": "LeTai.TrueShadow",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

+ 7
- 0
Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef.meta View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7ab3663edede26740845931880bf22af
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf View File


+ 7
- 0
Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf.meta View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c4e2187761ed8294780562fc58e8205e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 1
- 0
Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt View File

@ -0,0 +1 @@
https://leloctai.com/trueshadow/docs/

+ 7
- 0
Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt.meta View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 63a70f84fa489504abf9f477bd12d05e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Resources.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d5929e1d292a9d84180571372bbb84f6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 316e6d240db2e974d97ea072bee96163
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 103
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader View File

@ -0,0 +1,103 @@
Shader "Hidden/EfficientBlur"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
half4 _MainTex_TexelSize;
half4 _MainTex_ST;
uniform half _Radius;
struct v2f
{
half4 vertex : SV_POSITION;
half4 texcoord : TEXCOORD0;
};
/*struct appdata
{
half4 vertex : POSITION;
half2 texcoord: TEXCOORD0;
}*/
v2f vert(appdata_img v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
half4 offset = half2(-0.5h, 0.5h).xxyy; //-x, -y, x, y
offset *= _MainTex_TexelSize.xyxy;
offset *= _Radius;
o.texcoord = v.texcoord.xyxy + offset;
return o;
}
half4 frag(v2f i) : SV_Target
{
// half4 o =
// tex2D(_MainTex, i.texcoord.xw);
// o += tex2D(_MainTex, i.texcoord.zw);
// o += tex2D(_MainTex, i.texcoord.xy);
// o += tex2D(_MainTex, i.texcoord.zy);
// o /= 4.0;
//Pray to the compiler god these will MAD
half4 o =
tex2D(_MainTex, i.texcoord.xw) / 4.0h;
o += tex2D(_MainTex, i.texcoord.zw) / 4.0h;
o += tex2D(_MainTex, i.texcoord.xy) / 4.0h;
o += tex2D(_MainTex, i.texcoord.zy) / 4.0h;
return o;
}
ENDCG
SubShader
{
Cull Off ZWrite Off ZTest Always Blend Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
Pass
{
CGPROGRAM
//Crop before blur
#pragma vertex vertCrop
#pragma fragment frag
half4 _CropRegion;
half2 getNewUV(half2 oldUV)
{
return lerp(_CropRegion.xy, _CropRegion.zw, oldUV);
}
v2f vertCrop(appdata_img v)
{
v2f o = vert(v);
o.texcoord.xy = getNewUV(o.texcoord.xy);
o.texcoord.zw = getNewUV(o.texcoord.zw);
return o;
}
ENDCG
}
}
FallBack Off
}

+ 9
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader.meta View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 11ecd49e831fe6c4f8f68b583206390c
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

+ 61
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader View File

@ -0,0 +1,61 @@
Shader "Hidden/TrueShadow/ImprintPostProcess"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local __ BLEACH
#pragma multi_compile_local __ INSET
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
half4 frag(v2f i) : SV_Target
{
#if BLEACH
half4 color = half4(1,1,1, tex2D(_MainTex, i.uv).a);
#else
half4 color = tex2D(_MainTex, i.uv);
#endif
#if INSET
color.a = 1 - color.a;
#endif
color.rgb*=color.a;
return color;
}
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56c6b737089145c590ee9874dc3c09f7
timeCreated: 1602477197

+ 59
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader View File

@ -0,0 +1,59 @@
Shader "Hidden/TrueShadow/Cutout"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Offset ("Offset", Vector) = (0,0,0,0)
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Blend Zero OneMinusSrcAlpha, Zero OneMinusSrcAlpha
BlendOp Add, Add
// ColorMask a
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
uniform sampler2D _MainTex;
uniform float2 _Offset;
uniform float _OverflowAlpha;
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv + _Offset;
if (any(uv > 1) || any(uv < 0))
return _OverflowAlpha;
return fixed4(0, 0, 0, tex2D(_MainTex, uv).a);
}
ENDCG
}
}
}

+ 9
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader.meta View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 77361e944e5710f4993a94af0720a22f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

+ 69
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader View File

@ -0,0 +1,69 @@
Shader "Hidden/TrueShadow/PostProcess"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Offset ("Offset", Vector) = (0,0,0,0)
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
uniform sampler2D _ShadowTex;
uniform sampler2D _MainTex;
uniform float2 _Offset;
uniform float _OverflowAlpha;
uniform float _AlphaMultiplier;
fixed4 frag(v2f i) : SV_Target
{
half4 shadow = tex2D(_ShadowTex, i.uv);
half alpha = shadow.a;
half alphaBoosted = saturate(alpha * _AlphaMultiplier);
shadow.a = alphaBoosted;
shadow.rgb = shadow.rgb / alpha * alphaBoosted;
float cutOut;
float2 cutoutUv = i.uv + _Offset;
if (any(cutoutUv > 1) || any(cutoutUv < 0))
cutOut = _OverflowAlpha;
else
cutOut = tex2D(_MainTex, cutoutUv).a;
shadow *= 1 - cutOut;
return shadow;
}
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 64f3fdefd5e7411dae947574155e2253
timeCreated: 1614411795

+ 54
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader View File

@ -0,0 +1,54 @@
Shader "UI/TrueShadow-Additive"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend One One
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#include "TrueShadow.cginc"
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6c0e0b60ad64412c8cfcffd1553dcc06
timeCreated: 1594096623

+ 56
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader View File

@ -0,0 +1,56 @@
Shader "UI/TrueShadow-Multiply"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend DstColor Zero
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#define DO_BLEND_POSTPROCESS color.rgb = 1 - color.a + color.rgb;
#include "TrueShadow.cginc"
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 84318cb7c8604c59a985a677d93e4048
timeCreated: 1594096631

+ 54
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader View File

@ -0,0 +1,54 @@
Shader "UI/TrueShadow-Normal"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend One OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#include "TrueShadow.cginc"
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d81692c4b57a49aabf43f3423dc99e51
timeCreated: 1594094098

+ 54
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader View File

@ -0,0 +1,54 @@
Shader "UI/TrueShadow-Screen"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend OneMinusDstColor One
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#include "TrueShadow.cginc"
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f15b379e29b64cb1ae050f22d002148a
timeCreated: 1610185734

+ 62
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc View File

@ -0,0 +1,62 @@
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color.a = v.color.a;
OUT.color.rgb = v.color.rgb * v.color.a;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
float4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
#ifdef DO_BLEND_POSTPROCESS
DO_BLEND_POSTPROCESS
#endif
return color;
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3521747ea3d847a58d919a5a4d9f0fc6
timeCreated: 1594096488

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: adf483f749616b14ab22fc1bac9a154e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 78
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs View File

@ -0,0 +1,78 @@
#if LETAI_TRUESHADOW_DEBUG
using System;
using UnityEngine;
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
namespace LeTai.TrueShadow
{
[Serializable]
public class DebugSettings
{
const string FILE_PATH = "ProjectSettings/TrueShadowDebugSettings.json";
static DebugSettings instance;
public static DebugSettings Instance
{
get
{
if (instance == null)
{
#if UNITY_EDITOR
try
{
if (File.Exists(FILE_PATH))
instance = JsonUtility.FromJson<DebugSettings>(File.ReadAllText(FILE_PATH));
else
Create();
}
catch (Exception)
{
Create();
}
#else
Create();
#endif
}
return instance;
}
}
static void Create()
{
instance = new DebugSettings();
instance.Save();
}
public bool showObjects = true;
void Save()
{
#if UNITY_EDITOR
File.WriteAllText(FILE_PATH, JsonUtility.ToJson(this, true));
#endif
}
#if UNITY_EDITOR
[MenuItem("Tools/Show Objects")]
static void ShowObjects()
{
Instance.showObjects = true;
Instance.Save();
}
[MenuItem("Tools/Hide Objects")]
static void HideObjects()
{
Instance.showObjects = false;
Instance.Save();
}
#endif
}
}
#endif

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15f8726536514604185aa6c94cb75b8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 711abe41546958b459a552baad798f17
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 33
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs View File

@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace LeTai.TrueShadow.Editor
{
[InitializeOnLoad]
public static class AutoCustomScriptingDefine
{
internal static readonly HashSet<string> SYMBOLS = new HashSet<string> {"LETAI_TRUESHADOW"};
static AutoCustomScriptingDefine()
{
Apply();
}
public static void Apply()
{
AddMissingSymbols(EditorUserBuildSettings.activeBuildTarget);
}
static void AddMissingSymbols(BuildTarget buildTarget)
{
var currentGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentGroup).Split(';').ToList();
var missing = SYMBOLS.Except(defines).ToList();
defines.AddRange(missing);
if (missing.Count > 0)
PlayerSettings.SetScriptingDefineSymbolsForGroup(currentGroup, string.Join(";", defines));
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 150508a406864b6ca9ad4e38e75cb333
timeCreated: 1597477199

+ 59
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs View File

@ -0,0 +1,59 @@
using System;
using System.Globalization;
using System.Reflection;
using UnityEditor;
namespace LeTai.TrueShadow.Editor
{
public class EditorProperty
{
public readonly SerializedProperty serializedProperty;
readonly SerializedObject serializedObject;
readonly MethodInfo propertySetter;
readonly SerializedProperty dirtyFlag;
public EditorProperty(SerializedObject obj, string name)
{
var propertyName = char.ToLowerInvariant(name[0]) + name.Substring(1);
serializedObject = obj;
serializedProperty = serializedObject.FindProperty(propertyName);
propertySetter = serializedObject.targetObject.GetType().GetProperty(name).SetMethod;
dirtyFlag = serializedObject.FindProperty("modifiedFromInspector");
}
public void Draw()
{
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.PropertyField(serializedProperty);
if (!scope.changed)
return;
dirtyFlag.boolValue = true;
serializedObject.ApplyModifiedProperties();
foreach (var target in serializedObject.targetObjects)
{
switch (serializedProperty.propertyType)
{
case SerializedPropertyType.Float:
propertySetter.Invoke(target, new object[] {serializedProperty.floatValue});
break;
case SerializedPropertyType.Enum:
propertySetter.Invoke(target, new object[] {serializedProperty.enumValueIndex});
break;
case SerializedPropertyType.Boolean:
propertySetter.Invoke(target, new object[] {serializedProperty.boolValue});
break;
case SerializedPropertyType.Color:
propertySetter.Invoke(target, new object[] {serializedProperty.colorValue});
break;
default: throw new NotImplementedException();
}
}
}
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1f9db8b2544c48c2a7f13b46f27236e8
timeCreated: 1594635819

+ 67
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs View File

@ -0,0 +1,67 @@
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(InsetToggleAttribute))]
public class InsetToggle : InlineToolbar
{
static readonly Texture OUTER_SHADOW_TEXTURE = Utility.FindAsset<Texture>("Outer Shadow");
static readonly Texture INNER_SHADOW_TEXTURE = Utility.FindAsset<Texture>("Inner Shadow");
static InsetToggle()
{
textures = new[] {OUTER_SHADOW_TEXTURE, INNER_SHADOW_TEXTURE};
}
}
public class InlineToolbar : PropertyDrawer
{
protected static Texture[] textures;
static readonly GUIStyle LABEL_STYLE = new GUIStyle(EditorStyles.label)
{alignment = TextAnchor.MiddleLeft,};
public override void OnGUI(Rect position, SerializedProperty property,
GUIContent label)
{
using (var propScope = new EditorGUI.PropertyScope(position, label, property))
{
int id = GUIUtility.GetControlID(FocusType.Keyboard, position);
var lableRect = position;
lableRect.y += (lableRect.height - EditorGUIUtility.singleLineHeight) / 2;
lableRect.height = EditorGUIUtility.singleLineHeight;
var toolbarRect = EditorGUI.PrefixLabel(lableRect, id, propScope.content, LABEL_STYLE);
toolbarRect.width = EditorGUIUtility.singleLineHeight * 4f;
toolbarRect.height = position.height;
toolbarRect.y = position.y;
using (var changeScope = new EditorGUI.ChangeCheckScope())
{
var isOn = GUI.Toolbar(toolbarRect, property.boolValue ? 1 : 0, textures) == 1;
var changed = changeScope.changed;
if (Event.current.type == EventType.KeyDown &&
GUIUtility.keyboardControl == id)
{
if (Event.current.keyCode == KeyCode.Return ||
Event.current.keyCode == KeyCode.KeypadEnter ||
Event.current.keyCode == KeyCode.Space)
{
changed = GUI.changed = true;
isOn = !isOn;
}
}
if (changed)
property.boolValue = isOn;
}
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight * 2f;
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ea4346ac17c04991bf233f1dc0def012
timeCreated: 1602580020

+ 184
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs View File

@ -0,0 +1,184 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using static LeTai.TrueShadow.Math;
using EGU = UnityEditor.EditorGUIUtility;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(KnobAttribute))]
public class KnobPropertyDrawer : PropertyDrawer
{
public static bool procrastinationMode = false;
static readonly Texture2D KNOB_BG_TEXTURE = Utility.FindAsset<Texture2D>("Knob_BG");
static readonly Texture2D KNOB_FG_TEXTURE = Utility.FindAsset<Texture2D>("Knob_FG");
static readonly MethodInfo DO_FLOAT_FIELD_METHOD;
static readonly FieldInfo RECYCLED_EDITOR_PROPERTY;
static readonly FieldInfo FLOAT_FIELD_FORMAT_STRING_CONST;
static readonly Color KNOB_BG_COLOR;
static readonly Color KNOB_FG_COLOR;
static readonly Color KNOB_FG_COLOR_ACTIVE;
static KnobPropertyDrawer()
{
var editorGUIType = typeof(EditorGUI);
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static;
Type[] argumentTypes = {
Assembly.GetAssembly(editorGUIType).GetType("UnityEditor.EditorGUI+RecycledTextEditor"),
typeof(Rect),
typeof(Rect),
typeof(int),
typeof(float),
typeof(string),
typeof(GUIStyle),
typeof(bool)
};
DO_FLOAT_FIELD_METHOD = editorGUIType.GetMethod("DoFloatField", flags, null, argumentTypes, null);
RECYCLED_EDITOR_PROPERTY = editorGUIType.GetField("s_RecycledEditor", flags);
FLOAT_FIELD_FORMAT_STRING_CONST = editorGUIType.GetField("kFloatFieldFormatString", flags);
if (EGU.isProSkin)
{
KNOB_BG_COLOR = new Color(.164f, .164f, .164f);
KNOB_FG_COLOR = new Color(.701f, .701f, .701f);
KNOB_FG_COLOR_ACTIVE = new Color(.49f, .67f, .94f);
}
else
{
KNOB_BG_COLOR = new Color(.941f, .941f, .941f);
KNOB_FG_COLOR = new Color(.239f, .239f, .239f);
KNOB_FG_COLOR_ACTIVE = new Color(.054f, .274f, .549f);
}
}
static float DoFloatFieldInternal(Rect position,
Rect dragHotZone,
int id,
float value,
string formatString = null,
GUIStyle style = null,
bool draggable = true)
{
style = style ?? EditorStyles.numberField;
formatString = formatString ?? (string) FLOAT_FIELD_FORMAT_STRING_CONST.GetValue(null);
var editor = RECYCLED_EDITOR_PROPERTY.GetValue(null);
return (float) DO_FLOAT_FIELD_METHOD.Invoke(null, new[] {
editor,
position,
dragHotZone,
id,
value,
formatString,
style,
draggable
});
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (!(attribute is KnobAttribute)) return;
KnobProperty(position, label, property, Vector2.right);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return ControlHeight;
}
static float ControlHeight => EGU.singleLineHeight * 2.0f;
static float KnobSize => EGU.singleLineHeight * 2.5f;
static float KnobYOffset => (ControlHeight - KnobSize) / 2;
static Color Lighten(Color color, float amount)
{
Color.RGBToHSV(color, out var h, out var s, out var v);
return Color.HSVToRGB(h, s, v + amount);
}
public static void KnobProperty(Rect rect, GUIContent label, SerializedProperty prop, Vector2 zeroVector)
{
float angle = prop.floatValue;
float prevAngle = angle;
using (var propScope = new EditorGUI.PropertyScope(rect, label, prop))
using (var changeScope = new EditorGUI.ChangeCheckScope())
{
var labelRect = new Rect(rect) {
y = rect.y + (ControlHeight - EGU.singleLineHeight) / 2,
height = EGU.singleLineHeight
};
int fieldId = GUIUtility.GetControlID(FocusType.Keyboard, labelRect);
var fieldRect = EditorGUI.PrefixLabel(labelRect, fieldId, propScope.content);
labelRect.xMax = fieldRect.x;
fieldRect.x += ControlHeight;
fieldRect.width -= ControlHeight;
Rect knobRect = new Rect(rect.x + EGU.labelWidth + KnobYOffset,
rect.y + KnobYOffset,
KnobSize, KnobSize);
int knobId = GUIUtility.GetControlID(FocusType.Passive, knobRect);
if (Event.current != null)
{
if (Event.current.type == EventType.MouseDown && knobRect.Contains(Event.current.mousePosition))
{
GUIUtility.hotControl = knobId;
angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center);
}
else if (Event.current.type == EventType.MouseUp && GUIUtility.hotControl == knobId)
{
GUIUtility.hotControl = 0;
}
else if (Event.current.type == EventType.MouseDrag && GUIUtility.hotControl == knobId)
{
angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center);
}
else if (Event.current.type == EventType.Repaint)
{
var notRotated = GUI.matrix;
var oldColor = GUI.color;
var highlighted = GUIUtility.hotControl == knobId ||
GUIUtility.hotControl == fieldId ||
GUIUtility.keyboardControl == fieldId;
GUIUtility.RotateAroundPivot(angle, knobRect.center);
GUI.color = KNOB_BG_COLOR;
GUI.DrawTexture(knobRect, KNOB_BG_TEXTURE, ScaleMode.ScaleToFit, true, 1);
GUI.color = highlighted ? KNOB_FG_COLOR_ACTIVE : KNOB_FG_COLOR;
if (procrastinationMode) GUI.color = Color.red;
GUI.DrawTexture(knobRect, KNOB_FG_TEXTURE, ScaleMode.ScaleToFit, true, 1);
if (!procrastinationMode)
GUI.matrix = notRotated;
GUI.color = oldColor;
}
if (angle != prevAngle) GUI.changed = true;
}
angle = DoFloatFieldInternal(
fieldRect,
labelRect,
fieldId,
angle
);
if (changeScope.changed) prop.floatValue = angle;
}
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 07c24ad14ec14d40ab304c80ba6af657
timeCreated: 1594636852

+ 16
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef View File

@ -0,0 +1,16 @@
{
"name": "LeTai.TrueShadow.Editor",
"references": [
"LeTai.TrueShadow"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

+ 7
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef.meta View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a3c0f23110aac1b4384b9377b63b6595
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 104
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs View File

@ -0,0 +1,104 @@
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public class MigrateToVV1Window : EditorWindow
{
private const string SHOW_ON_START_EDITOR_PREFS_KEY = "LeTai.TrueShadow.MigrateToVV1WindowShown";
[MenuItem("Tools/TrueShadow/Migrate To v1")]
public static MigrateToVV1Window ShowWindow()
{
var window = GetWindow<MigrateToVV1Window>(true, "True Shadow");
window.position = new Rect(600, 400, 600, 400);
return window;
}
[InitializeOnLoadMethod]
private static void InitializeOnLoadMethod()
{
RegisterWindowCheck();
}
private static void RegisterWindowCheck()
{
if (!EditorApplication.isPlayingOrWillChangePlaymode)
{
EditorApplication.update += CheckShowWindow;
}
}
private static void CheckShowWindow()
{
EditorApplication.update -= CheckShowWindow;
if (EditorPrefs.GetBool(SHOW_ON_START_EDITOR_PREFS_KEY, true))
{
ShowWindow();
}
}
void OnDestroy()
{
EditorPrefs.SetBool(SHOW_ON_START_EDITOR_PREFS_KEY, false);
}
bool haveBackup;
private void OnGUI()
{
GUILayout.Label("Migrate to v1", EditorStyles.largeLabel);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox(
"In v1, Blend Mode was changed to produce better looking shadows, as well as better compatibility with 3rd parties asset. As a side effect, most shadows should now use Color Bleed Mode: <Black>. This tool attempt to do this automatically.\n\n" +
"All True Shadows in currently loaded scenes will be migrated. You may want to load all scenes you want to fix before migrating. All True Shadows in prefabs will also be migrated.\n\n" +
"All True Shadows in prefabs will also be migrated.\n\n" +
"You may access this dialog later from the Tools menu.",
MessageType.Info
);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox(
"!!! MAKE SURE TO BACK UP YOUR PROJECT BEFORE USE !!!\n\n" +
"This tool will modify your project files. Please backup your project before use. If you are unsure how to do this, do NOT use this tool! Manually change any problematic shadows Color Bleed mode to Black instead!",
MessageType.Warning);
EditorGUILayout.Separator();
haveBackup = EditorGUILayout.ToggleLeft("I have backed up the project and can undo any changes done by the tool", haveBackup);
if (haveBackup)
{
if (GUILayout.Button("Migrate to v1"))
MigrateToV1();
}
}
public static void MigrateToV1()
{
var allPrefabs = AssetDatabase.FindAssets("t:Prefab");
foreach (var guid in allPrefabs)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var prefabRoot = PrefabUtility.LoadPrefabContents(path);
var changed = false;
foreach (var shadow in prefabRoot.GetComponentsInChildren<TrueShadow>())
{
shadow.ColorBleedMode = ColorBleedMode.Black;
changed = true;
}
if (changed)
PrefabUtility.SaveAsPrefabAsset(prefabRoot, path);
PrefabUtility.UnloadPrefabContents(prefabRoot);
}
var inScene = Resources.FindObjectsOfTypeAll<TrueShadow>()
.ToArray();
Undo.RecordObjects(inScene, "Migrate to 0.5");
foreach (var shadow in inScene)
{
shadow.ColorBleedMode = ColorBleedMode.Black;
}
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 126149305ac84024ac1d713f39caf754
timeCreated: 1611560835

+ 19
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs View File

@ -0,0 +1,19 @@
using UnityEditor;
namespace LeTai.TrueShadow.Editor
{
[InitializeOnLoad]
class PrefabEventHandler
{
static PrefabEventHandler()
{
PrefabUtility.prefabInstanceUpdated += go =>
{
var shadows = go.GetComponentsInChildren<TrueShadow>();
foreach (var shadow in shadows)
shadow.ApplySerializedData();
};
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9806fc5a3b18445e9766a68cf69b81c9
timeCreated: 1600845150

+ 62
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs View File

@ -0,0 +1,62 @@
using System;
using System.Linq;
using System.Reflection;
namespace LeTai.Asset.TrueShadow.Editor
{
public static class ScenceGizmoAutoDisable
{
static readonly string[] NO_GIZMOS_CLASSES = {
"TrueShadow"
};
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnScriptsReloaded()
{
var Annotation = Type.GetType("UnityEditor.Annotation, UnityEditor");
if (Annotation == null) return;
var ClassId = Annotation.GetField("classID");
var ScriptClass = Annotation.GetField("scriptClass");
var Flags = Annotation.GetField("flags");
var IconEnabled = Annotation.GetField("iconEnabled");
Type AnnotationUtility = Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
if (AnnotationUtility == null) return;
var GetAnnotations = AnnotationUtility.GetMethod("GetAnnotations",
BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static);
if (GetAnnotations == null) return;
var SetIconEnabled = AnnotationUtility.GetMethod("SetIconEnabled",
BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static);
if (SetIconEnabled == null) return;
Array annotations = (Array) GetAnnotations.Invoke(null, null);
foreach (var a in annotations)
{
int classId = (int) ClassId.GetValue(a);
string scriptClass = (string) ScriptClass.GetValue(a);
int flags = (int) Flags.GetValue(a);
int iconEnabled = (int) IconEnabled.GetValue(a);
// built in types
if (string.IsNullOrEmpty(scriptClass)) continue;
// load a json or text file with class names
const int HasIcon = 1;
bool hasIconFlag = (flags & HasIcon) == HasIcon;
if (hasIconFlag &&
iconEnabled != 0 &&
NO_GIZMOS_CLASSES.Contains(scriptClass))
{
SetIconEnabled.Invoke(null, new object[] {classId, scriptClass, 0});
}
}
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a1266d64cf1066b47b900e5115a5b75d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 87
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs View File

@ -0,0 +1,87 @@
using UnityEditor;
using UnityEngine;
using static UnityEditor.EditorGUI;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(SpreadSliderAttribute))]
public class SpreadSliderDrawer : PropertyDrawer
{
const float SLIDER_SPACING = 5;
const float MARKER_HEIGHT = 6;
const float MARKER_ALPHA = .75f;
const float MARKER_FILLET = 2;
static readonly Vector4 START_RADII = new Vector4(MARKER_FILLET, 0, 0, MARKER_FILLET);
static readonly Vector4 END_RADII = new Vector4(0, MARKER_FILLET, MARKER_FILLET, 0);
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
using (var propScope = new PropertyScope(position, label, property))
using (var changeScope = new ChangeCheckScope())
{
var controlPosition = PrefixLabel(position, propScope.content);
var floatFieldWidth = Mathf.Min(EditorGUIUtility.fieldWidth, controlPosition.width);
var sliderPosition = new Rect(controlPosition)
{width = controlPosition.width - floatFieldWidth - SLIDER_SPACING};
const float marker1 = .8f;
const float marker2 = .95f;
DrawMarkers(sliderPosition,
(marker1, new Color(1.00000f, 0.60392f, 0.01961f, MARKER_ALPHA)),
(marker2, new Color(1.00000f, 0.25490f, 0.20784f, MARKER_ALPHA)));
var newVal = Slider(controlPosition,
GUIContent.none,
property.floatValue,
0, 1);
if (!Event.current.control && !Event.current.alt)
{
var dist1 = (newVal - marker1) * sliderPosition.width;
var dist2 = (newVal - marker2) * sliderPosition.width;
if (0 < dist1 && dist1 < 4)
newVal = marker1;
if (0 < dist2 && dist2 < 4)
newVal = marker2;
}
if (changeScope.changed)
property.floatValue = newVal;
}
}
void DrawMarkers(Rect sliderPosition, params (float, Color)[] markers)
{
var hPad = GUI.skin.horizontalSliderThumb.fixedWidth / 2f;
var markerXStart = sliderPosition.x + hPad;
var markerXEnd = sliderPosition.width - hPad * 2;
var vPad = (sliderPosition.height - MARKER_HEIGHT) / 2f;
var markerYStart = sliderPosition.y + vPad;
var markerHeight = sliderPosition.height - vPad * 2;
for (var i = 0; i < markers.Length; i++)
{
var (offset, color) = markers[i];
var x = markerXStart + markerXEnd * offset;
var width = i < markers.Length - 1
? sliderPosition.width * (markers[i + 1].Item1 - offset) - 1
: sliderPosition.xMax - x;
var position = new Rect {
x = x,
y = markerYStart,
width = width,
height = markerHeight
};
var radii = i == 0 ? START_RADII : END_RADII;
GUI.DrawTexture(position,
Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, color,
Vector4.zero, radii);
}
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3292983b33504803ae542a485f446019
timeCreated: 1615190623

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1cd90590774134c4ea35245f256f89e9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png View File

Before After
Width: 32  |  Height: 32  |  Size: 459 B

+ 130
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png.meta View File

@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: b11fa2df94e30d244aadf3846cb15aeb
labels:
- TrueShadowEditorResources
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 1
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
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 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: Android
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: WebGL
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: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1.1 KiB

+ 130
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png.meta View File

@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 413bbe8f3993d194682180c4acfc0d1e
labels:
- TrueShadowEditorResources
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
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
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 16
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
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: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1.2 KiB

+ 130
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png.meta View File

@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 94d408ca95ce77245aa4866768b6b55c
labels:
- TrueShadowEditorResources
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
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
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 16
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
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: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png View File

Before After
Width: 32  |  Height: 32  |  Size: 724 B

+ 130
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png.meta View File

@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 8cad3feef3766b240a76d467e152152e
labels:
- TrueShadowEditorResources
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 1
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
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 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: Android
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: WebGL
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: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png View File

Before After
Width: 64  |  Height: 64  |  Size: 2.0 KiB

+ 128
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png.meta View File

@ -0,0 +1,128 @@
fileFormatVersion: 2
guid: 098c7906709c37c4bba842c34581765c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
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
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 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: Android
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: WebGL
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: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

+ 104
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs View File

@ -0,0 +1,104 @@
using UnityEditor;
using UnityEngine;
using static UnityEditor.EditorGUILayout;
namespace LeTai.TrueShadow.Editor
{
[CanEditMultipleObjects]
[CustomEditor(typeof(TrueShadow))]
public class TrueShadowEditor : UnityEditor.Editor
{
EditorProperty insetProp;
EditorProperty sizeProp;
EditorProperty spreadProp;
EditorProperty angleProp;
EditorProperty distanceProp;
EditorProperty colorProp;
EditorProperty blendModeProp;
EditorProperty multiplyCasterAlphaProp;
EditorProperty ignoreCasterColorProp;
EditorProperty colorBleedModeProp;
GUIContent procrastinateLabel;
static bool showExperimental;
static bool showAdvanced;
void OnEnable()
{
insetProp = new EditorProperty(serializedObject, nameof(TrueShadow.Inset));
sizeProp = new EditorProperty(serializedObject, nameof(TrueShadow.Size));
spreadProp = new EditorProperty(serializedObject, nameof(TrueShadow.Spread));
angleProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetAngle));
distanceProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetDistance));
colorProp = new EditorProperty(serializedObject, nameof(TrueShadow.Color));
blendModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.BlendMode));
multiplyCasterAlphaProp = new EditorProperty(serializedObject, nameof(TrueShadow.UseCasterAlpha));
ignoreCasterColorProp = new EditorProperty(serializedObject, nameof(TrueShadow.IgnoreCasterColor));
colorBleedModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.ColorBleedMode));
if (EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental)))
{
showExperimental = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental), false);
showAdvanced = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showAdvanced), false);
}
procrastinateLabel = new GUIContent("Procrastinate", "A bug that is too fun to fix");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
var ts = (TrueShadow) target;
insetProp.Draw();
sizeProp.Draw();
spreadProp.Draw();
angleProp.Draw();
distanceProp.Draw();
colorProp.Draw();
if (ts.UsingRendererMaterialProvider)
{
using(new EditorGUI.DisabledScope(true))
LabelField(blendModeProp.serializedProperty.displayName, "Custom Material");
}
else
{
blendModeProp.Draw();
}
using (var change = new EditorGUI.ChangeCheckScope())
{
showAdvanced = Foldout(showAdvanced, "Advanced Settings", true);
using (new EditorGUI.IndentLevelScope())
if (showAdvanced)
{
multiplyCasterAlphaProp.Draw();
ignoreCasterColorProp.Draw();
colorBleedModeProp.Draw();
if (KnobPropertyDrawer.procrastinationMode)
{
var rot = GUI.matrix;
GUI.matrix = Matrix4x4.identity;
KnobPropertyDrawer.procrastinationMode ^= Toggle("Be Productive", false);
GUI.matrix = rot;
}
else
{
KnobPropertyDrawer.procrastinationMode |= Toggle(procrastinateLabel, false);
}
}
if (change.changed)
{
EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showExperimental), showExperimental);
EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showAdvanced), showAdvanced);
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 120b61c7775149ed9de9c782978f6d61
timeCreated: 1592985822

+ 22
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs View File

@ -0,0 +1,22 @@
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public static class Utility
{
public static T FindAsset<T>(string assetName) where T : UnityEngine.Object
{
var guids = AssetDatabase.FindAssets("l:TrueShadowEditorResources " + assetName);
if (guids.Length == 0)
{
Debug.LogError($"Asset \"{assetName}\" not found. " +
$"Make sure it have the label \"TrueShadowEditorResources\"");
return null;
}
var path = AssetDatabase.GUIDToAssetPath(guids[0]);
return AssetDatabase.LoadAssetAtPath<T>(path);
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 09b72999f3c04f898c16bf60deb38c6e
timeCreated: 1602578784

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 20daae54a38548b488eb9c2aa1d39507
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 9
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs View File

@ -0,0 +1,9 @@
using UnityEngine;
namespace LeTai.Effects
{
public class BlurConfig : ScriptableObject
{
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1598e613c3d69154db682bbf3c234cb2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 15
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs View File

@ -0,0 +1,15 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace LeTai.Effects
{
public interface IBlurAlgorithm
{
void Configure(BlurConfig config);
void Blur(CommandBuffer cmd,
RenderTargetIdentifier src,
Rect srcCropRegion,
RenderTexture target);
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5bc98ab7243bbdc40a0c52f6d1ed58a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 104
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs View File

@ -0,0 +1,104 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace LeTai.Effects
{
public class ScalableBlur : IBlurAlgorithm
{
Material material;
ScalableBlurConfig config;
const int BLUR_PASS = 0;
const int CROP_BLUR_PASS = 1;
Material Material
{
get
{
if (material == null)
Material = new Material(Shader.Find("Hidden/EfficientBlur"));
return material;
}
set => material = value;
}
~ScalableBlur()
{
if (!material) return;
if (Application.isPlaying)
Object.Destroy(material);
else
Object.DestroyImmediate(material);
}
public void Configure(BlurConfig config)
{
this.config = (ScalableBlurConfig) config;
}
public void Blur(CommandBuffer cmd,
RenderTargetIdentifier src,
Rect srcCropRegion,
RenderTexture target)
{
float radius = config.Radius;
Material.SetFloat(ShaderProperties.blurRadius, radius);
Material.SetVector(ShaderProperties.blurTextureCropRegion, srcCropRegion.ToMinMaxVector());
int firstDownsampleFactor = config.Iteration > 0 ? 1 : 0;
int stepCount = Mathf.Max(config.Iteration * 2 - 1, 1);
int firstIRT = ShaderProperties.intermediateRT[0];
CreateTempRenderTextureFrom(cmd, firstIRT, target, firstDownsampleFactor);
// cmd.BlitFullscreenTriangle(src, firstIRT, Material, CROP_BLUR_PASS);
cmd.Blit(src, firstIRT, Material, CROP_BLUR_PASS);
for (var i = 1; i < stepCount; i++)
{
BlurAtDepth(cmd, i, target);
}
// cmd.BlitFullscreenTriangle(ShaderProperties.intermediateRT[stepCount - 1], target, Material, BLUR_PASS);
cmd.Blit(ShaderProperties.intermediateRT[stepCount - 1], target, Material, BLUR_PASS);
CleanupIntermediateRT(cmd, stepCount);
}
protected virtual void BlurAtDepth(CommandBuffer cmd, int depth, RenderTexture baseTexture)
{
int sizeLevel = Utility.SimplePingPong(depth, config.Iteration - 1) + 1;
sizeLevel = Mathf.Min(sizeLevel, config.MaxDepth);
CreateTempRenderTextureFrom(cmd, ShaderProperties.intermediateRT[depth], baseTexture, sizeLevel);
// cmd.BlitFullscreenTriangle(
cmd.Blit(
ShaderProperties.intermediateRT[depth - 1],
ShaderProperties.intermediateRT[depth],
Material,
0
);
}
static void CreateTempRenderTextureFrom(CommandBuffer cmd,
int nameId,
RenderTexture src,
int downsampleFactor)
{
int w = src.width >> downsampleFactor; //= width / 2^downsample
int h = src.height >> downsampleFactor;
cmd.GetTemporaryRT(nameId, w, h, 0, FilterMode.Bilinear, src.format);
}
static void CleanupIntermediateRT(CommandBuffer cmd, int amount)
{
for (var i = 0; i < amount; i++)
{
cmd.ReleaseTemporaryRT(ShaderProperties.intermediateRT[i]);
}
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d72465d1220a01e4abccda77619f6763
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 110
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs View File

@ -0,0 +1,110 @@
using UnityEngine;
using static UnityEngine.Mathf;
namespace LeTai.Effects
{
public class ScalableBlurConfig : BlurConfig
{
[SerializeField] float radius = 4;
[SerializeField] int iteration = 4;
[SerializeField] int maxDepth = 6;
[SerializeField] [Range(0, 256)] float strength;
/// <summary>
/// Distance between the base texel and the texel to be sampled.
/// </summary>
public float Radius
{
get { return radius; }
set { radius = Max(0, value); }
}
/// <summary>
/// Half the number of time to process the image. It is half because the real number of iteration must alway be even. Using half also make calculation simpler
/// </summary>
/// <value>
/// Must be non-negative
/// </value>
public int Iteration
{
get { return iteration; }
set { iteration = Max(0, value); }
}
/// <summary>
/// Clamp the minimum size of the intermediate texture. Reduce flickering and blur
/// </summary>
/// <value>
/// Must larger than 0
/// </value>
public int MaxDepth
{
get { return maxDepth; }
set { maxDepth = Max(1, value); }
}
/// <summary>
/// User friendly property to control the amount of blur
/// </summary>
///<value>
/// Must be non-negative
/// </value>
public float Strength
{
get { return strength = radius * (3 * (1 << iteration) - 2) / UNIT_VARIANCE; }
set
{
strength = Max(0, value);
SetAdvancedFieldFromSimple();
}
}
// With the "correct" unit variance, the edge of the shadow at higher stddev go below 8bit fixed point resolution
// We "wastes" processing power on these.
// TODO: optimize that:
// The maximum distance that will show up is:
// e^(-D^2 / 2R^2) < .5/256
// => D < 3*sqrt(2*log(2)) * R ~ 3.53223*R
// Can probably stop sooner than that
static readonly float UNIT_VARIANCE = 1f + Sqrt(2f) / 2f;
/// <summary>
/// Calculate size and iteration from strength
/// </summary>
protected virtual void SetAdvancedFieldFromSimple()
{
if (strength < 1e-2)
{
iteration = 0;
radius = 0;
return;
}
var variance = strength * UNIT_VARIANCE;
// Each level of the pyramid have double the effective radius of the last, so total effective radius would be:
// S = (2^0 + 2^1 +...+ 2^iteration +...+ 2^1 + 2^0) * R
// https://en.wikipedia.org/wiki/1_%2B_2_%2B_4_%2B_8_%2B_%E2%8B%AF
// S = (3 * 2^I - 2) * R
// so:
// I = log((s + 2r)/ (3r))/log(2)
// and:
// R = S / (3 * 2^I - 2)
//
// Experimental result show that best result are obtained with R <= 2^I - 1, so:
// I >= log(1/6 * (sqrt(12S + 1) + 5))/log(2)
//
// There still some artifact at the lower end, not sure how to handle that yet
// TODO: use a different algorithm for low Strength.
iteration = CeilToInt(Log(1 / 6f * (Sqrt(12 * variance + 1) + 5)) / Log(2));
radius = variance / (3 * (1 << iteration) - 2);
}
void OnValidate()
{
SetAdvancedFieldFromSimple();
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 506e4e7bc6f8ce24486de8c2732c0a1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 37
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs View File

@ -0,0 +1,37 @@
using UnityEngine;
namespace LeTai.Effects
{
public static class ShaderProperties
{
private static bool isInitialized;
public static int[] intermediateRT;
public static int blurRadius;
public static int blurTextureCropRegion;
public static void Init()
{
if (isInitialized)
return;
blurRadius = Shader.PropertyToID("_Radius");
blurTextureCropRegion = Shader.PropertyToID("_CropRegion");
isInitialized = true;
}
public static void Init(int stackDepth)
{
intermediateRT = new int[stackDepth * 2 - 1];
for (var i = 0; i < intermediateRT.Length; i++)
{
intermediateRT[i] = Shader.PropertyToID(string.Format("TI_intermediate_rt_{0}", i));
}
Init();
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ae61d4a8774bbb41acdf25cded306c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fa263cbfa5524d12a0df2e7befd04f50
timeCreated: 1593508707

+ 138
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs View File

@ -0,0 +1,138 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class AnimatedBiStateButton : MonoBehaviour,
IPointerDownHandler, IPointerUpHandler,
IPointerEnterHandler, IPointerExitHandler
{
public enum State
{
Up,
AnimateDown,
Down,
AnimateUp,
}
public float animationDuration = .1f;
public AnimationCurve animationCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
public bool useEnterExitEvents = true;
public event Action willPress;
public event Action willRelease;
protected State state = State.Up;
/// <summary>
/// 0 = fully up
/// 1 = fully down
/// </summary>
protected float pressAmount = 0;
protected bool IsAnimating => state == State.AnimateDown || state == State.AnimateUp;
void Update()
{
PollPointerUp();
DoAnimation();
}
void DoAnimation()
{
if (!IsAnimating) return;
if (state == State.AnimateDown)
{
pressAmount += Time.deltaTime / animationDuration;
}
else if (state == State.AnimateUp)
{
pressAmount -= Time.deltaTime / animationDuration;
}
pressAmount = Mathf.Clamp01(pressAmount);
var animationProgress = pressAmount;
if (state == State.AnimateUp) animationProgress = 1 - animationProgress;
animationProgress = animationCurve.Evaluate(animationProgress);
if (state == State.AnimateUp) animationProgress = 1 - animationProgress;
Animate(animationProgress);
if (state == State.AnimateDown && pressAmount == 1)
{
state = State.Down;
}
if (state == State.AnimateUp && pressAmount == 0)
{
state = State.Up;
}
}
protected void Press()
{
if (state != State.Down && state != State.AnimateDown)
{
OnWillPress();
state = State.AnimateDown;
}
}
protected void Release()
{
if (state != State.Up && state != State.AnimateUp)
{
OnWillRelease();
state = State.AnimateUp;
}
}
/// <summary>
/// Pointer Up event does not fire on an object if it was not the one receive the Pointer Down event.
/// </summary>
void PollPointerUp()
{
if (useEnterExitEvents
&& (state == State.Down || state == State.AnimateDown)
&& !Input.GetMouseButton(0))
{
Release();
}
}
/// <summary>
/// NOP if not overrided
/// </summary>
/// <param name="visualPressAmount"><see cref="pressAmount"/> conformed to <see cref="animationCurve"/></param>
protected virtual void Animate(float visualPressAmount) { }
public void OnPointerDown(PointerEventData eventData)
{
Press();
}
public void OnPointerUp(PointerEventData eventData)
{
Release();
}
public void OnPointerEnter(PointerEventData eventData)
{
if (useEnterExitEvents && Input.GetMouseButton(0)) Press();
}
public void OnPointerExit(PointerEventData eventData)
{
if (useEnterExitEvents) Release();
}
protected virtual void OnWillPress()
{
willPress?.Invoke();
}
protected virtual void OnWillRelease()
{
willRelease?.Invoke();
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d498001a5177468b90ceba93a17a5307
timeCreated: 1603966347

+ 69
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs View File

@ -0,0 +1,69 @@
using UnityEngine;
namespace LeTai.TrueShadow
{
[RequireComponent(typeof(TrueShadow))]
public class InsetOnPress : AnimatedBiStateButton
{
TrueShadow[] shadows;
float[] normalOpacity;
bool wasInset;
void OnEnable()
{
shadows = GetComponents<TrueShadow>();
normalOpacity = new float[shadows.Length];
}
protected override void Animate(float visualPressAmount)
{
void SetAllOpacity(float lerpProgress)
{
for (var i = 0; i < shadows.Length; i++)
{
var color = shadows[i].Color;
color.a = Mathf.Lerp(0, normalOpacity[i], lerpProgress);
shadows[i].Color = color;
}
}
bool shouldInset = visualPressAmount > .5f;
if (shouldInset != wasInset)
{
for (var i = 0; i < shadows.Length; i++)
{
shadows[i].Inset = shouldInset;
}
wasInset = shouldInset;
}
if (shouldInset)
{
SetAllOpacity(visualPressAmount * 2f - 1f);
}
else
{
SetAllOpacity(1 - visualPressAmount * 2f);
}
}
void MemorizeOpacity()
{
if (IsAnimating) return;
for (var i = 0; i < shadows.Length; i++)
{
normalOpacity[i] = shadows[i].Color.a;
}
}
protected override void OnWillPress()
{
wasInset = shadows[0].Inset;
MemorizeOpacity();
base.OnWillPress();
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dd53a06400e8496e82467031771bf46e
timeCreated: 1602747228

+ 242
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs View File

@ -0,0 +1,242 @@
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static UnityEngine.Mathf;
namespace LeTai.TrueShadow
{
[RequireComponent(typeof(TrueShadow))]
public class InteractiveShadow : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, ISelectHandler,
IDeselectHandler, IPointerDownHandler, IPointerUpHandler
{
public float smoothTime = .05f;
[Tooltip("Deselect on pointer up")]
public bool autoDeselect;
[Header("Size")]
public float selectedSize = 28;
public float hoverSize = 28;
public float clickedSize = 24;
[Header("Distance")]
public float selectedDistance = 12;
public float hoverDistance = 12;
public float clickedDistance = 8;
[Header("Color")]
public Color selectedColor = new Color(0, 0, 0, .25f);
public Color hoverColor = new Color(0, 0, 0, .20f);
public Color clickedColor = new Color(0, 0, 0, .25f);
float normalSize;
float normalDistance;
Color normalColor;
bool isSelected;
bool isHovered;
bool isClicked;
TrueShadow shadow;
Selectable selectable;
float targetSize;
float targetDistance;
Color targetColor;
static readonly Color FADED_COLOR = new Color(.5f, .5f, .5f, .5f);
#if UNITY_EDITOR
void Reset()
{
shadow = FindTrueShadow();
if (shadow)
{
normalSize = shadow.Size;
normalDistance = shadow.OffsetDistance;
normalColor = shadow.Color;
// Clicked UI remain selected, which is unwanted. Selected state is probably most useful on console
// and keyboard nav, the later is rather hard to detect
bool selectedIsNormal = Input.mousePresent || Input.touchSupported;
autoDeselect = selectedIsNormal;
hoverSize = Round(Min(normalSize * 1.75f, normalSize + 20f));
selectedSize = selectedIsNormal ? normalSize : hoverSize;
clickedSize = Round(Min(normalSize * 1.25f, normalSize + 15f));
hoverDistance = Round(Min(normalDistance * 1.5f, normalDistance + 20f));
selectedDistance = selectedIsNormal ? normalDistance : hoverDistance;
clickedDistance = Round(Min(normalDistance * 1.25f, normalDistance + 15f));
hoverColor = Color.Lerp(normalColor, FADED_COLOR, .15f);
selectedColor = selectedIsNormal ? normalColor : hoverColor;
clickedColor = Color.Lerp(normalColor, FADED_COLOR, .25f);
}
}
#endif
void OnEnable()
{
shadow = FindTrueShadow();
selectable = GetComponent<Selectable>();
targetSize = normalSize = shadow.Size;
targetDistance = normalDistance = shadow.OffsetDistance;
targetColor = normalColor = shadow.Color;
shadow.Size = targetSize = normalSize;
shadow.OffsetDistance = targetDistance = normalDistance;
}
TrueShadow FindTrueShadow()
{
var shadows = GetComponents<TrueShadow>();
if (shadows.Length == 0) return null;
var ishadows = GetComponents<InteractiveShadow>();
int index = 0;
for (; index < ishadows.Length; index++)
if (ishadows[index] == this)
break;
return shadows[index];
}
void OnStateChange()
{
if (isClicked)
{
targetSize = clickedSize;
targetDistance = clickedDistance;
targetColor = clickedColor;
}
else if (isSelected)
{
targetSize = selectedSize;
targetDistance = selectedDistance;
targetColor = selectedColor;
}
else if (isHovered)
{
targetSize = hoverSize;
targetDistance = hoverDistance;
targetColor = hoverColor;
}
else
{
targetSize = normalSize;
targetDistance = normalDistance;
targetColor = normalColor;
}
if (selectable && selectable.interactable && selectable.isActiveAndEnabled)
{
if (selectable.transition == Selectable.Transition.ColorTint)
{
StopAllCoroutines();
StartCoroutine(DirtyForSeconds(selectable.colors.fadeDuration));
}
}
}
IEnumerator DirtyForSeconds(float duration)
{
var start = Time.time;
while (start + duration >= Time.time)
{
shadow.SetTextureDirty();
yield return null;
}
}
#region AnimationState
float currentSizeVelocity;
float currentDistanceVelocity;
float currentColorRVelocity;
float currentColorGVelocity;
float currentColorBVelocity;
float currentColorAVelocity;
#endregion
void Update()
{
if (!Approximately(targetSize, shadow.Size))
{
shadow.Size = SmoothDamp(shadow.Size, targetSize,
ref currentSizeVelocity, smoothTime);
}
if (!Approximately(targetDistance, shadow.OffsetDistance))
{
shadow.OffsetDistance = SmoothDamp(shadow.OffsetDistance, targetDistance,
ref currentDistanceVelocity, smoothTime);
}
var shadowColor = shadow.Color;
if (!Approximately(targetColor.a, shadowColor.a))
{
var r = SmoothDamp(shadowColor.r, targetColor.r,
ref currentColorRVelocity, smoothTime);
var g = SmoothDamp(shadowColor.g, targetColor.g,
ref currentColorGVelocity, smoothTime);
var b = SmoothDamp(shadowColor.b, targetColor.b,
ref currentColorBVelocity, smoothTime);
var a = SmoothDamp(shadowColor.a, targetColor.a,
ref currentColorAVelocity, smoothTime);
shadow.Color = new Color(r, g, b, a);
}
}
public void OnPointerEnter(PointerEventData eventData)
{
isHovered = true;
OnStateChange();
}
public void OnPointerExit(PointerEventData eventData)
{
isHovered = false;
OnStateChange();
}
public void OnSelect(BaseEventData eventData)
{
isSelected = true;
OnStateChange();
}
public void OnDeselect(BaseEventData eventData)
{
isSelected = false;
OnStateChange();
}
public void OnPointerDown(PointerEventData eventData)
{
isClicked = true;
OnStateChange();
}
public void OnPointerUp(PointerEventData eventData)
{
if (autoDeselect && EventSystem.current.currentSelectedGameObject == gameObject)
EventSystem.current.SetSelectedGameObject(null);
isClicked = false;
OnStateChange();
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2b6bd66378f54ffc974312b194733dd9
timeCreated: 1593508708

+ 40
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs View File

@ -0,0 +1,40 @@
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow.PluginInterfaces
{
public interface ITrueShadowCasterMaterialProvider
{
Material GetTrueShadowCasterMaterial();
}
public interface ITrueShadowCasterMeshModifier
{
void ModifyTrueShadowCasterMesh(Mesh mesh);
}
public interface ITrueShadowCasterMaterialPropertiesModifier
{
void ModifyTrueShadowCasterMaterialProperties(MaterialPropertyBlock propertyBlock);
}
public interface ITrueShadowCasterClearColorProvider
{
Color GetTrueShadowCasterClearColor();
}
public interface ITrueShadowRendererMaterialProvider
{
Material GetTrueShadowRendererMaterial();
}
public interface ITrueShadowRendererMaterialModifier
{
void ModifyTrueShadowRendererMaterial(Material baseMaterial);
}
public interface ITrueShadowRendererMeshModifier
{
void ModifyTrueShadowRenderMesh(VertexHelper vertexHelper);
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81f076a2e89b8b34da77ca09f22cfe59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 312
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs View File

@ -0,0 +1,312 @@
using System.Collections.Generic;
using LeTai.Effects;
using UnityEngine;
using UnityEngine.Rendering;
namespace LeTai.TrueShadow
{
public class ShadowFactory
{
private static ShadowFactory instance;
public static ShadowFactory Instance => instance ?? (instance = new ShadowFactory());
readonly Dictionary<int, ShadowContainer> shadowCache =
new Dictionary<int, ShadowContainer>();
readonly CommandBuffer cmd;
readonly MaterialPropertyBlock materialProps;
readonly ScalableBlur blurProcessor;
readonly ScalableBlurConfig blurConfig;
Material cutoutMaterial;
Material imprintPostProcessMaterial;
Material shadowPostProcessMaterial;
Material CutoutMaterial =>
cutoutMaterial ? cutoutMaterial : cutoutMaterial = new Material(Shader.Find("Hidden/TrueShadow/Cutout"));
Material ImprintPostProcessMaterial =>
imprintPostProcessMaterial
? imprintPostProcessMaterial
: imprintPostProcessMaterial = new Material(Shader.Find("Hidden/TrueShadow/ImprintPostProcess"));
Material ShadowPostProcessMaterial =>
shadowPostProcessMaterial
? shadowPostProcessMaterial
: shadowPostProcessMaterial = new Material(Shader.Find("Hidden/TrueShadow/PostProcess"));
private ShadowFactory()
{
cmd = new CommandBuffer {name = "Shadow Commands"};
materialProps = new MaterialPropertyBlock();
materialProps.SetVector(ShaderId.CLIP_RECT,
new Vector4(float.NegativeInfinity, float.NegativeInfinity,
float.PositiveInfinity, float.PositiveInfinity));
materialProps.SetInt(ShaderId.COLOR_MASK, (int) ColorWriteMask.All); // Render shadow even if mask hide graphic
ShaderProperties.Init(8);
blurConfig = ScriptableObject.CreateInstance<ScalableBlurConfig>();
blurConfig.hideFlags = HideFlags.HideAndDontSave;
blurProcessor = new ScalableBlur();
blurProcessor.Configure(blurConfig);
}
~ShadowFactory()
{
cmd.Dispose();
Utility.SafeDestroy(blurConfig);
Utility.SafeDestroy(cutoutMaterial);
Utility.SafeDestroy(imprintPostProcessMaterial);
}
#if LETAI_TRUESHADOW_DEBUG
RenderTexture debugTexture;
#endif
// public int createdContainerCount;
// public int releasedContainerCount;
internal void Get(ShadowSettingSnapshot snapshot, ref ShadowContainer container)
{
if (float.IsNaN(snapshot.dimensions.x) || snapshot.dimensions.x < 1 ||
float.IsNaN(snapshot.dimensions.y) || snapshot.dimensions.y < 1)
{
ReleaseContainer(container);
return;
}
#if LETAI_TRUESHADOW_DEBUG
RenderTexture.ReleaseTemporary(debugTexture);
if (snapshot.shadow.alwaysRender)
debugTexture = GenerateShadow(snapshot).Texture;
#endif
// Each request need a coresponding shadow texture
// Texture may be shared by multiple elements
// Texture are released when no longer used by any element
// ShadowContainer keep track of texture and their usage
int requestHash = snapshot.GetHashCode();
// Case: requester can keep the same texture
if (container?.requestHash == requestHash)
return;
ReleaseContainer(container);
if (shadowCache.TryGetValue(requestHash, out var existingContainer))
{
// Case: requester got texture from someone else
existingContainer.RefCount++;
container = existingContainer;
}
else
{
// Case: requester got new unique texture
container = shadowCache[requestHash] = GenerateShadow(snapshot);
// Debug.Log($"Created new container for request\t{requestHash}\tTotal Created: {++createdContainerCount}\t Alive: {createdContainerCount - releasedContainerCount}");
}
}
internal void ReleaseContainer(ShadowContainer container)
{
if (container == null)
return;
if (--container.RefCount > 0)
return;
RenderTexture.ReleaseTemporary(container.Texture);
shadowCache.Remove(container.requestHash);
// Debug.Log($"Released container for request\t{container.requestHash}\tTotal Released: {++releasedContainerCount}\t Alive: {createdContainerCount - releasedContainerCount}");
}
static readonly Rect UNIT_RECT = new Rect(0, 0, 1, 1);
ShadowContainer GenerateShadow(ShadowSettingSnapshot snapshot)
{
// return GenColoredTexture(request.GetHashCode());
cmd.Clear();
cmd.BeginSample("TrueShadow:Capture");
var bounds = snapshot.shadow.SpriteMesh.bounds;
var misalignment = CalcMisalignment(snapshot.canvas, snapshot.canvasRt, snapshot.shadow.RectTransform, bounds);
var padding = Mathf.CeilToInt(snapshot.size);
var imprintViewW = Mathf.RoundToInt(snapshot.dimensions.x + misalignment.bothSS.x);
var imprintViewH = Mathf.RoundToInt(snapshot.dimensions.y + misalignment.bothSS.y);
var tw = imprintViewW + padding * 2;
var th = imprintViewH + padding * 2;
var shadowTex = RenderTexture.GetTemporary(tw, th, 0, RenderTextureFormat.ARGB32);
var imprintTexDesc = shadowTex.descriptor;
imprintTexDesc.msaaSamples = snapshot.shouldAntialiasImprint ? Mathf.Max(1, QualitySettings.antiAliasing) : 1;
var imprintTex = RenderTexture.GetTemporary(imprintTexDesc);
RenderTexture imprintTexProcessed = null;
bool needProcessImprint = snapshot.shadow.IgnoreCasterColor || snapshot.shadow.Inset;
if (needProcessImprint)
imprintTexProcessed = RenderTexture.GetTemporary(imprintTexDesc);
var texture = snapshot.shadow.Content;
if (texture)
materialProps.SetTexture(ShaderId.MAIN_TEX, texture);
else
materialProps.SetTexture(ShaderId.MAIN_TEX, Texture2D.whiteTexture);
cmd.SetRenderTarget(imprintTex);
cmd.ClearRenderTarget(true, true, snapshot.shadow.ClearColor);
cmd.SetViewport(new Rect(padding, padding, imprintViewW, imprintViewH));
var imprintBoundMin = (Vector2) bounds.min - misalignment.minLS;
var imprintBoundMax = (Vector2) bounds.max + misalignment.maxLS;
cmd.SetViewProjectionMatrices(
Matrix4x4.identity,
Matrix4x4.Ortho(imprintBoundMin.x, imprintBoundMax.x,
imprintBoundMin.y, imprintBoundMax.y,
-1, 1)
);
snapshot.shadow.ModifyShadowCastingMesh(snapshot.shadow.SpriteMesh);
snapshot.shadow.ModifyShadowCastingMaterialProperties(materialProps);
cmd.DrawMesh(snapshot.shadow.SpriteMesh,
Matrix4x4.identity,
snapshot.shadow.GetShadowCastingMaterial(),
0, 0,
materialProps);
if (needProcessImprint)
{
ImprintPostProcessMaterial.SetKeyword("BLEACH", snapshot.shadow.IgnoreCasterColor);
ImprintPostProcessMaterial.SetKeyword("INSET", snapshot.shadow.Inset);
cmd.Blit(imprintTex, imprintTexProcessed, ImprintPostProcessMaterial);
}
cmd.EndSample("TrueShadow:Capture");
var needPostProcess = snapshot.shadow.Spread > 1e-3;
cmd.BeginSample("TrueShadow:Cast");
RenderTexture blurSrc = needProcessImprint ? imprintTexProcessed : imprintTex;
RenderTexture blurDst;
if (needPostProcess)
blurDst = RenderTexture.GetTemporary(shadowTex.descriptor);
else
blurDst = shadowTex;
if (snapshot.size < 1e-2)
{
cmd.Blit(blurSrc, blurDst);
}
else
{
blurConfig.Strength = snapshot.size;
blurProcessor.Blur(cmd, blurSrc, UNIT_RECT, blurDst);
}
cmd.EndSample("TrueShadow:Cast");
var relativeOffset = new Vector2(snapshot.canvasRelativeOffset.x / tw,
snapshot.canvasRelativeOffset.y / th);
var overflowAlpha = snapshot.shadow.Inset ? 1 : 0;
if (needPostProcess)
{
cmd.BeginSample("TrueShadow:PostProcess");
ShadowPostProcessMaterial.SetTexture(ShaderId.SHADOW_TEX, blurDst);
ShadowPostProcessMaterial.SetVector(ShaderId.OFFSET, relativeOffset);
ShadowPostProcessMaterial.SetFloat(ShaderId.OVERFLOW_ALPHA, overflowAlpha);
ShadowPostProcessMaterial.SetFloat(ShaderId.ALPHA_MULTIPLIER,
1f / Mathf.Max(1e-6f, 1f - snapshot.shadow.Spread));
cmd.SetViewport(UNIT_RECT);
cmd.Blit(blurSrc, shadowTex, ShadowPostProcessMaterial);
cmd.EndSample("TrueShadow:PostProcess");
}
else if (snapshot.shadow.Cutout)
{
cmd.BeginSample("TrueShadow:Cutout");
CutoutMaterial.SetVector(ShaderId.OFFSET, relativeOffset);
CutoutMaterial.SetFloat(ShaderId.OVERFLOW_ALPHA, overflowAlpha);
cmd.SetViewport(UNIT_RECT);
cmd.Blit(blurSrc, shadowTex, CutoutMaterial);
cmd.EndSample("TrueShadow:Cutout");
}
Graphics.ExecuteCommandBuffer(cmd);
RenderTexture.ReleaseTemporary(imprintTex);
RenderTexture.ReleaseTemporary(blurSrc);
if (needPostProcess)
RenderTexture.ReleaseTemporary(blurDst);
return new ShadowContainer(shadowTex, snapshot, padding, misalignment.minLS);
}
readonly struct PixelMisalignment
{
public readonly Vector2 bothSS;
public readonly Vector2 minLS;
public readonly Vector2 maxLS;
public PixelMisalignment(Vector2 bothSS, Vector2 minLS, Vector2 maxLS)
{
this.bothSS = bothSS;
this.minLS = minLS;
this.maxLS = maxLS;
}
}
PixelMisalignment CalcMisalignment(Canvas canvas, RectTransform canvasRt, RectTransform casterRt, Bounds meshBound)
{
PixelMisalignment misalignment;
if (canvas.renderMode == RenderMode.WorldSpace)
{
misalignment = new PixelMisalignment();
}
else
{
var referenceCamera = canvas.renderMode == RenderMode.ScreenSpaceCamera ? canvas.worldCamera : null;
var pxMisalignmentAtMin = casterRt.LocalToScreenPoint(meshBound.min, referenceCamera).Frac();
var pxMisalignmentAtMax =
Vector2.one - casterRt.LocalToScreenPoint(meshBound.max, referenceCamera).Frac();
if (pxMisalignmentAtMax.x > 1 - 1e-5)
pxMisalignmentAtMax.x = 0;
if (pxMisalignmentAtMax.y > 1 - 1e-5)
pxMisalignmentAtMax.y = 0;
misalignment = new PixelMisalignment(
pxMisalignmentAtMin + pxMisalignmentAtMax,
canvasRt.ScreenToCanvasSize(pxMisalignmentAtMin, referenceCamera),
canvasRt.ScreenToCanvasSize(pxMisalignmentAtMax, referenceCamera)
);
}
return misalignment;
}
RenderTexture GenColoredTexture(int hash)
{
var tex = new Texture2D(1, 1);
tex.SetPixels32(new[] {new Color32((byte) (hash >> 8), (byte) (hash >> 16), (byte) (hash >> 24), 255)});
tex.Apply();
var rt = RenderTexture.GetTemporary(1, 1);
Graphics.Blit(tex, rt);
return rt;
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8d1278f371c48a784a5294591372531
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 76
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs View File

@ -0,0 +1,76 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
namespace LeTai.TrueShadow
{
public partial class ShadowRenderer
{
// TODO: cleanup unused mask materials
static readonly Dictionary<(bool, Material), Material> MASK_MATERIALS_CACHE =
new Dictionary<(bool, Material), Material>();
internal static void ClearMaskMaterialCache()
{
foreach (var keyValuePair in MASK_MATERIALS_CACHE)
{
if(Application.isPlaying)
Destroy(keyValuePair.Value);
else
DestroyImmediate(keyValuePair.Value);
}
MASK_MATERIALS_CACHE.Clear();
}
public Material GetModifiedMaterial(Material baseMaterial)
{
if (!shadow)
return baseMaterial;
shadow.ModifyShadowRendererMaterial(baseMaterial);
if (!baseMaterial.HasProperty(ShaderId.COLOR_MASK) ||
!baseMaterial.HasProperty(ShaderId.STENCIL_OP))
return baseMaterial;
bool casterIsMask = shadow.GetComponent<Mask>() != null;
MASK_MATERIALS_CACHE.TryGetValue((casterIsMask, baseMaterial), out var mat);
if (!mat)
{
mat = new Material(baseMaterial);
if (shadow.ShadowAsSibling)
{
// Prevent shadow from writing to stencil mask
mat.SetInt(ShaderId.COLOR_MASK, (int) ColorWriteMask.All);
mat.SetInt(ShaderId.STENCIL_OP, (int) StencilOp.Keep);
}
else if (casterIsMask)
{
// Escape mask if we have one
var baseStencilId = mat.GetInt(ShaderId.STENCIL_ID) + 1;
int stencilDepth = 0;
for (; stencilDepth < 8; stencilDepth++)
{
if (((baseStencilId >> stencilDepth) & 1) == 1)
break;
}
stencilDepth = Mathf.Max(0, stencilDepth - 1);
var stencilId = (1 << stencilDepth) - 1;
mat.SetInt(ShaderId.STENCIL_ID, stencilId);
mat.SetInt(ShaderId.STENCIL_READ_MASK, stencilId);
}
MASK_MATERIALS_CACHE[(casterIsMask, baseMaterial)] = mat;
}
return mat;
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b035d21af0d3447296a96ea4f27b5f53
timeCreated: 1600848777

+ 189
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs View File

@ -0,0 +1,189 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow
{
[AddComponentMenu("")]
[ExecuteAlways]
public partial class ShadowRenderer : MonoBehaviour, ILayoutIgnorer, IMaterialModifier, IMeshModifier
{
public bool ignoreLayout => true;
internal CanvasRenderer CanvasRenderer { get; private set; }
TrueShadow shadow;
RectTransform rt;
RawImage graphic;
Texture shadowTexture;
public static void Initialize(TrueShadow shadow, ref ShadowRenderer renderer)
{
if (renderer && renderer.shadow == shadow)
{
renderer.gameObject.SetActive(true);
return;
}
var obj = new GameObject($"{shadow.gameObject.name}'s Shadow") {
#if LETAI_TRUESHADOW_DEBUG
hideFlags = DebugSettings.Instance.showObjects
? HideFlags.DontSave
: HideFlags.HideAndDontSave
#else
hideFlags = HideFlags.HideAndDontSave
#endif
};
#if LETAI_TRUESHADOW_DEBUG && UNITY_EDITOR
UnityEditor.SceneVisibilityManager.instance.DisablePicking(obj, true);
#endif
shadow.SetHierachyDirty();
var rt = obj.AddComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.zero;
var graphic = obj.AddComponent<RawImage>();
graphic.raycastTarget = false;
graphic.color = shadow.Color;
renderer = obj.AddComponent<ShadowRenderer>();
renderer.shadow = shadow;
renderer.rt = rt;
renderer.graphic = graphic;
// renderer.RecreateGraphic(shadow.Baked ? GraphicType.Image : GraphicType.RawImage);
renderer.UpdateMaterial();
renderer.CanvasRenderer = obj.GetComponent<CanvasRenderer>();
renderer.CanvasRenderer.SetColor(shadow.IgnoreCasterColor ? Color.white : shadow.CanvasRenderer.GetColor());
renderer.CanvasRenderer.SetAlpha(shadow.CanvasRenderer.GetAlpha());
renderer.ReLayout();
}
public void UpdateMaterial()
{
var mat = shadow.BlendMode.GetMaterial();
graphic.material = mat ? mat : shadow.GetShadowRenderingNormalMaterial();
}
internal void ReLayout()
{
if (!isActiveAndEnabled)
return;
var casterRt = shadow.RectTransform;
if (!casterRt)
{
CanvasRenderer.SetAlpha(0);
return;
}
if (!shadowTexture)
{
CanvasRenderer.SetAlpha(0);
return;
}
var container = shadow.ShadowContainer;
var canvasScale = container?.Snapshot?.canvasScale ?? graphic.canvas.scaleFactor;
var shadowTexSize = new Vector2(shadowTexture.width, shadowTexture.height) / canvasScale;
rt.sizeDelta = shadowTexSize;
// pivot should be relative to the un-blurred part of the texture, not the whole mesh
var casterPivotLS = -(Vector2) shadow.SpriteMesh.bounds.min;
var padding = (container?.Padding ?? Mathf.CeilToInt(shadow.Size * canvasScale)) / canvasScale * Vector2.one;
var misalign = container?.PxMisalignmentAtMinLS ?? Vector2.zero;
rt.pivot = (casterPivotLS + padding + misalign) / shadowTexSize;
var canvasRelativeOffset = container?.Snapshot?.canvasRelativeOffset / canvasScale ?? shadow.Offset;
var offset = shadow.ShadowAsSibling
? shadow.Offset.WithZ(0)
: canvasRelativeOffset.WithZ(0);
rt.localPosition = shadow.ShadowAsSibling
? casterRt.localPosition + offset
: offset;
rt.localRotation = shadow.ShadowAsSibling ? casterRt.localRotation : Quaternion.identity;
rt.localScale = shadow.ShadowAsSibling ? casterRt.localScale : Vector3.one;
var color = shadow.Color;
if (shadow.UseCasterAlpha)
color.a *= shadow.Graphic.color.a;
graphic.color = color;
CanvasRenderer.SetColor(shadow.IgnoreCasterColor ? Color.white : shadow.CanvasRenderer.GetColor());
CanvasRenderer.SetAlpha(shadow.CanvasRenderer.GetAlpha());
graphic.Rebuild(CanvasUpdate.PreRender);
}
public void SetTexture(Texture texture)
{
shadowTexture = texture;
CanvasRenderer.SetTexture(texture);
graphic.texture = texture;
}
public void SetMaterialDirty()
{
graphic.SetMaterialDirty();
}
public void ModifyMesh(VertexHelper vertexHelper)
{
if (!shadow)
return;
shadow.ModifyShadowRendererMesh(vertexHelper);
}
public void ModifyMesh(Mesh mesh)
{
Debug.Assert(true, "This should only be called on old unsupported Unity version");
}
protected virtual void LateUpdate()
{
// Destroy events are not consistently called for some reason, have to poll
if (!shadow)
Dispose();
}
bool willBeDestroyed;
protected virtual void OnDestroy()
{
willBeDestroyed = true;
}
public void Dispose()
{
if (willBeDestroyed) return;
if (shadow && shadow.ShadowAsSibling)
{
// Destroy does not happen immediately. Want out of hierarchy.
gameObject.SetActive(false);
transform.SetParent(null);
}
#if UNITY_EDITOR
// This look redundant but is necessary!
if (!Application.isPlaying && !UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
DestroyImmediate(gameObject);
else if (Application.isPlaying)
Destroy(gameObject);
#else
Destroy(gameObject);
#endif
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8c213e24c3734f43b893d039b31ac5bc
timeCreated: 1592813121

+ 139
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs View File

@ -0,0 +1,139 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow
{
class ShadowSettingSnapshot
{
public readonly TrueShadow shadow;
public readonly Canvas canvas;
public readonly RectTransform canvasRt;
public readonly bool shouldAntialiasImprint;
public readonly float canvasScale;
public readonly float size;
public readonly Vector2 canvasRelativeOffset;
public readonly Vector2 dimensions;
internal ShadowSettingSnapshot(TrueShadow shadow)
{
this.shadow = shadow;
canvas = shadow.Graphic.canvas;
canvasRt = (RectTransform) canvas.transform;
var meshBound = shadow.SpriteMesh.bounds;
shouldAntialiasImprint = canvas.renderMode != RenderMode.ScreenSpaceOverlay;
canvasScale = canvas.scaleFactor;
var canvasRelativeRotation = Quaternion.Inverse(canvasRt.rotation) * shadow.RectTransform.rotation;
canvasRelativeOffset = shadow.Offset.Rotate(-canvasRelativeRotation.eulerAngles.z) * canvasScale;
dimensions = (Vector2) meshBound.size * canvasScale;
size = shadow.Size * canvasScale;
CalcHash();
}
const int DIMENSIONS_HASH_STEP = 1;
void CalcHash()
{
var graphic = shadow.Graphic;
int canvasScaleHash = (int) (canvasScale * 1e4);
int insetHash = shadow.Inset ? 1 : 0;
var clearColor = shadow.ClearColor;
var imageColor = graphic.color;
int colorHash = HashUtils.CombineHashCodes(
shadow.IgnoreCasterColor ? 1 : 0,
(int) shadow.ColorBleedMode,
(int) (imageColor.r * 255),
(int) (imageColor.g * 255),
(int) (imageColor.b * 255),
(int) (imageColor.a * 255),
(int) (clearColor.r * 255),
(int) (clearColor.g * 255),
(int) (clearColor.b * 255),
(int) (clearColor.a * 255)
);
// Hack until we have separated cutout cache, or proper sibling mode
int offsetHash = HashUtils.CombineHashCodes(
shadow.Cutout ? 1 : 0,
(int) (canvasRelativeOffset.x * 100),
(int) (canvasRelativeOffset.y * 100)
);
// Tiled type cannot be batched by similar size
int dimensionHash = graphic is Image im && im.type == Image.Type.Tiled
? dimensions.GetHashCode()
: HashUtils.CombineHashCodes(
Mathf.CeilToInt(dimensions.x / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP,
Mathf.CeilToInt(dimensions.y / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP
);
var sizeHash = Mathf.CeilToInt(size * 100);
var commonHash = HashUtils.CombineHashCodes(
shadow.TextureRevision,
canvasScaleHash,
insetHash,
colorHash,
offsetHash,
dimensionHash,
sizeHash
);
switch (graphic)
{
case Image image:
int spriteHash = 0;
if (image.sprite)
spriteHash = image.sprite.GetHashCode();
int imageHash = HashUtils.CombineHashCodes(
(int) image.type,
(int) (image.fillAmount * 360 * 20),
(int) image.fillMethod,
image.fillOrigin,
image.fillClockwise ? 1 : 0
);
hash = HashUtils.CombineHashCodes(
commonHash,
spriteHash,
imageHash
);
break;
case RawImage rawImage:
var textureHash = 0;
if (rawImage.texture)
textureHash = rawImage.texture.GetInstanceID();
hash = HashUtils.CombineHashCodes(
commonHash,
textureHash
);
break;
default:
hash = commonHash;
break;
}
}
int hash;
// ReSharper disable once NonReadonlyMemberInGetHashCode
public override int GetHashCode() => hash;
public override bool Equals(object obj)
{
if (obj == null) return false;
return GetHashCode() == obj.GetHashCode();
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 93693e4b8ffcbca48bc39fba2e37ffda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 193
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs View File

@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace LeTai.TrueShadow
{
[ExecuteAlways]
public class ShadowSorter : MonoBehaviour
{
#region SortDataContainer
readonly struct SortEntry : IComparable<SortEntry>
{
public readonly TrueShadow shadow;
public readonly Transform shadowTransform;
public readonly Transform rendererTransform;
public SortEntry(TrueShadow shadow)
{
this.shadow = shadow;
shadowTransform = shadow.transform;
rendererTransform = shadow.shadowRenderer.transform;
}
public int CompareTo(SortEntry other)
{
return other.shadowTransform.GetSiblingIndex().CompareTo(shadowTransform.GetSiblingIndex());
}
}
readonly struct SortGroup
{
public readonly Transform parentTransform;
public readonly List<SortEntry> sortEntries;
public SortGroup(SortEntry firstEntry)
{
sortEntries = new List<SortEntry> {firstEntry};
parentTransform = firstEntry.shadowTransform.parent;
}
public void Add(SortEntry pair)
{
if (pair.shadowTransform.parent != parentTransform)
return;
var index = sortEntries.BinarySearch(pair);
if (index < 0)
sortEntries.Insert(~index, pair);
}
public override int GetHashCode()
{
return parentTransform.GetHashCode();
}
public override bool Equals(object obj)
{
return obj is SortGroup other && other.parentTransform == parentTransform;
}
}
#endregion
private static ShadowSorter instance;
public static ShadowSorter Instance
{
get
{
if (!instance)
{
var existings = FindObjectsOfType<ShadowSorter>();
for (int i = existings.Length - 1; i > 0; i--)
{
Destroy(existings[i]);
}
#if UNITY_EDITOR
var hidden = GameObject.Find("/" + nameof(ShadowSorter));
while (hidden)
{
DestroyImmediate(hidden);
hidden = GameObject.Find("/" + nameof(ShadowSorter));
}
#endif
instance = existings.Length > 0 ? existings[0] : null;
if (!instance)
{
var obj = new GameObject(nameof(ShadowSorter)) {
#if LETAI_TRUESHADOW_DEBUG
hideFlags = DebugSettings.Instance.showObjects
? HideFlags.DontSave
: HideFlags.HideAndDontSave
#else
hideFlags = HideFlags.HideAndDontSave
#endif
};
instance = obj.AddComponent<ShadowSorter>();
}
}
return instance;
}
}
readonly IndexedSet<TrueShadow> shadows = new IndexedSet<TrueShadow>();
readonly IndexedSet<SortGroup> sortGroups = new IndexedSet<SortGroup>();
public void Register(TrueShadow shadow)
{
shadows.AddUnique(shadow);
}
public void UnRegister(TrueShadow shadow)
{
shadows.Remove(shadow);
}
void LateUpdate()
{
if (!this) return;
for (var i = 0; i < shadows.Count; i++)
{
var shadow = shadows[i];
if (!shadow || !shadow.isActiveAndEnabled)
continue;
shadow.CheckHierarchyDirtied();
if (shadow.hierachyDirty)
AddSortEntry(shadow);
}
Sort();
}
void AddSortEntry(TrueShadow shadow)
{
var entry = new SortEntry(shadow);
var group = new SortGroup(entry);
var oldIndex = sortGroups.IndexOf(group);
if (oldIndex > -1)
sortGroups[oldIndex].Add(entry);
else
sortGroups.Add(group);
}
public void Sort()
{
for (var i = 0; i < sortGroups.Count; i++)
{
var group = sortGroups[i];
if (!group.parentTransform)
continue;
foreach (var entry in group.sortEntries)
{
entry.rendererTransform.SetParent(group.parentTransform, false);
var rendererSid = entry.rendererTransform.GetSiblingIndex();
var shadowSid = entry.shadowTransform.GetSiblingIndex();
if (rendererSid > shadowSid)
{
entry.rendererTransform.SetSiblingIndex(shadowSid);
}
else
{
entry.rendererTransform.SetSiblingIndex(shadowSid - 1);
}
entry.shadow.UnSetHierachyDirty();
}
// This is a separated loop, as siblind index of an entry will be affected by the laters
foreach (var entry in group.sortEntries)
{
entry.shadow.ForgetSiblingIndexChanges();
}
}
sortGroups.Clear();
}
void OnApplicationQuit()
{
// make sure object are recreated when exit play mode. Otherwise it turn into some weird state. need more research
Destroy(gameObject);
}
}
}

+ 11
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs.meta View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cbf4f3c805fa455abb21fbb9ad6e54d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Structure.meta View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f395e653641dd7442bba503cb28b07a0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

+ 42
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs View File

@ -0,0 +1,42 @@
using System;
using UnityEngine;
namespace LeTai.TrueShadow
{
public enum BlendMode
{
Normal,
Additive,
Screen,
Multiply,
}
public static class BlendModeExtensions
{
static Material matNormal;
static Material materialAdditive;
static Material matScreen;
static Material matMultiply;
public static Material GetMaterial(this BlendMode blendMode)
{
switch (blendMode)
{
case BlendMode.Normal:
if (!matNormal) matNormal = new Material(Shader.Find("UI/TrueShadow-Normal"));
return matNormal;
case BlendMode.Additive:
if (!materialAdditive) materialAdditive = new Material(Shader.Find("UI/TrueShadow-Additive"));
return materialAdditive;
case BlendMode.Screen:
if (!matScreen) matScreen = new Material(Shader.Find("UI/TrueShadow-Screen"));
return matScreen;
case BlendMode.Multiply:
if (!matMultiply) matMultiply = new Material(Shader.Find("UI/TrueShadow-Multiply"));
return matMultiply;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}

+ 3
- 0
Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs.meta View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3379d45961064912b9e67abda88f84da
timeCreated: 1594095942

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save