com.mavrodiev.toolbox 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/Editor/Material-From-Texture-Maps/MaterialFromTextureMaps.cs +335 -0
  3. package/Editor/Material-From-Texture-Maps/MaterialFromTextureMaps.cs.meta +2 -0
  4. package/Editor/Material-From-Texture-Maps.meta +8 -0
  5. package/Editor/Mavrodiev.Toolbox.Editor.asmdef +10 -2
  6. package/Editor/MeshHealthWindow.cs +154 -0
  7. package/Editor/MeshHealthWindow.cs.meta +2 -0
  8. package/Editor/Texel-Density/TexelDensityView.cs +154 -0
  9. package/Editor/Texel-Density/TexelDensityView.cs.meta +2 -0
  10. package/Editor/Texel-Density.meta +8 -0
  11. package/Materials/M_Decal_Rain-Ripples.mat +77 -0
  12. package/Materials/M_Decal_Rain-Ripples.mat.meta +8 -0
  13. package/Materials/M_Dust-Back-Scatter.mat +40 -0
  14. package/Materials/M_Dust-Back-Scatter.mat.meta +8 -0
  15. package/Materials/M_Fake-Beam.mat +74 -0
  16. package/Materials/M_Fake-Beam.mat.meta +8 -0
  17. package/Materials/M_Flat.mat +155 -0
  18. package/Materials/M_Flat.mat.meta +8 -0
  19. package/Materials/M_Ghost.mat +35 -0
  20. package/Materials/M_Ghost.mat.meta +8 -0
  21. package/Materials/M_Glass-Clear.mat +39 -0
  22. package/Materials/M_Glass-Clear.mat.meta +8 -0
  23. package/Materials/M_Glass-Frosted.mat +39 -0
  24. package/Materials/M_Glass-Frosted.mat.meta +8 -0
  25. package/Materials/M_Glass-Reeded.mat +39 -0
  26. package/Materials/M_Glass-Reeded.mat.meta +8 -0
  27. package/Materials/M_Glow_Sodium.mat +33 -0
  28. package/Materials/M_Glow_Sodium.mat.meta +8 -0
  29. package/Materials/M_Glow_White.mat +33 -0
  30. package/Materials/M_Glow_White.mat.meta +8 -0
  31. package/Materials/M_Interior-Rooms-Shop.mat +41 -0
  32. package/Materials/M_Interior-Rooms-Shop.mat.meta +8 -0
  33. package/Materials/M_Interior-Rooms.mat +41 -0
  34. package/Materials/M_Interior-Rooms.mat.meta +8 -0
  35. package/Materials/M_Planar-Floor.mat +45 -0
  36. package/Materials/M_Planar-Floor.mat.meta +8 -0
  37. package/Materials/M_Reference-Overlay.mat +74 -0
  38. package/Materials/M_Reference-Overlay.mat.meta +8 -0
  39. package/Materials/M_Toon.mat +155 -0
  40. package/Materials/M_Toon.mat.meta +8 -0
  41. package/Materials/M_Tube-Dying.mat +35 -0
  42. package/Materials/M_Tube-Dying.mat.meta +8 -0
  43. package/Materials/M_Tube-Steady.mat +35 -0
  44. package/Materials/M_Tube-Steady.mat.meta +8 -0
  45. package/Materials/M_Water-Flood.mat +42 -0
  46. package/Materials/M_Water-Flood.mat.meta +8 -0
  47. package/Materials/M_Water.mat +42 -0
  48. package/Materials/M_Water.mat.meta +8 -0
  49. package/Materials/STOutline.mat +155 -0
  50. package/Materials/STOutline.mat.meta +8 -0
  51. package/Materials.meta +8 -0
  52. package/Runtime/CameraBreathing.cs +102 -0
  53. package/Runtime/CameraBreathing.cs.meta +2 -0
  54. package/Runtime/Mavrodiev.Toolbox.asmdef +4 -1
  55. package/Runtime/PlanarReflection.cs +165 -0
  56. package/Runtime/PlanarReflection.cs.meta +2 -0
  57. package/Runtime/Reference-Overlay.prefab +109 -0
  58. package/Runtime/Reference-Overlay.prefab.meta +7 -0
  59. package/Runtime/ReferenceOverlay.cs +175 -0
  60. package/Runtime/ReferenceOverlay.cs.meta +2 -0
  61. package/Runtime/RippleFlipbook.cs +116 -0
  62. package/Runtime/RippleFlipbook.cs.meta +2 -0
  63. package/Runtime/Terrain/HillTerrainGenerator.cs +143 -0
  64. package/Runtime/Terrain/HillTerrainGenerator.cs.meta +2 -0
  65. package/Runtime/Terrain/HillTerrainProfile.cs +64 -0
  66. package/Runtime/Terrain/HillTerrainProfile.cs.meta +2 -0
  67. package/Runtime/Terrain/TerrainSandbox.cs +83 -0
  68. package/Runtime/Terrain/TerrainSandbox.cs.meta +2 -0
  69. package/Runtime/Terrain.meta +8 -0
  70. package/Samples~/Camera-Showcase/Camera-Showcase.unity +2990 -0
  71. package/Samples~/Camera-Showcase/Camera-Showcase.unity.meta +7 -0
  72. package/Samples~/Camera-Showcase/M_Showcase_Grey.mat +139 -0
  73. package/Samples~/Camera-Showcase/M_Showcase_Grey.mat.meta +8 -0
  74. package/Samples~/Camera-Showcase/M_Showcase_Post.mat +139 -0
  75. package/Samples~/Camera-Showcase/M_Showcase_Post.mat.meta +8 -0
  76. package/Samples~/Camera-Showcase/Showcase-Portrait-Grid.png +0 -0
  77. package/Samples~/Camera-Showcase/Showcase-Portrait-Grid.png.meta +119 -0
  78. package/Samples~/Light-And-Space-Showcase/Light-And-Space-Showcase.unity +10616 -0
  79. package/Samples~/Light-And-Space-Showcase/Light-And-Space-Showcase.unity.meta +7 -0
  80. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-1.mat +74 -0
  81. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-1.mat.meta +8 -0
  82. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-2.mat +74 -0
  83. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-2.mat.meta +8 -0
  84. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-6.mat +74 -0
  85. package/Samples~/Light-And-Space-Showcase/M_Showcase_Beam-Edge-6.mat.meta +8 -0
  86. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-0.3.mat +55 -0
  87. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-0.3.mat.meta +8 -0
  88. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-0.6.mat +55 -0
  89. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-0.6.mat.meta +8 -0
  90. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-1.2.mat +55 -0
  91. package/Samples~/Light-And-Space-Showcase/M_Showcase_Caustics-1.2.mat.meta +8 -0
  92. package/Samples~/Light-And-Space-Showcase/M_Showcase_Dark.mat +139 -0
  93. package/Samples~/Light-And-Space-Showcase/M_Showcase_Dark.mat.meta +8 -0
  94. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ghost-Fade-10.mat +35 -0
  95. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ghost-Fade-10.mat.meta +8 -0
  96. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ghost-Fade-5.mat +35 -0
  97. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ghost-Fade-5.mat.meta +8 -0
  98. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ground.mat +139 -0
  99. package/Samples~/Light-And-Space-Showcase/M_Showcase_Ground.mat.meta +8 -0
  100. package/Samples~/Light-And-Space-Showcase/M_Showcase_Rooms-1x1-Depth-2.mat +41 -0
  101. package/Samples~/Light-And-Space-Showcase/M_Showcase_Rooms-1x1-Depth-2.mat.meta +8 -0
  102. package/Samples~/Light-And-Space-Showcase/M_Showcase_Rooms-3x1-Depth-5.mat +41 -0
  103. package/Samples~/Light-And-Space-Showcase/M_Showcase_Rooms-3x1-Depth-5.mat.meta +8 -0
  104. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-0.5.mat +35 -0
  105. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-0.5.mat.meta +8 -0
  106. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-0.mat +35 -0
  107. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-0.mat.meta +8 -0
  108. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-1.mat +35 -0
  109. package/Samples~/Light-And-Space-Showcase/M_Showcase_Tube-Broken-1.mat.meta +8 -0
  110. package/Samples~/Mesh-Tools-Showcase/Mesh-Health-Showcase.unity +1097 -0
  111. package/Samples~/Mesh-Tools-Showcase/Mesh-Health-Showcase.unity.meta +7 -0
  112. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Centimetres.asset +181 -0
  113. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Centimetres.asset.meta +8 -0
  114. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Flipped.asset +181 -0
  115. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Flipped.asset.meta +8 -0
  116. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Good.asset +181 -0
  117. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Good.asset.meta +8 -0
  118. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Hole.asset +181 -0
  119. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Hole.asset.meta +8 -0
  120. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Off-Grid.asset +181 -0
  121. package/Samples~/Mesh-Tools-Showcase/Meshes/Box-Off-Grid.asset.meta +8 -0
  122. package/Samples~/Mesh-Tools-Showcase/Meshes.meta +8 -0
  123. package/Samples~/Reflections-Showcase/M_Showcase_Blue.mat +139 -0
  124. package/Samples~/Reflections-Showcase/M_Showcase_Blue.mat.meta +8 -0
  125. package/Samples~/Reflections-Showcase/M_Showcase_Red.mat +139 -0
  126. package/Samples~/Reflections-Showcase/M_Showcase_Red.mat.meta +8 -0
  127. package/Samples~/Reflections-Showcase/M_Showcase_Yellow.mat +139 -0
  128. package/Samples~/Reflections-Showcase/M_Showcase_Yellow.mat.meta +8 -0
  129. package/Samples~/Reflections-Showcase/Reflections-Showcase.unity +1136 -0
  130. package/Samples~/Reflections-Showcase/Reflections-Showcase.unity.meta +7 -0
  131. package/Samples~/Skies-Showcase/M_Showcase_Grey.mat +139 -0
  132. package/Samples~/Skies-Showcase/M_Showcase_Grey.mat.meta +8 -0
  133. package/Samples~/Skies-Showcase/M_Showcase_Sky-Gradient.mat +39 -0
  134. package/Samples~/Skies-Showcase/M_Showcase_Sky-Gradient.mat.meta +8 -0
  135. package/Samples~/Skies-Showcase/M_Showcase_Sky-Procedural.mat +38 -0
  136. package/Samples~/Skies-Showcase/M_Showcase_Sky-Procedural.mat.meta +8 -0
  137. package/Samples~/Skies-Showcase/Skies-Gradient.unity +1060 -0
  138. package/Samples~/Skies-Showcase/Skies-Gradient.unity.meta +7 -0
  139. package/Samples~/Skies-Showcase/Skies-Procedural.unity +1060 -0
  140. package/Samples~/Skies-Showcase/Skies-Procedural.unity.meta +7 -0
  141. package/Samples~/Surfaces-Showcase/M_Showcase_Curtain-0.mat +40 -0
  142. package/Samples~/Surfaces-Showcase/M_Showcase_Curtain-0.mat.meta +8 -0
  143. package/Samples~/Surfaces-Showcase/M_Showcase_Curtain-1.5.mat +40 -0
  144. package/Samples~/Surfaces-Showcase/M_Showcase_Curtain-1.5.mat.meta +8 -0
  145. package/Samples~/Surfaces-Showcase/M_Showcase_Emissive-Bar.mat +139 -0
  146. package/Samples~/Surfaces-Showcase/M_Showcase_Emissive-Bar.mat.meta +8 -0
  147. package/Samples~/Surfaces-Showcase/M_Showcase_Ground.mat +139 -0
  148. package/Samples~/Surfaces-Showcase/M_Showcase_Ground.mat.meta +8 -0
  149. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-CRT.mat +46 -0
  150. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-CRT.mat.meta +8 -0
  151. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-LED.mat +46 -0
  152. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-LED.mat.meta +8 -0
  153. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-Plain.mat +46 -0
  154. package/Samples~/Surfaces-Showcase/M_Showcase_Screen-Plain.mat.meta +8 -0
  155. package/Samples~/Surfaces-Showcase/M_Showcase_Stripe-Dark.mat +139 -0
  156. package/Samples~/Surfaces-Showcase/M_Showcase_Stripe-Dark.mat.meta +8 -0
  157. package/Samples~/Surfaces-Showcase/M_Showcase_Stripe-Light.mat +139 -0
  158. package/Samples~/Surfaces-Showcase/M_Showcase_Stripe-Light.mat.meta +8 -0
  159. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-1.mat +155 -0
  160. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-1.mat.meta +8 -0
  161. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-3.mat +155 -0
  162. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-3.mat.meta +8 -0
  163. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-5.mat +155 -0
  164. package/Samples~/Surfaces-Showcase/M_Showcase_Toon-Steps-5.mat.meta +8 -0
  165. package/Samples~/Surfaces-Showcase/M_Showcase_Triplanar-Object.mat +50 -0
  166. package/Samples~/Surfaces-Showcase/M_Showcase_Triplanar-Object.mat.meta +8 -0
  167. package/Samples~/Surfaces-Showcase/M_Showcase_Triplanar-World.mat +50 -0
  168. package/Samples~/Surfaces-Showcase/M_Showcase_Triplanar-World.mat.meta +8 -0
  169. package/Samples~/Surfaces-Showcase/Surfaces-Showcase.unity +10448 -0
  170. package/Samples~/Surfaces-Showcase/Surfaces-Showcase.unity.meta +7 -0
  171. package/Samples~/Surfaces-Showcase/T_Showcase_Checker.png +0 -0
  172. package/Samples~/Surfaces-Showcase/T_Showcase_Checker.png.meta +119 -0
  173. package/Samples~/Surfaces-Showcase/T_Showcase_Screen-Content.png +0 -0
  174. package/Samples~/Surfaces-Showcase/T_Showcase_Screen-Content.png.meta +119 -0
  175. package/Samples~/Texture-Tools-Showcase/Example-Output/M_Stone-Paving.mat +142 -0
  176. package/Samples~/Texture-Tools-Showcase/Example-Output/M_Stone-Paving.mat.meta +8 -0
  177. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_AmbientOcclusion.jpg +0 -0
  178. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_AmbientOcclusion.jpg.meta +119 -0
  179. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_Color.jpg +0 -0
  180. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_Color.jpg.meta +119 -0
  181. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_MetallicSmoothness.png +0 -0
  182. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_MetallicSmoothness.png.meta +119 -0
  183. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_NormalGL.jpg +0 -0
  184. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_NormalGL.jpg.meta +119 -0
  185. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_Roughness.jpg +0 -0
  186. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving/Stone-Paving_Roughness.jpg.meta +119 -0
  187. package/Samples~/Texture-Tools-Showcase/Example-Output/Stone-Paving.meta +8 -0
  188. package/Samples~/Texture-Tools-Showcase/Example-Output.meta +8 -0
  189. package/Samples~/Texture-Tools-Showcase/M_Ground.mat +139 -0
  190. package/Samples~/Texture-Tools-Showcase/M_Ground.mat.meta +8 -0
  191. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_AmbientOcclusion.jpg +0 -0
  192. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_AmbientOcclusion.jpg.meta +119 -0
  193. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_Color.jpg +0 -0
  194. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_Color.jpg.meta +119 -0
  195. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_NormalGL.jpg +0 -0
  196. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_NormalGL.jpg.meta +119 -0
  197. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_Roughness.jpg +0 -0
  198. package/Samples~/Texture-Tools-Showcase/Raw-Set/Stone-Paving_Roughness.jpg.meta +119 -0
  199. package/Samples~/Texture-Tools-Showcase/Raw-Set.meta +8 -0
  200. package/Samples~/Texture-Tools-Showcase/Texture-Tools-Showcase.unity +1603 -0
  201. package/Samples~/Texture-Tools-Showcase/Texture-Tools-Showcase.unity.meta +7 -0
  202. package/Samples~/Weathering-Showcase/M_Showcase_Damp-0.3.mat +63 -0
  203. package/Samples~/Weathering-Showcase/M_Showcase_Damp-0.3.mat.meta +8 -0
  204. package/Samples~/Weathering-Showcase/M_Showcase_Damp-0.8.mat +63 -0
  205. package/Samples~/Weathering-Showcase/M_Showcase_Damp-0.8.mat.meta +8 -0
  206. package/Samples~/Weathering-Showcase/M_Showcase_Damp-1.5.mat +63 -0
  207. package/Samples~/Weathering-Showcase/M_Showcase_Damp-1.5.mat.meta +8 -0
  208. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Colour.mat +77 -0
  209. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Colour.mat.meta +8 -0
  210. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Normal.mat +77 -0
  211. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Normal.mat.meta +8 -0
  212. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Ripples.mat +77 -0
  213. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Ripples.mat.meta +8 -0
  214. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Smoothness.mat +77 -0
  215. package/Samples~/Weathering-Showcase/M_Showcase_Decal-Smoothness.mat.meta +8 -0
  216. package/Samples~/Weathering-Showcase/M_Showcase_Ground-Smooth.mat +139 -0
  217. package/Samples~/Weathering-Showcase/M_Showcase_Ground-Smooth.mat.meta +8 -0
  218. package/Samples~/Weathering-Showcase/M_Showcase_Ground.mat +139 -0
  219. package/Samples~/Weathering-Showcase/M_Showcase_Ground.mat.meta +8 -0
  220. package/Samples~/Weathering-Showcase/M_Showcase_Light-Box.mat +141 -0
  221. package/Samples~/Weathering-Showcase/M_Showcase_Light-Box.mat.meta +8 -0
  222. package/Samples~/Weathering-Showcase/M_Showcase_Puddles.mat +66 -0
  223. package/Samples~/Weathering-Showcase/M_Showcase_Puddles.mat.meta +8 -0
  224. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.3.mat +62 -0
  225. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.3.mat.meta +8 -0
  226. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.6.mat +62 -0
  227. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.6.mat.meta +8 -0
  228. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.9.mat +62 -0
  229. package/Samples~/Weathering-Showcase/M_Showcase_Snow-0.9.mat.meta +8 -0
  230. package/Samples~/Weathering-Showcase/M_Showcase_Wet-0.0.mat +66 -0
  231. package/Samples~/Weathering-Showcase/M_Showcase_Wet-0.0.mat.meta +8 -0
  232. package/Samples~/Weathering-Showcase/M_Showcase_Wet-0.5.mat +66 -0
  233. package/Samples~/Weathering-Showcase/M_Showcase_Wet-0.5.mat.meta +8 -0
  234. package/Samples~/Weathering-Showcase/M_Showcase_Wet-1.0.mat +66 -0
  235. package/Samples~/Weathering-Showcase/M_Showcase_Wet-1.0.mat.meta +8 -0
  236. package/Samples~/Weathering-Showcase/T_Showcase_Noise.png +0 -0
  237. package/Samples~/Weathering-Showcase/T_Showcase_Noise.png.meta +119 -0
  238. package/Samples~/Weathering-Showcase/Weathering-Showcase.unity +5533 -0
  239. package/Samples~/Weathering-Showcase/Weathering-Showcase.unity.meta +7 -0
  240. package/Shaders/Common/Library-Lighting.hlsl +51 -0
  241. package/Shaders/Common/Library-Lighting.hlsl.meta +7 -0
  242. package/Shaders/Common/Library-Passes.hlsl +130 -0
  243. package/Shaders/Common/Library-Passes.hlsl.meta +7 -0
  244. package/Shaders/Common/Planar-Reflection.hlsl +42 -0
  245. package/Shaders/Common/Planar-Reflection.hlsl.meta +7 -0
  246. package/Shaders/Common.meta +8 -0
  247. package/Shaders/Debug/Texel-Density.shader +172 -0
  248. package/Shaders/Debug/Texel-Density.shader.meta +9 -0
  249. package/Shaders/Debug.meta +8 -0
  250. package/Shaders/Light-And-Space/Caustics.shader +281 -0
  251. package/Shaders/Light-And-Space/Caustics.shader.meta +9 -0
  252. package/Shaders/Light-And-Space/Dust-Back-Scatter.shader +158 -0
  253. package/Shaders/Light-And-Space/Dust-Back-Scatter.shader.meta +9 -0
  254. package/Shaders/Light-And-Space/Dying-Tube.shader +188 -0
  255. package/Shaders/Light-And-Space/Dying-Tube.shader.meta +9 -0
  256. package/Shaders/Light-And-Space/Fake-Beam.shader +73 -0
  257. package/Shaders/Light-And-Space/Fake-Beam.shader.meta +9 -0
  258. package/Shaders/Light-And-Space/Ghost.shader +137 -0
  259. package/Shaders/Light-And-Space/Ghost.shader.meta +9 -0
  260. package/Shaders/Light-And-Space/Glow-Volume.shader +136 -0
  261. package/Shaders/Light-And-Space/Glow-Volume.shader.meta +9 -0
  262. package/Shaders/Light-And-Space/Interior-Rooms.shader +247 -0
  263. package/Shaders/Light-And-Space/Interior-Rooms.shader.meta +9 -0
  264. package/Shaders/Light-And-Space/Meshes/Beam-Cone.asset +181 -0
  265. package/Shaders/Light-And-Space/Meshes/Beam-Cone.asset.meta +8 -0
  266. package/Shaders/Light-And-Space/Meshes/Human-Silhouette-1.8m-Merged.asset +181 -0
  267. package/Shaders/Light-And-Space/Meshes/Human-Silhouette-1.8m-Merged.asset.meta +8 -0
  268. package/Shaders/Light-And-Space/Meshes.meta +8 -0
  269. package/Shaders/Light-And-Space/Textures/T_Beam-Gradient.png +0 -0
  270. package/Shaders/Light-And-Space/Textures/T_Beam-Gradient.png.meta +119 -0
  271. package/Shaders/Light-And-Space/Textures.meta +8 -0
  272. package/Shaders/Light-And-Space.meta +8 -0
  273. package/Shaders/Skies/TriColorSkyboxGradient.shader +99 -0
  274. package/Shaders/Skies/TriColorSkyboxGradient.shader.meta +9 -0
  275. package/Shaders/Skies.meta +8 -0
  276. package/Shaders/Surfaces/Curtain.shader +231 -0
  277. package/Shaders/Surfaces/Curtain.shader.meta +9 -0
  278. package/Shaders/Surfaces/Glass.shader +210 -0
  279. package/Shaders/Surfaces/Glass.shader.meta +9 -0
  280. package/Shaders/Surfaces/Meshes/Curtain-Plane-1.6x2.6m.asset +181 -0
  281. package/Shaders/Surfaces/Meshes/Curtain-Plane-1.6x2.6m.asset.meta +8 -0
  282. package/Shaders/Surfaces/Meshes.meta +8 -0
  283. package/Shaders/Surfaces/Planar-Floor.shader +205 -0
  284. package/Shaders/Surfaces/Planar-Floor.shader.meta +9 -0
  285. package/Shaders/Surfaces/Screen.shader +239 -0
  286. package/Shaders/Surfaces/Screen.shader.meta +9 -0
  287. package/Shaders/Surfaces/Simple-Toon/Shaders/STCore.hlsl +115 -0
  288. package/Shaders/Surfaces/Simple-Toon/Shaders/STCore.hlsl.meta +7 -0
  289. package/Shaders/Surfaces/Simple-Toon/Shaders/STFunctions.hlsl +115 -0
  290. package/Shaders/Surfaces/Simple-Toon/Shaders/STFunctions.hlsl.meta +7 -0
  291. package/Shaders/Surfaces/Simple-Toon/Shaders/STOutline.shader +299 -0
  292. package/Shaders/Surfaces/Simple-Toon/Shaders/STOutline.shader.meta +16 -0
  293. package/Shaders/Surfaces/Simple-Toon/Shaders.meta +8 -0
  294. package/Shaders/Surfaces/Simple-Toon.meta +8 -0
  295. package/Shaders/Surfaces/Textures/Glass-Frosted_Normal.png +0 -0
  296. package/Shaders/Surfaces/Textures/Glass-Frosted_Normal.png.meta +119 -0
  297. package/Shaders/Surfaces/Textures/Glass-Reeded_Normal.png +0 -0
  298. package/Shaders/Surfaces/Textures/Glass-Reeded_Normal.png.meta +119 -0
  299. package/Shaders/Surfaces/Textures/Water-Ripples_Normal.png +0 -0
  300. package/Shaders/Surfaces/Textures/Water-Ripples_Normal.png.meta +119 -0
  301. package/Shaders/Surfaces/Textures.meta +8 -0
  302. package/Shaders/Surfaces/Triplanar.shader +229 -0
  303. package/Shaders/Surfaces/Triplanar.shader.meta +9 -0
  304. package/Shaders/Surfaces/Water.shader +215 -0
  305. package/Shaders/Surfaces/Water.shader.meta +9 -0
  306. package/Shaders/Surfaces.meta +8 -0
  307. package/Shaders/Terrain/Terrain-Height-Bands.shader +178 -0
  308. package/Shaders/Terrain/Terrain-Height-Bands.shader.meta +9 -0
  309. package/Shaders/Terrain/Terrain-Mono.shader +147 -0
  310. package/Shaders/Terrain/Terrain-Mono.shader.meta +9 -0
  311. package/Shaders/Terrain.meta +8 -0
  312. package/Shaders/Weathering/Damp-Base.shader +185 -0
  313. package/Shaders/Weathering/Damp-Base.shader.meta +9 -0
  314. package/Shaders/Weathering/Decal-Masked.shadergraph +3374 -0
  315. package/Shaders/Weathering/Decal-Masked.shadergraph.meta +20 -0
  316. package/Shaders/Weathering/Snow-Top.shader +185 -0
  317. package/Shaders/Weathering/Snow-Top.shader.meta +9 -0
  318. package/Shaders/Weathering/SurfaceBase.hlsl +42 -0
  319. package/Shaders/Weathering/SurfaceBase.hlsl.meta +7 -0
  320. package/Shaders/Weathering/SurfaceDepthNormalsPass.hlsl +90 -0
  321. package/Shaders/Weathering/SurfaceDepthNormalsPass.hlsl.meta +7 -0
  322. package/Shaders/Weathering/SurfaceForwardPass.hlsl +182 -0
  323. package/Shaders/Weathering/SurfaceForwardPass.hlsl.meta +7 -0
  324. package/Shaders/Weathering/Textures/Ripples/Ripple-00.png +0 -0
  325. package/Shaders/Weathering/Textures/Ripples/Ripple-00.png.meta +119 -0
  326. package/Shaders/Weathering/Textures/Ripples/Ripple-01.png +0 -0
  327. package/Shaders/Weathering/Textures/Ripples/Ripple-01.png.meta +119 -0
  328. package/Shaders/Weathering/Textures/Ripples/Ripple-02.png +0 -0
  329. package/Shaders/Weathering/Textures/Ripples/Ripple-02.png.meta +119 -0
  330. package/Shaders/Weathering/Textures/Ripples/Ripple-03.png +0 -0
  331. package/Shaders/Weathering/Textures/Ripples/Ripple-03.png.meta +119 -0
  332. package/Shaders/Weathering/Textures/Ripples/Ripple-04.png +0 -0
  333. package/Shaders/Weathering/Textures/Ripples/Ripple-04.png.meta +119 -0
  334. package/Shaders/Weathering/Textures/Ripples/Ripple-05.png +0 -0
  335. package/Shaders/Weathering/Textures/Ripples/Ripple-05.png.meta +119 -0
  336. package/Shaders/Weathering/Textures/Ripples/Ripple-06.png +0 -0
  337. package/Shaders/Weathering/Textures/Ripples/Ripple-06.png.meta +119 -0
  338. package/Shaders/Weathering/Textures/Ripples/Ripple-07.png +0 -0
  339. package/Shaders/Weathering/Textures/Ripples/Ripple-07.png.meta +119 -0
  340. package/Shaders/Weathering/Textures/Ripples/Ripple-08.png +0 -0
  341. package/Shaders/Weathering/Textures/Ripples/Ripple-08.png.meta +119 -0
  342. package/Shaders/Weathering/Textures/Ripples/Ripple-09.png +0 -0
  343. package/Shaders/Weathering/Textures/Ripples/Ripple-09.png.meta +119 -0
  344. package/Shaders/Weathering/Textures/Ripples/Ripple-10.png +0 -0
  345. package/Shaders/Weathering/Textures/Ripples/Ripple-10.png.meta +119 -0
  346. package/Shaders/Weathering/Textures/Ripples/Ripple-11.png +0 -0
  347. package/Shaders/Weathering/Textures/Ripples/Ripple-11.png.meta +119 -0
  348. package/Shaders/Weathering/Textures/Ripples/Ripple-12.png +0 -0
  349. package/Shaders/Weathering/Textures/Ripples/Ripple-12.png.meta +119 -0
  350. package/Shaders/Weathering/Textures/Ripples/Ripple-13.png +0 -0
  351. package/Shaders/Weathering/Textures/Ripples/Ripple-13.png.meta +119 -0
  352. package/Shaders/Weathering/Textures/Ripples/Ripple-14.png +0 -0
  353. package/Shaders/Weathering/Textures/Ripples/Ripple-14.png.meta +119 -0
  354. package/Shaders/Weathering/Textures/Ripples/Ripple-15.png +0 -0
  355. package/Shaders/Weathering/Textures/Ripples/Ripple-15.png.meta +119 -0
  356. package/Shaders/Weathering/Textures/Ripples.meta +8 -0
  357. package/Shaders/Weathering/Textures/T_Decal_Soft-Square_Mask.png +0 -0
  358. package/Shaders/Weathering/Textures/T_Decal_Soft-Square_Mask.png.meta +119 -0
  359. package/Shaders/Weathering/Textures.meta +8 -0
  360. package/Shaders/Weathering/Wet-Puddles.shader +215 -0
  361. package/Shaders/Weathering/Wet-Puddles.shader.meta +9 -0
  362. package/Shaders/Weathering.meta +8 -0
  363. package/Shaders.meta +8 -0
  364. package/Third Party Notices.md +48 -0
  365. package/package.json +54 -5
package/CHANGELOG.md CHANGED
@@ -1,4 +1,7 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0 — 2026-11-03
4
+ The tools: camera breathing, planar reflection, reference overlay, ripple flipbook, terrain helpers, the mesh-health and texel-density windows, material from texture maps, and the shaders. Eight showcase samples, one per tool family. Needs URP and ProBuilder.
5
+
3
6
  ## 1.0.0 — 2026-10-27
4
7
  First version: the empty package.
@@ -0,0 +1,335 @@
1
+ // Material From Texture Maps - a folder of PBR texture maps (ambientCG, Poly Haven...) becomes one URP Lit material.
2
+ // 1. finds the sets in the folder by their file names (colour, normal, roughness, metal, occlusion, height)
3
+ // 2. fixes the import settings: colour sRGB on, normal map as Normal map, every data map sRGB off
4
+ // 3. packs metallic (RGB) and smoothness = 1 - roughness (A) into <Set>_MetallicSmoothness.png
5
+ // 4. makes M_<Set>.mat (URP Lit) with every map, tiled to the surface's real size (Tiling = 1 / real size, for metre UVs)
6
+ // Run on selected Lit materials instead, it converts them: it finds the roughness map next to the Base Map
7
+ // (or a roughness map sitting in the Metallic Map slot), packs it and assigns the packed map.
8
+ // Install: Assets/_Staging/com.mavrodiev.toolbox/Editor/Material-From-Texture-Maps/MaterialFromTextureMaps.cs
9
+ // In the package, the Editor asmdef needs: Unity.RenderPipelines.Universal.Editor, Unity.RenderPipelines.Universal.Runtime,
10
+ // Unity.RenderPipelines.Core.Runtime.
11
+
12
+ using System.Collections.Generic;
13
+ using System.IO;
14
+ using System.Linq;
15
+ using System.Text;
16
+ using System.Text.RegularExpressions;
17
+ using UnityEditor;
18
+ using UnityEngine;
19
+
20
+ namespace Mavrodiev.Toolbox.Editor
21
+ {
22
+ public enum MapRole { None, Color, NormalGL, NormalDX, Roughness, Metallic, Occlusion, Height, Opacity, PackedARM }
23
+
24
+ public class MaterialFromTextureMaps : EditorWindow
25
+ {
26
+ // the role of a map, from the last word of its file name; longer words first
27
+ static readonly (string word, MapRole role)[] Words =
28
+ {
29
+ ("normal_gl", MapRole.NormalGL), ("normalgl", MapRole.NormalGL), ("nor_gl", MapRole.NormalGL),
30
+ ("normal_dx", MapRole.NormalDX), ("normaldx", MapRole.NormalDX), ("nor_dx", MapRole.NormalDX),
31
+ ("ambientocclusion", MapRole.Occlusion), ("ambient_occlusion", MapRole.Occlusion), ("occlusion", MapRole.Occlusion), ("ao", MapRole.Occlusion),
32
+ ("basecolor", MapRole.Color), ("base_color", MapRole.Color), ("albedo", MapRole.Color), ("diffuse", MapRole.Color),
33
+ ("diff", MapRole.Color), ("colour", MapRole.Color), ("color", MapRole.Color), ("col", MapRole.Color),
34
+ ("roughness", MapRole.Roughness), ("rough", MapRole.Roughness),
35
+ ("metalness", MapRole.Metallic), ("metallic", MapRole.Metallic), ("metal", MapRole.Metallic),
36
+ ("displacement", MapRole.Height), ("height", MapRole.Height), ("disp", MapRole.Height),
37
+ ("opacity", MapRole.Opacity), ("alpha", MapRole.Opacity),
38
+ ("arm", MapRole.PackedARM),
39
+ ("normal", MapRole.NormalGL), ("nor", MapRole.NormalGL), ("nrm", MapRole.NormalGL),
40
+ };
41
+
42
+ // resolution and format words left in by the download sites: _1K, -JPG, _2k, _png...
43
+ static readonly Regex Noise = new Regex(@"[_\- ](\d+k|jpg|jpeg|png|exr|tif|tiff)(?=[_\- ]|$)", RegexOptions.IgnoreCase);
44
+
45
+ DefaultAsset folder;
46
+ float realSize = 2f;
47
+ bool useHeight;
48
+ DefaultAsset outputFolder;
49
+ string report = "";
50
+ Vector2 scroll;
51
+
52
+ [MenuItem("Tools/Mavrodiev/Material From Texture Maps", false, 1000)]
53
+ public static void Open() => GetWindow<MaterialFromTextureMaps>("Material From Texture Maps");
54
+
55
+ [MenuItem("Assets/Mavrodiev/Material From Texture Maps", false, 1000)]
56
+ static void OpenOnSelection()
57
+ {
58
+ var window = GetWindow<MaterialFromTextureMaps>("Material From Texture Maps");
59
+ var path = AssetDatabase.GetAssetPath(Selection.activeObject);
60
+ if (!AssetDatabase.IsValidFolder(path)) path = Path.GetDirectoryName(path)?.Replace('\\', '/');
61
+ if (!string.IsNullOrEmpty(path)) window.folder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(path);
62
+ }
63
+
64
+ void OnGUI()
65
+ {
66
+ EditorGUILayout.LabelField("Make a material from a folder of maps", EditorStyles.boldLabel);
67
+ folder = (DefaultAsset)EditorGUILayout.ObjectField("Maps folder", folder, typeof(DefaultAsset), false);
68
+ realSize = Mathf.Max(0.01f, EditorGUILayout.FloatField("Real size (m)", realSize));
69
+ EditorGUILayout.HelpBox("Tiling = 1 ÷ real size, for surfaces whose UVs are in metres (ProBuilder, a 1 m cube). On other meshes, set Tiling after.", MessageType.None);
70
+ useHeight = EditorGUILayout.Toggle("Use height map", useHeight);
71
+ outputFolder = (DefaultAsset)EditorGUILayout.ObjectField("Save in (empty: with the maps)", outputFolder, typeof(DefaultAsset), false);
72
+ using (new EditorGUI.DisabledScope(folder == null))
73
+ if (GUILayout.Button("Make material")) report = MakeFromFolder(AssetDatabase.GetAssetPath(folder), realSize, useHeight,
74
+ outputFolder ? AssetDatabase.GetAssetPath(outputFolder) : null);
75
+
76
+ EditorGUILayout.Space();
77
+ EditorGUILayout.LabelField("Convert the selected Lit materials", EditorStyles.boldLabel);
78
+ var selected = Selection.GetFiltered<Material>(SelectionMode.Assets);
79
+ using (new EditorGUI.DisabledScope(selected.Length == 0))
80
+ if (GUILayout.Button($"Convert {selected.Length} selected material(s)")) report = Convert(selected);
81
+
82
+ EditorGUILayout.Space();
83
+ scroll = EditorGUILayout.BeginScrollView(scroll);
84
+ EditorGUILayout.HelpBox(report == "" ? "Nothing done yet." : report, MessageType.Info);
85
+ EditorGUILayout.EndScrollView();
86
+ }
87
+
88
+ // ---------- finding the maps ----------
89
+
90
+ public static (string set, MapRole role) Classify(string assetPath)
91
+ {
92
+ var name = Path.GetFileNameWithoutExtension(assetPath);
93
+ if (name.ToLowerInvariant().Contains("metallicsmoothness")) return (null, MapRole.None); // our own output
94
+ var clean = Noise.Replace(name, ""); // the set name keeps its own spelling
95
+ var lower = clean.ToLowerInvariant().Replace('-', '_').Replace(' ', '_'); // matching ignores the separator
96
+ foreach (var (word, role) in Words)
97
+ if (lower.EndsWith("_" + word))
98
+ return (clean.Substring(0, clean.Length - word.Length - 1), role);
99
+ return (null, MapRole.None);
100
+ }
101
+
102
+ static Dictionary<string, Dictionary<MapRole, string>> FindSets(string folderPath)
103
+ {
104
+ var sets = new Dictionary<string, Dictionary<MapRole, string>>();
105
+ foreach (var guid in AssetDatabase.FindAssets("t:Texture2D", new[] { folderPath }))
106
+ {
107
+ var path = AssetDatabase.GUIDToAssetPath(guid);
108
+ var (set, role) = Classify(path);
109
+ if (role == MapRole.None) continue;
110
+ var key = Path.GetDirectoryName(path).Replace('\\', '/') + "/" + set; // a set lives in one folder
111
+ if (!sets.TryGetValue(key, out var maps)) sets[key] = maps = new Dictionary<MapRole, string>();
112
+ if (!maps.ContainsKey(role)) maps[role] = path;
113
+ }
114
+ return sets;
115
+ }
116
+
117
+ // ---------- 1. import settings ----------
118
+
119
+ static void FixImport(string path, MapRole role)
120
+ {
121
+ if (!(AssetImporter.GetAtPath(path) is TextureImporter importer)) return;
122
+ bool changed = false;
123
+ if (role == MapRole.NormalGL || role == MapRole.NormalDX)
124
+ {
125
+ if (importer.textureType != TextureImporterType.NormalMap) { importer.textureType = TextureImporterType.NormalMap; changed = true; }
126
+ bool flip = role == MapRole.NormalDX; // DirectX normals: green points down; Unity reads OpenGL normals
127
+ if (importer.flipGreenChannel != flip) { importer.flipGreenChannel = flip; changed = true; }
128
+ }
129
+ else
130
+ {
131
+ if (importer.textureType != TextureImporterType.Default) { importer.textureType = TextureImporterType.Default; changed = true; }
132
+ bool srgb = role == MapRole.Color; // only the colour is shown to the eye; the rest are numbers
133
+ if (importer.sRGBTexture != srgb) { importer.sRGBTexture = srgb; changed = true; }
134
+ }
135
+ if (changed) importer.SaveAndReimport();
136
+ }
137
+
138
+ // ---------- 2. packing ----------
139
+
140
+ // Reads a texture's pixels through the GPU, so the texture does not need Read/Write enabled.
141
+ // The data maps are sRGB off by then, so the values come through unchanged.
142
+ static Color[] ReadPixels(Texture texture, int width, int height)
143
+ {
144
+ var rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
145
+ Graphics.Blit(texture, rt);
146
+ var previous = RenderTexture.active;
147
+ RenderTexture.active = rt;
148
+ var copy = new Texture2D(width, height, TextureFormat.RGBA32, false, true);
149
+ copy.ReadPixels(new Rect(0, 0, width, height), 0, 0);
150
+ copy.Apply();
151
+ RenderTexture.active = previous;
152
+ RenderTexture.ReleaseTemporary(rt);
153
+ var pixels = copy.GetPixels();
154
+ DestroyImmediate(copy);
155
+ return pixels;
156
+ }
157
+
158
+ // Metallic in R, G and B (white = bare metal), smoothness = 1 - roughness in A: what URP Lit's Metallic Map reads.
159
+ public static Texture2D Pack(string roughnessPath, string metallicPath, string outputPath)
160
+ {
161
+ var roughness = AssetDatabase.LoadAssetAtPath<Texture2D>(roughnessPath);
162
+ var metallic = metallicPath != null ? AssetDatabase.LoadAssetAtPath<Texture2D>(metallicPath) : null;
163
+ int width = roughness.width, height = roughness.height;
164
+ var rough = ReadPixels(roughness, width, height);
165
+ var metal = metallic != null ? ReadPixels(metallic, width, height) : null;
166
+
167
+ var packed = new Texture2D(width, height, TextureFormat.RGBA32, false, true);
168
+ var pixels = new Color[rough.Length];
169
+ for (int i = 0; i < pixels.Length; i++)
170
+ {
171
+ float m = metal != null ? metal[i].r : 0f;
172
+ pixels[i] = new Color(m, m, m, 1f - rough[i].r);
173
+ }
174
+ packed.SetPixels(pixels);
175
+ packed.Apply();
176
+ File.WriteAllBytes(outputPath, packed.EncodeToPNG());
177
+ DestroyImmediate(packed);
178
+
179
+ AssetDatabase.ImportAsset(outputPath, ImportAssetOptions.ForceUpdate);
180
+ if (AssetImporter.GetAtPath(outputPath) is TextureImporter importer)
181
+ {
182
+ importer.textureType = TextureImporterType.Default;
183
+ importer.sRGBTexture = false;
184
+ importer.alphaSource = TextureImporterAlphaSource.FromInput;
185
+ importer.alphaIsTransparency = false;
186
+ importer.SaveAndReimport();
187
+ }
188
+ return AssetDatabase.LoadAssetAtPath<Texture2D>(outputPath);
189
+ }
190
+
191
+ // ---------- 3. the material ----------
192
+
193
+ static void SetKeywords(Material material)
194
+ {
195
+ // URP's own keyword set-up, the same the Lit Inspector runs (verified public in URP 17.6)
196
+ BaseShaderGUI.SetMaterialKeywords(material, UnityEditor.Rendering.Universal.ShaderGUI.LitGUI.SetMaterialKeywords);
197
+ }
198
+
199
+ static Texture2D Load(Dictionary<MapRole, string> maps, MapRole role) =>
200
+ maps.TryGetValue(role, out var path) ? AssetDatabase.LoadAssetAtPath<Texture2D>(path) : null;
201
+
202
+ // the normal map, OpenGL or DirectX (no ?? on Unity objects: a destroyed object is not null to ??)
203
+ static Texture2D LoadNormal(Dictionary<MapRole, string> maps)
204
+ {
205
+ var normal = Load(maps, MapRole.NormalGL);
206
+ if (normal == null) normal = Load(maps, MapRole.NormalDX);
207
+ return normal;
208
+ }
209
+
210
+ public static string MakeFromFolder(string folderPath, float realSize, bool useHeight, string outputFolder)
211
+ {
212
+ var log = new StringBuilder();
213
+ var sets = FindSets(folderPath);
214
+ if (sets.Count == 0) return "No texture maps found (the names need a last word such as _Color, _NormalGL, _Roughness).";
215
+ var lit = Shader.Find("Universal Render Pipeline/Lit");
216
+
217
+ foreach (var pair in sets)
218
+ {
219
+ var setFolder = Path.GetDirectoryName(pair.Key).Replace('\\', '/');
220
+ var setName = Path.GetFileName(pair.Key);
221
+ var maps = pair.Value;
222
+ if (maps.ContainsKey(MapRole.PackedARM) && !maps.ContainsKey(MapRole.Roughness))
223
+ log.AppendLine($"{setName}: a packed ARM map is not used (Lit reads occlusion from green, where ARM keeps roughness). Download the separate maps.");
224
+ if (!maps.ContainsKey(MapRole.Color)) { log.AppendLine($"{setName}: no colour map, skipped."); continue; }
225
+
226
+ foreach (var map in maps) FixImport(map.Value, map.Key);
227
+
228
+ Texture2D packed = null;
229
+ if (maps.TryGetValue(MapRole.Roughness, out var roughPath))
230
+ {
231
+ maps.TryGetValue(MapRole.Metallic, out var metalPath);
232
+ packed = Pack(roughPath, metalPath, $"{setFolder}/{setName}_MetallicSmoothness.png");
233
+ }
234
+
235
+ var saveFolder = string.IsNullOrEmpty(outputFolder) ? setFolder : outputFolder;
236
+ var materialPath = $"{saveFolder}/M_{setName}.mat";
237
+ var material = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
238
+ bool isNew = material == null;
239
+ if (isNew) material = new Material(lit);
240
+
241
+ material.SetTexture("_BaseMap", Load(maps, MapRole.Color));
242
+ material.SetColor("_BaseColor", Color.white);
243
+ var normal = LoadNormal(maps);
244
+ material.SetTexture("_BumpMap", normal);
245
+ material.SetFloat("_BumpScale", 1f);
246
+ material.SetTexture("_OcclusionMap", Load(maps, MapRole.Occlusion));
247
+ material.SetFloat("_OcclusionStrength", 1f);
248
+ if (packed != null)
249
+ {
250
+ material.SetTexture("_MetallicGlossMap", packed);
251
+ material.SetFloat("_SmoothnessTextureChannel", 0f); // smoothness from the Metallic Map's alpha
252
+ material.SetFloat("_Smoothness", 1f); // the slider scales the map: 1 = the map as it is
253
+ }
254
+ else
255
+ {
256
+ material.SetFloat("_Metallic", 0f);
257
+ material.SetFloat("_Smoothness", 0.5f);
258
+ log.AppendLine($"{setName}: no roughness map, Smoothness left at 0.5: set it by eye.");
259
+ }
260
+ var height = useHeight ? Load(maps, MapRole.Height) : null;
261
+ material.SetTexture("_ParallaxMap", height);
262
+ if (height != null) material.SetFloat("_Parallax", 0.02f);
263
+ material.SetTextureScale("_BaseMap", Vector2.one / realSize); // Lit uses the Base Map's tiling for every map
264
+ material.SetTextureOffset("_BaseMap", Vector2.zero);
265
+ SetKeywords(material);
266
+
267
+ if (isNew) AssetDatabase.CreateAsset(material, materialPath);
268
+ else EditorUtility.SetDirty(material);
269
+ log.AppendLine($"{setName}: {materialPath} ({string.Join(", ", maps.Keys)}), Tiling {1f / realSize:0.###}.");
270
+ }
271
+ AssetDatabase.SaveAssets();
272
+ Debug.Log("Material From Texture Maps\n" + log);
273
+ return log.ToString();
274
+ }
275
+
276
+ // ---------- converting existing materials ----------
277
+
278
+ public static string Convert(IEnumerable<Material> materials)
279
+ {
280
+ var log = new StringBuilder();
281
+ foreach (var material in materials)
282
+ {
283
+ var shaderName = material.shader != null ? material.shader.name : "";
284
+ if (shaderName != "Universal Render Pipeline/Lit" && shaderName != "Universal Render Pipeline/Complex Lit")
285
+ {
286
+ log.AppendLine($"{material.name}: not a URP Lit material ({shaderName}), skipped. Convert it to URP first.");
287
+ continue;
288
+ }
289
+ var baseMap = material.GetTexture("_BaseMap");
290
+ if (baseMap == null) { log.AppendLine($"{material.name}: no Base Map, skipped."); continue; }
291
+
292
+ var basePath = AssetDatabase.GetAssetPath(baseMap);
293
+ var (setName, _) = Classify(basePath);
294
+ var setFolder = Path.GetDirectoryName(basePath).Replace('\\', '/');
295
+ var sets = FindSets(setFolder);
296
+ sets.TryGetValue(setFolder + "/" + setName, out var maps);
297
+ if (maps == null) maps = new Dictionary<MapRole, string>();
298
+
299
+ // a roughness map placed in the Metallic Map slot (it reads as reversed smoothness)
300
+ var inSlot = material.GetTexture("_MetallicGlossMap");
301
+ bool fromSlot = false;
302
+ if (inSlot != null && Classify(AssetDatabase.GetAssetPath(inSlot)).role == MapRole.Roughness)
303
+ {
304
+ maps[MapRole.Roughness] = AssetDatabase.GetAssetPath(inSlot);
305
+ fromSlot = true;
306
+ }
307
+
308
+ if (!maps.TryGetValue(MapRole.Roughness, out var roughPath))
309
+ {
310
+ log.AppendLine($"{material.name}: no roughness map found next to its Base Map, nothing to convert.");
311
+ continue;
312
+ }
313
+ foreach (var map in maps) FixImport(map.Value, map.Key);
314
+ maps.TryGetValue(MapRole.Metallic, out var metalPath);
315
+ var packedName = string.IsNullOrEmpty(setName) ? material.name : setName;
316
+ var packedPath = $"{setFolder}/{packedName}_MetallicSmoothness.png";
317
+ // the set is already packed (a library set, or a second material on the same maps): use that map
318
+ var packed = fromSlot ? null : AssetDatabase.LoadAssetAtPath<Texture2D>(packedPath);
319
+ if (packed == null) packed = Pack(roughPath, metalPath, packedPath);
320
+
321
+ material.SetTexture("_MetallicGlossMap", packed);
322
+ material.SetFloat("_SmoothnessTextureChannel", 0f);
323
+ material.SetFloat("_Smoothness", 1f);
324
+ if (material.GetTexture("_BumpMap") == null) material.SetTexture("_BumpMap", LoadNormal(maps));
325
+ if (material.GetTexture("_OcclusionMap") == null) material.SetTexture("_OcclusionMap", Load(maps, MapRole.Occlusion));
326
+ SetKeywords(material);
327
+ EditorUtility.SetDirty(material);
328
+ log.AppendLine($"{material.name}: {packedName}_MetallicSmoothness.png (smoothness = 1 - roughness) assigned to the Metallic Map; tiling kept.");
329
+ }
330
+ AssetDatabase.SaveAssets();
331
+ Debug.Log("Material From Texture Maps (convert)\n" + log);
332
+ return log.ToString();
333
+ }
334
+ }
335
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: b337a620dc8eb8c4095c1a946b60e6c6
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: e6c1d13240782e54da188025cc8d60fa
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "Mavrodiev.Toolbox.Editor",
3
3
  "rootNamespace": "Mavrodiev.Toolbox.Editor",
4
- "references": [ "Mavrodiev.Toolbox" ],
5
- "includePlatforms": [ "Editor" ],
4
+ "references": [
5
+ "Mavrodiev.Toolbox",
6
+ "Unity.RenderPipelines.Universal.Runtime",
7
+ "Unity.RenderPipelines.Universal.Editor",
8
+ "Unity.RenderPipelines.Core.Runtime",
9
+ "Unity.RenderPipelines.Core.Editor"
10
+ ],
11
+ "includePlatforms": [
12
+ "Editor"
13
+ ],
6
14
  "excludePlatforms": [],
7
15
  "allowUnsafeCode": false,
8
16
  "overrideReferences": false,
@@ -0,0 +1,154 @@
1
+ using System.Collections.Generic;
2
+ using UnityEditor;
3
+ using UnityEngine;
4
+
5
+ namespace Mavrodiev.Toolbox.Editor
6
+ {
7
+ /// <summary>
8
+ /// Mesh Health: select one or more objects and read what is wrong with their meshes —
9
+ /// holes (open edges), faces turned inside out, scale not 1, size and pivot off the grid,
10
+ /// missing materials, and the triangle count. It only reads; it never changes the mesh.
11
+ /// </summary>
12
+ public class MeshHealthWindow : EditorWindow
13
+ {
14
+ const float k_Grid = 0.1f; // size and pivot are "on the grid" in 10 cm steps
15
+ const int k_DenseTriangles = 10000; // above this a single prop counts as dense
16
+
17
+ Vector2 m_Scroll;
18
+ readonly Dictionary<MeshFilter, Result> m_Cache = new Dictionary<MeshFilter, Result>();
19
+
20
+ [MenuItem("Tools/Mavrodiev/Mesh Health")]
21
+ public static void Open()
22
+ {
23
+ var w = GetWindow<MeshHealthWindow>();
24
+ w.titleContent = new GUIContent("Mesh Health");
25
+ w.Show();
26
+ }
27
+
28
+ void OnSelectionChange() { m_Cache.Clear(); Repaint(); }
29
+ void OnFocus() => m_Cache.Clear();
30
+
31
+ void OnGUI()
32
+ {
33
+ var targets = Selection.gameObjects;
34
+ if (targets.Length == 0)
35
+ {
36
+ EditorGUILayout.HelpBox("Select an object with a mesh in the Hierarchy.", MessageType.Info);
37
+ return;
38
+ }
39
+
40
+ if (GUILayout.Button("Check again")) m_Cache.Clear();
41
+ m_Scroll = EditorGUILayout.BeginScrollView(m_Scroll);
42
+ foreach (var go in targets)
43
+ {
44
+ foreach (var mf in go.GetComponentsInChildren<MeshFilter>())
45
+ DrawReport(mf, m_Cache);
46
+ }
47
+ EditorGUILayout.EndScrollView();
48
+ }
49
+
50
+ static void DrawReport(MeshFilter mf, Dictionary<MeshFilter, Result> cache)
51
+ {
52
+ var mesh = mf.sharedMesh;
53
+ EditorGUILayout.Space(6);
54
+ EditorGUILayout.LabelField(mf.gameObject.name, EditorStyles.boldLabel);
55
+ if (mesh == null)
56
+ {
57
+ EditorGUILayout.HelpBox("The Mesh Filter has no mesh.", MessageType.Error);
58
+ return;
59
+ }
60
+ if (!cache.TryGetValue(mf, out var r)) { r = Check(mf); cache[mf] = r; }
61
+ Line(r.openEdges == 0, r.openEdges == 0 ? "Closed: no holes." : r.openEdges + " open edges: the mesh has holes.");
62
+ Line(r.signedVolume >= 0f, r.signedVolume >= 0f ? "Faces point outward." : "Faces point inward: the mesh is inside out (flipped normals).");
63
+ Line(r.scaleIsOne, r.scaleIsOne ? "Scale is 1, 1, 1." : "Scale is " + Vec(r.scale) + ", not 1. Fix the size in the import settings or the mesh.");
64
+ Line(!r.looksLikeCentimetres, r.looksLikeCentimetres ? "The mesh is " + Vec(r.meshSize) + " m: probably made in centimetres (try Scale Factor 0.01)." : "Mesh size " + Vec(r.meshSize) + " m.");
65
+ Line(r.sizeOnGrid, r.sizeOnGrid ? "Size is in whole 10 cm steps." : "Size is off the 10 cm grid.");
66
+ Line(r.pivotOnGrid, r.pivotOnGrid ? "Pivot sits on a corner, an edge midpoint or the centre of the base." : "Pivot is " + Vec(r.pivotOffset) + " m from the bottom corner: off the grid.");
67
+ Line(r.missingMaterials == 0, r.missingMaterials == 0 ? "Every submesh has a material." : r.missingMaterials + " submesh(es) without a material.");
68
+ Line(r.triangles <= k_DenseTriangles, r.triangles.ToString("N0") + " triangles, " + mesh.vertexCount.ToString("N0") + " vertices.");
69
+ }
70
+
71
+ static void Line(bool ok, string text)
72
+ {
73
+ var icon = EditorGUIUtility.IconContent(ok ? "TestPassed" : "console.warnicon.sml");
74
+ EditorGUILayout.LabelField(new GUIContent(" " + text, icon.image), EditorStyles.wordWrappedLabel);
75
+ }
76
+
77
+ static string Vec(Vector3 v) => v.x.ToString("0.###") + ", " + v.y.ToString("0.###") + ", " + v.z.ToString("0.###");
78
+
79
+ public struct Result
80
+ {
81
+ public int openEdges;
82
+ public float signedVolume;
83
+ public bool scaleIsOne;
84
+ public Vector3 scale;
85
+ public Vector3 meshSize;
86
+ public bool looksLikeCentimetres;
87
+ public bool sizeOnGrid;
88
+ public bool pivotOnGrid;
89
+ public Vector3 pivotOffset;
90
+ public int missingMaterials;
91
+ public int triangles;
92
+ }
93
+
94
+ /// <summary>Runs every check on one Mesh Filter (in the Editor every mesh can be read).</summary>
95
+ public static Result Check(MeshFilter mf)
96
+ {
97
+ var mesh = mf.sharedMesh;
98
+ var res = new Result();
99
+ var v = mesh.vertices;
100
+ var t = mesh.triangles;
101
+ res.triangles = t.Length / 3;
102
+
103
+ // Holes: weld vertices by position, then count edges used by exactly one triangle.
104
+ var weld = new Dictionary<Vector3Int, int>();
105
+ var id = new int[v.Length];
106
+ for (int i = 0; i < v.Length; i++)
107
+ {
108
+ var k = new Vector3Int(Mathf.RoundToInt(v[i].x * 1000f), Mathf.RoundToInt(v[i].y * 1000f), Mathf.RoundToInt(v[i].z * 1000f));
109
+ if (!weld.TryGetValue(k, out id[i])) { id[i] = weld.Count; weld.Add(k, id[i]); }
110
+ }
111
+ var edges = new Dictionary<long, int>();
112
+ double vol = 0;
113
+ for (int i = 0; i < t.Length; i += 3)
114
+ {
115
+ for (int e = 0; e < 3; e++)
116
+ {
117
+ int a = id[t[i + e]], b = id[t[i + (e + 1) % 3]];
118
+ long key = a < b ? ((long)a << 32) | (uint)b : ((long)b << 32) | (uint)a;
119
+ edges.TryGetValue(key, out int n);
120
+ edges[key] = n + 1;
121
+ }
122
+ vol += Vector3.Dot(v[t[i]], Vector3.Cross(v[t[i + 1]], v[t[i + 2]])) / 6.0;
123
+ }
124
+ foreach (var n in edges.Values) if (n == 1) res.openEdges++;
125
+ res.signedVolume = (float)vol;
126
+
127
+ // Scale and size.
128
+ res.scale = mf.transform.lossyScale;
129
+ res.scaleIsOne = Approx(res.scale.x, 1f) && Approx(res.scale.y, 1f) && Approx(res.scale.z, 1f);
130
+ var b0 = mesh.bounds;
131
+ res.meshSize = b0.size;
132
+ res.looksLikeCentimetres = Mathf.Max(b0.size.x, Mathf.Max(b0.size.y, b0.size.z)) > 30f;
133
+ res.sizeOnGrid = OnGrid(b0.size.x) && OnGrid(b0.size.y) && OnGrid(b0.size.z);
134
+
135
+ // Pivot (the mesh's origin) against the bounds: a corner, an edge midpoint or the base centre.
136
+ res.pivotOffset = -b0.min;
137
+ res.pivotOnGrid = PivotOk(b0.min.x, b0.max.x) && Approx(b0.min.y, 0f) && PivotOk(b0.min.z, b0.max.z);
138
+
139
+ // Materials.
140
+ var mr = mf.GetComponent<Renderer>();
141
+ if (mr != null)
142
+ {
143
+ var mats = mr.sharedMaterials;
144
+ for (int s = 0; s < mesh.subMeshCount; s++)
145
+ if (s >= mats.Length || mats[s] == null) res.missingMaterials++;
146
+ }
147
+ return res;
148
+ }
149
+
150
+ static bool Approx(float a, float b) => Mathf.Abs(a - b) < 0.001f;
151
+ static bool OnGrid(float x) => Mathf.Abs(x / k_Grid - Mathf.Round(x / k_Grid)) < 0.01f;
152
+ static bool PivotOk(float min, float max) => Approx(min, 0f) || Approx(max, 0f) || Approx(min + max, 0f);
153
+ }
154
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: adfd264297d5cce49b26af7319c4a30a