LuxUberShaderGUI.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. using UnityEngine.Rendering;
  5. using UnityEditor.Rendering.Universal;
  6. namespace UnityEditor
  7. {
  8. public class LuxUberShaderGUI : ShaderGUI
  9. {
  10. public enum SurfaceType {
  11. Opaque,
  12. Transparent
  13. }
  14. public enum BlendMode {
  15. Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency
  16. Premultiply, // Physically plausible transparency mode, implemented as alpha pre-multiply
  17. Additive,
  18. Multiply
  19. }
  20. public enum WorkflowMode {
  21. Specular = 0,
  22. Metallic = 1
  23. }
  24. public enum RenderFace {
  25. Both = 0,
  26. Back = 1,
  27. Front = 2
  28. }
  29. public enum SmoothnessMapChannel {
  30. SpecularMetallicAlpha,
  31. AlbedoAlpha,
  32. }
  33. public static class Styles {
  34. public static readonly string[] metallicSmoothnessChannelNames = {"Metallic Alpha", "Albedo Alpha"};
  35. public static readonly string[] specularSmoothnessChannelNames = {"Specular Alpha", "Albedo Alpha"};
  36. }
  37. static string url = "https://docs.google.com/document/d/1ck3hmPzKUdewHfwsvmPYwSPCP8azwtpzN7aOLJHvMqE/edit#heading=h.thxlhugei9is";
  38. static Texture2D helpIcon = EditorGUIUtility.FindTexture("_Help");
  39. static GUIContent helpbuttonGUIContent = new GUIContent(helpIcon, "Open Online Documentation");
  40. public bool openSurfaceOptions = false;
  41. public bool openSurfaceInputs = false;
  42. public bool openDetailSurfaceInputs = false;
  43. public bool openAdvancedSurfaceInputs = false;
  44. public bool openRimLighingInputs = false;
  45. public bool openStencilOptions = false;
  46. public bool openAdvancedOptions = false;
  47. private MaterialProperty surfaceOptionsProps;
  48. private MaterialProperty surfaceInputsProps;
  49. private MaterialProperty surfaceDetailInputsProps;
  50. private MaterialProperty advancedSurfaceInputsProps;
  51. private MaterialProperty RimLighingInputsProps;
  52. private MaterialProperty stencilOptionsProps;
  53. private MaterialProperty advancedOptionsProps;
  54. private MaterialProperty surfaceTypeProp;
  55. private MaterialProperty blendModeProp;
  56. private MaterialProperty workflowmodeProp;
  57. private MaterialProperty ztestProp;
  58. private MaterialProperty cullingProp;
  59. private MaterialProperty alphaClipProp;
  60. private MaterialProperty alphaCutoffProp;
  61. private MaterialProperty cameraFadingEnabledProp;
  62. private MaterialProperty cameraFadeDistProp;
  63. private MaterialProperty cameraFadeShadowsProp;
  64. private MaterialProperty cameraShadowFadeDistProp;
  65. private MaterialProperty receiveShadowsProp;
  66. private MaterialProperty baseColorProp;
  67. private MaterialProperty baseMapProp;
  68. private MaterialProperty specGlossMapProp;
  69. private MaterialProperty specColorProp;
  70. private MaterialProperty metallicGlossMapProp;
  71. private MaterialProperty metallicProp;
  72. private MaterialProperty smoothnessProp;
  73. private MaterialProperty smoothnessMapChannelProp;
  74. private MaterialProperty bumpMapProp;
  75. private MaterialProperty bumpMapScaleProp;
  76. private MaterialProperty enableNormalProp;
  77. private MaterialProperty occlusionStrengthProp;
  78. private MaterialProperty occlusionMapProp;
  79. private MaterialProperty enableOcclusionProp;
  80. private MaterialProperty emissionColorProp;
  81. private MaterialProperty emissionMapProp;
  82. private MaterialProperty emissionProp;
  83. private MaterialProperty DetailMask;
  84. private MaterialProperty DetailAlbedoMapScale;
  85. private MaterialProperty DetailAlbedoMap;
  86. private MaterialProperty DetailNormalMapScale;
  87. private MaterialProperty DetailNormalMap;
  88. private MaterialProperty heightMapProp;
  89. private MaterialProperty enableParallaxProp;
  90. private MaterialProperty parallaxProp;
  91. private MaterialProperty enableParallaxShadowsProp;
  92. private MaterialProperty BentNormalMapProp;
  93. private MaterialProperty EnableBentNormalProp;
  94. private MaterialProperty HorizonOcclusionProp;
  95. private MaterialProperty GeometricSpecularAAProp;
  96. private MaterialProperty ScreenSpaceVarianceProp;
  97. private MaterialProperty SAAThresholdProp;
  98. private MaterialProperty AOfromGIProp;
  99. private MaterialProperty GItoAOProp;
  100. private MaterialProperty GItoAOBiasProp;
  101. private MaterialProperty RimProp;
  102. private MaterialProperty RimColorProp;
  103. private MaterialProperty RimPowerProp;
  104. private MaterialProperty RimFrequencyProp;
  105. private MaterialProperty RimMinPowerProp;
  106. private MaterialProperty RimPerPositionFrequencyProp;
  107. private MaterialProperty stencilProp;
  108. private MaterialProperty readMaskProp;
  109. private MaterialProperty writeMaskProp;
  110. private MaterialProperty stencilCompProp;
  111. private MaterialProperty stencilOpProp;
  112. private MaterialProperty stencilFailProp;
  113. private MaterialProperty stenciZfailProp;
  114. private MaterialProperty SpecularHighlightsProps;
  115. private MaterialProperty EnvironmentReflectionsProps;
  116. /*
  117. public virtual void OnOpenGUI(Material material, MaterialEditor materialEditor)
  118. {
  119. // Foldout states
  120. m_HeaderStateKey = k_KeyPrefix + material.shader.name; // Create key string for editor prefs
  121. m_SurfaceOptionsFoldout = new SavedBool($"{m_HeaderStateKey}.SurfaceOptionsFoldout", true);
  122. foreach (var obj in materialEditor.targets)
  123. MaterialChanged((Material)obj);
  124. }
  125. */
  126. public virtual void FindProperties(MaterialProperty[] properties)
  127. {
  128. surfaceOptionsProps = FindProperty("_FoldSurfaceOptions", properties);
  129. surfaceInputsProps = FindProperty("_FoldSurfaceInputs", properties);
  130. surfaceDetailInputsProps = FindProperty("_FoldSurfaceDetailInputs", properties);
  131. advancedSurfaceInputsProps = FindProperty("_FoldAdvancedSurfaceInputs", properties);
  132. RimLighingInputsProps = FindProperty("_FoldRimLightingInputs", properties);
  133. stencilOptionsProps = FindProperty("_FoldStencilOptions", properties);
  134. advancedOptionsProps = FindProperty("_FoldAdvanced", properties);
  135. surfaceTypeProp = FindProperty("_Surface", properties);
  136. blendModeProp = FindProperty("_Blend", properties);
  137. workflowmodeProp = FindProperty("_WorkflowMode", properties);
  138. ztestProp = FindProperty("_ZTest", properties);
  139. cullingProp = FindProperty("_Cull", properties);
  140. alphaClipProp = FindProperty("_AlphaClip", properties);
  141. alphaCutoffProp = FindProperty("_Cutoff", properties);
  142. cameraFadingEnabledProp = FindProperty("_CameraFadingEnabled", properties);
  143. cameraFadeDistProp = FindProperty("_CameraFadeDist", properties);
  144. cameraFadeShadowsProp = FindProperty("_CameraFadeShadows", properties);
  145. cameraShadowFadeDistProp = FindProperty("_CameraShadowFadeDist", properties);
  146. receiveShadowsProp = FindProperty("_ReceiveShadows", properties, false);
  147. baseMapProp = FindProperty("_BaseMap", properties);
  148. baseColorProp = FindProperty("_BaseColor", properties);
  149. specGlossMapProp = FindProperty("_SpecGlossMap", properties);
  150. specColorProp = FindProperty("_SpecColor", properties);
  151. metallicGlossMapProp = FindProperty("_MetallicGlossMap", properties);
  152. metallicProp = FindProperty("_Metallic", properties);
  153. smoothnessProp = FindProperty("_Smoothness", properties);
  154. smoothnessMapChannelProp = FindProperty("_SmoothnessTextureChannel", properties);
  155. bumpMapProp = FindProperty("_BumpMap", properties);
  156. bumpMapScaleProp = FindProperty("_BumpScale", properties);
  157. enableNormalProp = FindProperty("_EnableNormal", properties);
  158. occlusionStrengthProp = FindProperty("_OcclusionStrength", properties);
  159. occlusionMapProp = FindProperty("_OcclusionMap", properties);
  160. enableOcclusionProp = FindProperty("_EnableOcclusion", properties);
  161. emissionColorProp = FindProperty("_EmissionColor", properties);
  162. emissionMapProp = FindProperty("_EmissionMap", properties);
  163. emissionProp = FindProperty("_Emission", properties);
  164. DetailMask = FindProperty("_DetailMask", properties);
  165. DetailAlbedoMapScale = FindProperty("_DetailAlbedoMapScale", properties);
  166. DetailAlbedoMap = FindProperty("_DetailAlbedoMap", properties);
  167. DetailNormalMapScale = FindProperty("_DetailNormalMapScale", properties);
  168. DetailNormalMap = FindProperty("_DetailNormalMap", properties);
  169. //
  170. heightMapProp = FindProperty("_HeightMap", properties);
  171. parallaxProp = FindProperty("_Parallax", properties);
  172. enableParallaxProp = FindProperty("_EnableParallax", properties);
  173. enableParallaxShadowsProp = FindProperty("_EnableParallaxShadows", properties);
  174. BentNormalMapProp = FindProperty("_BentNormalMap", properties);
  175. EnableBentNormalProp = FindProperty("_EnableBentNormal", properties);
  176. HorizonOcclusionProp = FindProperty("_HorizonOcclusion", properties);
  177. GeometricSpecularAAProp = FindProperty("_GeometricSpecularAA", properties);
  178. ScreenSpaceVarianceProp = FindProperty("_ScreenSpaceVariance", properties);
  179. SAAThresholdProp = FindProperty("_SAAThreshold", properties);
  180. AOfromGIProp = FindProperty("_AOfromGI", properties);
  181. GItoAOProp = FindProperty("_GItoAO", properties);
  182. GItoAOBiasProp = FindProperty("_GItoAOBias", properties);
  183. //
  184. RimProp = FindProperty("_Rim", properties);
  185. RimColorProp = FindProperty("_RimColor", properties);
  186. RimPowerProp = FindProperty("_RimPower", properties);
  187. RimFrequencyProp = FindProperty("_RimFrequency", properties);
  188. RimMinPowerProp = FindProperty("_RimMinPower", properties);
  189. RimPerPositionFrequencyProp = FindProperty("_RimPerPositionFrequency", properties);
  190. //
  191. stencilProp = FindProperty("_Stencil", properties);
  192. readMaskProp = FindProperty("_ReadMask", properties);
  193. writeMaskProp = FindProperty("_WriteMask", properties);
  194. stencilCompProp = FindProperty("_StencilComp", properties);
  195. stencilOpProp = FindProperty("_StencilOp", properties);
  196. stencilFailProp = FindProperty("_StencilFail", properties);
  197. stenciZfailProp = FindProperty("_StencilZFail", properties);
  198. SpecularHighlightsProps = FindProperty("_SpecularHighlights", properties);
  199. EnvironmentReflectionsProps = FindProperty("_EnvironmentReflections", properties);
  200. }
  201. public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties)
  202. {
  203. Material material = materialEditor.target as Material;
  204. FindProperties(properties);
  205. // Always needed vars
  206. bool surfaceModeChanged = false;
  207. var workflow = (WorkflowMode)workflowmodeProp.floatValue;
  208. var surface = (SurfaceType)surfaceTypeProp.floatValue;
  209. bool alphaclipChanged = false;
  210. var alphaclip = (alphaClipProp.floatValue == 1)? true : false;
  211. // -----------------------
  212. // Help
  213. var txt = new GUIContent("Help");
  214. var position = GUILayoutUtility.GetRect(txt, GUIStyle.none);
  215. var headerPos = new Rect(position.x + 1, position.y, position.width - 20, 20);
  216. var btnPos = new Rect(position.x + headerPos.width, position.y, 20, 20);
  217. GUI.Label(headerPos, new GUIContent("Help"), EditorStyles.boldLabel);
  218. if (GUI.Button(btnPos, helpbuttonGUIContent, EditorStyles.boldLabel)) {
  219. Help.BrowseURL(url);
  220. }
  221. GUILayout.Space(10);
  222. // -----------------------
  223. // Surface Options
  224. openSurfaceOptions = (surfaceOptionsProps.floatValue == 1.0f) ? true : false;
  225. EditorGUI.BeginChangeCheck();
  226. openSurfaceOptions = EditorGUILayout.BeginFoldoutHeaderGroup(openSurfaceOptions, "Surface Options");
  227. if (EditorGUI.EndChangeCheck()) {
  228. surfaceOptionsProps.floatValue = openSurfaceOptions? 1.0f : 0.0f;
  229. }
  230. if(openSurfaceOptions){
  231. // Workflow
  232. EditorGUI.BeginChangeCheck();
  233. //var workflow = (WorkflowMode)workflowmodeProp.floatValue;
  234. workflow = (WorkflowMode)EditorGUILayout.EnumPopup("Workflow Mode", workflow);
  235. if (EditorGUI.EndChangeCheck()) {
  236. materialEditor.RegisterPropertyChangeUndo("Workflow Mode");
  237. workflowmodeProp.floatValue = (float)workflow;
  238. if((float)workflow == 0.0f) {
  239. material.EnableKeyword("_SPECULAR_SETUP");
  240. }
  241. else {
  242. material.DisableKeyword("_SPECULAR_SETUP");
  243. }
  244. }
  245. // Surface
  246. EditorGUI.BeginChangeCheck();
  247. //var surface = (SurfaceType)surfaceTypeProp.floatValue;
  248. surface = (SurfaceType)EditorGUILayout.EnumPopup("Surface Type", surface);
  249. if (EditorGUI.EndChangeCheck()) {
  250. materialEditor.RegisterPropertyChangeUndo("Surface Type");
  251. surfaceModeChanged = true;
  252. surfaceTypeProp.floatValue = (float)surface;
  253. if (surface == SurfaceType.Opaque) {
  254. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  255. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  256. material.SetInt("_ZWrite", 1);
  257. material.SetOverrideTag("RenderType", "Opaque");
  258. material.renderQueue = (int)RenderQueue.Geometry;
  259. material.SetShaderPassEnabled("ShadowCaster", true);
  260. }
  261. else {
  262. material.SetOverrideTag("RenderType", "Transparent");
  263. material.SetInt("_ZWrite", 0);
  264. material.renderQueue = (int)RenderQueue.Transparent;
  265. material.SetShaderPassEnabled("ShadowCaster", false);
  266. }
  267. }
  268. // Culling
  269. EditorGUI.BeginChangeCheck();
  270. var culling = (RenderFace)cullingProp.floatValue;
  271. culling = (RenderFace)EditorGUILayout.EnumPopup("Render Face", culling);
  272. if (EditorGUI.EndChangeCheck())
  273. {
  274. materialEditor.RegisterPropertyChangeUndo("Cull");
  275. cullingProp.floatValue = (float)culling;
  276. material.doubleSidedGI = (RenderFace)cullingProp.floatValue != RenderFace.Front;
  277. }
  278. // Alpha Clipping
  279. // Allow alpha clipping for transparents as well
  280. // if (surface == SurfaceType.Opaque) {
  281. EditorGUI.BeginChangeCheck();
  282. alphaclip = EditorGUILayout.Toggle(new GUIContent("Alpha Clipping"), alphaClipProp.floatValue == 1);
  283. // Make sure we set alpha clip if surface type has changed only as well
  284. if (EditorGUI.EndChangeCheck() || surfaceModeChanged) {
  285. alphaclipChanged = true;
  286. if (alphaclip) {
  287. alphaClipProp.floatValue = 1;
  288. material.EnableKeyword("_ALPHATEST_ON");
  289. if (surface == SurfaceType.Opaque) {
  290. material.renderQueue = (int)RenderQueue.AlphaTest;
  291. material.SetOverrideTag("RenderType", "TransparentCutout");
  292. }
  293. // We may have to re eanble camera fading
  294. if(cameraFadingEnabledProp.floatValue == 1) {
  295. material.EnableKeyword("_FADING_ON");
  296. if(cameraFadeShadowsProp.floatValue == 1) {
  297. material.EnableKeyword("_FADING_SHADOWS_ON");
  298. }
  299. else {
  300. material.DisableKeyword("_FADING_SHADOWS_ON");
  301. }
  302. }
  303. else {
  304. material.DisableKeyword("_FADING_ON");
  305. material.DisableKeyword("_FADING_SHADOWS_ON");
  306. }
  307. }
  308. else {
  309. alphaClipProp.floatValue = 0;
  310. material.DisableKeyword("_ALPHATEST_ON");
  311. if (surface == SurfaceType.Opaque) {
  312. material.renderQueue = (int)RenderQueue.Geometry;
  313. material.SetOverrideTag("RenderType", "Opaque");
  314. material.DisableKeyword("_FADING_ON");
  315. material.DisableKeyword("_FADING_SHADOWS_ON");
  316. }
  317. }
  318. }
  319. if (alphaclip) {
  320. materialEditor.ShaderProperty(alphaCutoffProp, "Threshold", 1);
  321. }
  322. // }
  323. // Camera Fading
  324. if (alphaclip) {
  325. EditorGUI.BeginChangeCheck();
  326. materialEditor.ShaderProperty(cameraFadingEnabledProp, "Camera Fading", 1);
  327. materialEditor.ShaderProperty(cameraFadeDistProp, "Fade Distance", 2);
  328. materialEditor.ShaderProperty(cameraFadeShadowsProp, "Fade Shadows", 2);
  329. materialEditor.ShaderProperty(cameraShadowFadeDistProp, "Shadow Fade Dist", 2);
  330. if (EditorGUI.EndChangeCheck()) {
  331. if(cameraFadingEnabledProp.floatValue == 1) {
  332. material.EnableKeyword("_FADING_ON");
  333. if(cameraFadeShadowsProp.floatValue == 1) {
  334. material.EnableKeyword("_FADING_SHADOWS_ON");
  335. }
  336. else {
  337. material.DisableKeyword("_FADING_SHADOWS_ON");
  338. }
  339. }
  340. else {
  341. material.DisableKeyword("_FADING_ON");
  342. material.DisableKeyword("_FADING_SHADOWS_ON");
  343. }
  344. }
  345. }
  346. else {
  347. material.DisableKeyword("_FADING_ON");
  348. material.DisableKeyword("_FADING_SHADOWS_ON");
  349. }
  350. // Shadows
  351. EditorGUI.BeginChangeCheck();
  352. var receiveShadows = EditorGUILayout.Toggle(new GUIContent("Receive Shadows"), receiveShadowsProp.floatValue == 1.0f);
  353. if (EditorGUI.EndChangeCheck()) {
  354. receiveShadowsProp.floatValue = receiveShadows ? 1.0f : 0.0f;
  355. if(receiveShadows) {
  356. material.DisableKeyword("_RECEIVE_SHADOWS_OFF");
  357. }
  358. else {
  359. material.EnableKeyword("_RECEIVE_SHADOWS_OFF");
  360. }
  361. }
  362. // Transparency
  363. if (surface == SurfaceType.Transparent) {
  364. EditorGUI.BeginChangeCheck();
  365. //DoPopup(Styles.blendingMode, blendModeProp, Enum.GetNames(typeof(BlendMode)));
  366. var blendMode = (BlendMode)blendModeProp.floatValue;
  367. blendMode = (BlendMode)EditorGUILayout.EnumPopup("Blend Mode", blendMode);
  368. // Make sure we set blend mode if surface type has changed only as well
  369. if (EditorGUI.EndChangeCheck() || surfaceModeChanged) {
  370. blendModeProp.floatValue = (float)blendMode;
  371. material.DisableKeyword("_ALPHATEST_ON");
  372. switch (blendMode) {
  373. case BlendMode.Alpha:
  374. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
  375. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  376. material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  377. break;
  378. case BlendMode.Premultiply:
  379. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  380. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  381. material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
  382. break;
  383. case BlendMode.Additive:
  384. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  385. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
  386. material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  387. break;
  388. case BlendMode.Multiply:
  389. material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
  390. material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  391. material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  392. material.EnableKeyword("_ALPHAMODULATE_ON");
  393. break;
  394. }
  395. }
  396. }
  397. // ZTesting
  398. EditorGUI.BeginChangeCheck();
  399. var ztest = (UnityEngine.Rendering.CompareFunction)ztestProp.floatValue;
  400. ztest = (UnityEngine.Rendering.CompareFunction)EditorGUILayout.EnumPopup("ZTest", ztest);
  401. if (EditorGUI.EndChangeCheck())
  402. {
  403. materialEditor.RegisterPropertyChangeUndo("ZTest");
  404. ztestProp.floatValue = (float)ztest;
  405. }
  406. // Spacing
  407. EditorGUILayout.Space();
  408. }
  409. EditorGUILayout.EndFoldoutHeaderGroup();
  410. // -----------------------
  411. // Surface Inputs
  412. openSurfaceInputs = (surfaceInputsProps.floatValue == 1.0f) ? true : false;
  413. EditorGUI.BeginChangeCheck();
  414. openSurfaceInputs = EditorGUILayout.BeginFoldoutHeaderGroup(openSurfaceInputs, "Surface Inputs");
  415. if (EditorGUI.EndChangeCheck()) {
  416. surfaceInputsProps.floatValue = openSurfaceInputs? 1.0f : 0.0f;
  417. }
  418. if(openSurfaceInputs){
  419. EditorGUILayout.Space();
  420. // Basemap / Color
  421. materialEditor.TexturePropertySingleLine(new GUIContent("Base Map"), baseMapProp, baseColorProp);
  422. // Metallic
  423. string[] smoothnessChannelNames;
  424. bool hasGlossMap = false;
  425. if ((WorkflowMode)workflowmodeProp.floatValue == WorkflowMode.Metallic) {
  426. hasGlossMap = metallicGlossMapProp.textureValue != null;
  427. smoothnessChannelNames = Styles.metallicSmoothnessChannelNames;
  428. EditorGUI.BeginChangeCheck();
  429. materialEditor.TexturePropertySingleLine(new GUIContent("Metallic Map"), metallicGlossMapProp, hasGlossMap ? null : metallicProp);
  430. if (EditorGUI.EndChangeCheck()) {
  431. if(metallicGlossMapProp.textureValue != null) {
  432. material.EnableKeyword("_METALLICSPECGLOSSMAP");
  433. }
  434. else {
  435. material.DisableKeyword("_METALLICSPECGLOSSMAP");
  436. }
  437. }
  438. }
  439. // Specular
  440. else {
  441. hasGlossMap = specGlossMapProp.textureValue != null;
  442. smoothnessChannelNames = Styles.specularSmoothnessChannelNames;
  443. EditorGUI.BeginChangeCheck();
  444. materialEditor.TexturePropertySingleLine(new GUIContent("Specular Map"), specGlossMapProp, hasGlossMap ? null : specColorProp);
  445. if (EditorGUI.EndChangeCheck()) {
  446. if(specGlossMapProp.textureValue != null) {
  447. material.EnableKeyword("_METALLICSPECGLOSSMAP");
  448. }
  449. else {
  450. material.DisableKeyword("_METALLICSPECGLOSSMAP");
  451. }
  452. }
  453. }
  454. // Smoothness
  455. EditorGUI.indentLevel++;
  456. EditorGUI.indentLevel++;
  457. EditorGUI.BeginChangeCheck();
  458. EditorGUI.showMixedValue = smoothnessProp.hasMixedValue;
  459. var smoothness = EditorGUILayout.Slider("Smoothness", smoothnessProp.floatValue, 0f, 1f);
  460. if (EditorGUI.EndChangeCheck())
  461. smoothnessProp.floatValue = smoothness;
  462. EditorGUI.showMixedValue = false;
  463. EditorGUI.indentLevel--;
  464. // Chose Smoothness Cannel in case we have any GlossMap
  465. //if (hasGlossMap) {
  466. EditorGUI.indentLevel++;
  467. EditorGUI.BeginDisabledGroup(surface != SurfaceType.Opaque);
  468. EditorGUI.BeginChangeCheck();
  469. EditorGUI.showMixedValue = smoothnessMapChannelProp.hasMixedValue;
  470. var smoothnessSource = (int) smoothnessMapChannelProp.floatValue;
  471. // This is correct, but it does not allow fading
  472. if (surface == SurfaceType.Opaque && !alphaclip) {
  473. smoothnessSource = EditorGUILayout.Popup(new GUIContent("Source"), smoothnessSource, smoothnessChannelNames);
  474. }
  475. else {
  476. GUI.enabled = false;
  477. EditorGUILayout.Popup(new GUIContent("Source"), 0, smoothnessChannelNames);
  478. material.DisableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  479. GUI.enabled = true;
  480. }
  481. // Make sure we set the proper keyword even if only alphaclip has changed as well
  482. if (EditorGUI.EndChangeCheck() || alphaclipChanged ) {
  483. smoothnessMapChannelProp.floatValue = smoothnessSource;
  484. if (smoothnessSource == 1) {
  485. material.EnableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  486. }
  487. else {
  488. material.DisableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  489. }
  490. }
  491. EditorGUI.showMixedValue = false;
  492. EditorGUI.EndDisabledGroup();
  493. EditorGUI.indentLevel--;
  494. //}
  495. // We may still sample from Albedo alpha
  496. /* else {
  497. // We can not sample smoothness from albedo alpha of the shader is transparent
  498. if (surface == SurfaceType.Opaque && !alphaclip) {
  499. EditorGUI.indentLevel++;
  500. EditorGUI.BeginChangeCheck();
  501. var smoothnessFromAlbedoAlpha = EditorGUILayout.Toggle(new GUIContent("Source Albedo Alpha"), smoothnessMapChannelProp.floatValue == 1);
  502. if (EditorGUI.EndChangeCheck()) {
  503. if (smoothnessFromAlbedoAlpha) {
  504. smoothnessMapChannelProp.floatValue = 1;
  505. material.EnableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  506. }
  507. else {
  508. smoothnessMapChannelProp.floatValue = 0;
  509. material.DisableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  510. }
  511. }
  512. EditorGUI.indentLevel--;
  513. }
  514. else {
  515. smoothnessMapChannelProp.floatValue = 0;
  516. material.DisableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
  517. }
  518. }
  519. */
  520. EditorGUI.indentLevel--;
  521. // Normal
  522. // NOTE: _NORMALMAP is needed by Bent normal as well: see sh lighting.
  523. EditorGUI.BeginChangeCheck();
  524. materialEditor.TexturePropertySingleLine(new GUIContent("Normal Map"), bumpMapProp, bumpMapScaleProp);
  525. if (EditorGUI.EndChangeCheck() || bumpMapProp.textureValue == null ) {
  526. if(bumpMapProp.textureValue != null && bumpMapScaleProp.floatValue != 0.0f) {
  527. material.EnableKeyword("_NORMALMAP");
  528. material.EnableKeyword("_SAMPLENORMAL");
  529. enableNormalProp.floatValue = 1.0f;
  530. }
  531. else {
  532. if (BentNormalMapProp.textureValue == null) {
  533. material.DisableKeyword("_NORMALMAP");
  534. }
  535. material.DisableKeyword("_SAMPLENORMAL");
  536. enableNormalProp.floatValue = 0.0f;
  537. }
  538. }
  539. // Occlusion
  540. EditorGUI.BeginChangeCheck();
  541. materialEditor.TexturePropertySingleLine(new GUIContent("Occlusion Map"), occlusionMapProp, occlusionMapProp.textureValue != null ? occlusionStrengthProp : null);
  542. if (EditorGUI.EndChangeCheck()) {
  543. if (occlusionMapProp.textureValue != null && occlusionStrengthProp.floatValue > 0 ) {
  544. material.EnableKeyword("_OCCLUSIONMAP");
  545. enableOcclusionProp.floatValue = 1;
  546. }
  547. else {
  548. material.DisableKeyword("_OCCLUSIONMAP");
  549. enableOcclusionProp.floatValue = 0;
  550. }
  551. }
  552. // Emission
  553. EditorGUI.BeginChangeCheck();
  554. var emission = EditorGUILayout.Toggle(new GUIContent("Emission"), (emissionProp.floatValue == 1)? true : false );
  555. if (EditorGUI.EndChangeCheck()) {
  556. if (emission) {
  557. material.EnableKeyword("_EMISSION");
  558. emissionProp.floatValue = 1;
  559. }
  560. else {
  561. material.DisableKeyword("_EMISSION");
  562. emissionProp.floatValue = 0;
  563. }
  564. }
  565. if (emission) {
  566. EditorGUI.BeginChangeCheck();
  567. materialEditor.TexturePropertyWithHDRColor(new GUIContent("Emission Map"), emissionMapProp, emissionColorProp, false);
  568. if (EditorGUI.EndChangeCheck()) {
  569. var brightness = emissionColorProp.colorValue.maxColorComponent;
  570. material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
  571. if (brightness <= 0f) {
  572. material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
  573. }
  574. }
  575. }
  576. // Tiling
  577. EditorGUILayout.Space();
  578. materialEditor.TextureScaleOffsetProperty(baseMapProp);
  579. // Spacing
  580. EditorGUILayout.Space();
  581. }
  582. EditorGUILayout.EndFoldoutHeaderGroup();
  583. // -----------------------
  584. // Detail Surface Inputs
  585. openDetailSurfaceInputs = (surfaceDetailInputsProps.floatValue == 1.0f) ? true : false;
  586. EditorGUI.BeginChangeCheck();
  587. openDetailSurfaceInputs = EditorGUILayout.BeginFoldoutHeaderGroup(openDetailSurfaceInputs, "Detail Surface Inputs");
  588. if (EditorGUI.EndChangeCheck()) {
  589. surfaceDetailInputsProps.floatValue = openDetailSurfaceInputs? 1.0f : 0.0f;
  590. }
  591. if (openDetailSurfaceInputs) {
  592. EditorGUILayout.Space();
  593. EditorGUI.BeginChangeCheck();
  594. materialEditor.TexturePropertySingleLine(new GUIContent("Detail Mask (A)"), DetailMask);
  595. materialEditor.TexturePropertySingleLine(new GUIContent("Detail Albedo"), DetailAlbedoMap, DetailAlbedoMap.textureValue != null ? DetailAlbedoMapScale : null );
  596. materialEditor.TexturePropertySingleLine(new GUIContent("Detail Normal"), DetailNormalMap, DetailNormalMap.textureValue != null ? DetailNormalMapScale : null );
  597. materialEditor.TextureScaleOffsetProperty(DetailAlbedoMap);
  598. if (EditorGUI.EndChangeCheck()) {
  599. bool hasDetailMap = material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap");
  600. CoreUtils.SetKeyword(material, "_DETAIL", hasDetailMap);
  601. }
  602. }
  603. EditorGUILayout.EndFoldoutHeaderGroup();
  604. // -----------------------
  605. // Advanced Surface Inputs
  606. GUIContent labeltooltip;
  607. openAdvancedSurfaceInputs = (advancedSurfaceInputsProps.floatValue == 1.0f) ? true : false;
  608. EditorGUI.BeginChangeCheck();
  609. openAdvancedSurfaceInputs = EditorGUILayout.BeginFoldoutHeaderGroup(openAdvancedSurfaceInputs, "Advanced Surface Inputs");
  610. if (EditorGUI.EndChangeCheck()) {
  611. advancedSurfaceInputsProps.floatValue = openAdvancedSurfaceInputs? 1.0f : 0.0f;
  612. }
  613. if (openAdvancedSurfaceInputs) {
  614. EditorGUILayout.Space();
  615. // Parallax
  616. EditorGUI.BeginChangeCheck();
  617. labeltooltip = new GUIContent("Height Map (G)", "RGB texture which stores height in the green color channel used by parallax extrusion.");
  618. materialEditor.TexturePropertySingleLine(new GUIContent("Height Map (G)"), heightMapProp, heightMapProp.textureValue != null ? parallaxProp : null);
  619. if (EditorGUI.EndChangeCheck()) {
  620. if ( (heightMapProp.textureValue != null) && (parallaxProp.floatValue > 0) ) {
  621. material.EnableKeyword("_PARALLAX");
  622. enableParallaxProp.floatValue = 1;
  623. }
  624. else {
  625. material.DisableKeyword("_PARALLAX");
  626. enableParallaxProp.floatValue = 0;
  627. }
  628. }
  629. if ( alphaclip && (heightMapProp.textureValue != null) && (parallaxProp.floatValue > 0) ) {
  630. EditorGUI.BeginChangeCheck();
  631. labeltooltip = new GUIContent("Parallax Shadows", "If checked the shader will apply parallax mapping even in the shadow caster pass. This is somehow correct for directional shadows where we can derive the view direction from the (shadow) camera’s forward vector but not in case we render spot lights. Furthermore even parallax directional shadow casters are quite unstable if you rotate the camera. So check if you really need this...");
  632. var pShadows = EditorGUILayout.Toggle(labeltooltip, enableParallaxShadowsProp.floatValue == 1);
  633. if (EditorGUI.EndChangeCheck() || surfaceModeChanged) {
  634. if (pShadows) {
  635. enableParallaxShadowsProp.floatValue = 1;
  636. material.EnableKeyword("_PARALLAXSHADOWS");
  637. }
  638. else {
  639. enableParallaxShadowsProp.floatValue = 0;
  640. material.DisableKeyword("_PARALLAXSHADOWS");
  641. }
  642. }
  643. EditorGUILayout.Space();
  644. }
  645. else {
  646. enableParallaxShadowsProp.floatValue = 0;
  647. material.DisableKeyword("_PARALLAXSHADOWS");
  648. }
  649. // Bent Normals
  650. EditorGUI.BeginChangeCheck();
  651. labeltooltip = new GUIContent("Bent Normal Map", "Cosine weighted Bent Normal Map in tangent space. If assigned the shader will tweak ambient diffuse lighting and ambient specular reflections.");
  652. materialEditor.TexturePropertySingleLine(labeltooltip, BentNormalMapProp);
  653. if (EditorGUI.EndChangeCheck()) {
  654. if (BentNormalMapProp.textureValue != null) {
  655. EnableBentNormalProp.floatValue = 1;
  656. material.EnableKeyword("_BENTNORMAL");
  657. material.EnableKeyword("_NORMALMAP");
  658. }
  659. else {
  660. EnableBentNormalProp.floatValue = 0;
  661. material.DisableKeyword("_BENTNORMAL");
  662. if(bumpMapProp.textureValue == null) {
  663. material.DisableKeyword("_NORMALMAP");
  664. }
  665. }
  666. }
  667. // Horizon Occlusion
  668. labeltooltip = new GUIContent("Horizon Occlusion", "Terminates light leaking caused by normal mapped ambient specular reflections where the reflection vector might end up pointing behind the surface being rendered.");
  669. materialEditor.ShaderProperty(HorizonOcclusionProp, labeltooltip, 0);
  670. // Specular AA
  671. EditorGUI.BeginChangeCheck();
  672. labeltooltip = new GUIContent("Geometric Specular AA", "When enabled the shader reduces specular aliasing on high density meshes by reducing smoothness at grazing angles.");
  673. var specAA = EditorGUILayout.Toggle(labeltooltip, GeometricSpecularAAProp.floatValue == 1);
  674. if (EditorGUI.EndChangeCheck()) {
  675. if (specAA) {
  676. GeometricSpecularAAProp.floatValue = 1;
  677. material.EnableKeyword("_ENABLE_GEOMETRIC_SPECULAR_AA");
  678. }
  679. else {
  680. GeometricSpecularAAProp.floatValue = 0;
  681. material.DisableKeyword("_ENABLE_GEOMETRIC_SPECULAR_AA");
  682. }
  683. }
  684. if (specAA) {
  685. labeltooltip = new GUIContent("Screen Space Variance", "Controls the amount of Specular AA. Higher values give a more blurry result.");
  686. materialEditor.ShaderProperty(ScreenSpaceVarianceProp, labeltooltip, 1);
  687. labeltooltip = new GUIContent("Threshold", "Controls the amount of Specular AA. Higher values allow higher reduction.");
  688. materialEditor.ShaderProperty(SAAThresholdProp, labeltooltip, 1);
  689. }
  690. // GI TO AO
  691. EditorGUI.BeginChangeCheck();
  692. labeltooltip = new GUIContent("GI to Specular Occlusion", "In case you use lightmaps you may activate this feature to derive some kind of specular occlusion just from the lightmap and its baked ambient occlusion.");
  693. var GIAO = EditorGUILayout.Toggle(labeltooltip, AOfromGIProp.floatValue == 1);
  694. if (EditorGUI.EndChangeCheck()) {
  695. if (GIAO) {
  696. AOfromGIProp.floatValue = 1;
  697. material.EnableKeyword("_ENABLE_AO_FROM_GI");
  698. }
  699. else {
  700. AOfromGIProp.floatValue = 0;
  701. material.DisableKeyword("_ENABLE_AO_FROM_GI");
  702. }
  703. }
  704. if (GIAO) {
  705. labeltooltip = new GUIContent("GI to AO Factor", "Controls the amount of specular occlusion. It acts as a factor to brighten the value sampled from the lightmap.");
  706. materialEditor.ShaderProperty(GItoAOProp, labeltooltip, 1);
  707. labeltooltip = new GUIContent("Bias", "Adds a constant value to brighten the value sampled from the lightmap.");
  708. materialEditor.ShaderProperty(GItoAOBiasProp, labeltooltip, 1);
  709. }
  710. // Spacing
  711. EditorGUILayout.Space();
  712. }
  713. EditorGUILayout.EndFoldoutHeaderGroup();
  714. // -----------------------
  715. // Rim Lighting
  716. openRimLighingInputs = (RimLighingInputsProps.floatValue == 1.0f) ? true : false;
  717. EditorGUI.BeginChangeCheck();
  718. openRimLighingInputs = EditorGUILayout.BeginFoldoutHeaderGroup(openRimLighingInputs, "Rim Lighting");
  719. if (EditorGUI.EndChangeCheck()) {
  720. RimLighingInputsProps.floatValue = openRimLighingInputs? 1.0f : 0.0f;
  721. }
  722. if(openRimLighingInputs){
  723. // Rim
  724. EditorGUI.BeginChangeCheck();
  725. materialEditor.ShaderProperty(RimProp, "Enable Rim Lighting", 0);
  726. materialEditor.ShaderProperty(RimColorProp, "Rim Color", 0);
  727. materialEditor.ShaderProperty(RimPowerProp, "Rim Power", 0);
  728. materialEditor.ShaderProperty(RimFrequencyProp, "Rim Frequency", 0);
  729. materialEditor.ShaderProperty(RimMinPowerProp, "Rim Min Power", 1);
  730. materialEditor.ShaderProperty(RimPerPositionFrequencyProp, "Rim Per Position Frequency", 1);
  731. if (EditorGUI.EndChangeCheck()) {
  732. if(RimProp.floatValue == 1) {
  733. material.EnableKeyword("_RIMLIGHTING");
  734. }
  735. else {
  736. material.DisableKeyword("_RIMLIGHTING");
  737. }
  738. }
  739. EditorGUILayout.Space();
  740. }
  741. EditorGUILayout.EndFoldoutHeaderGroup();
  742. // -----------------------
  743. // Stencil Inputs
  744. openStencilOptions = (stencilOptionsProps.floatValue == 1.0f) ? true : false;
  745. EditorGUI.BeginChangeCheck();
  746. openStencilOptions = EditorGUILayout.BeginFoldoutHeaderGroup(openStencilOptions, "Stencil Options");
  747. if (EditorGUI.EndChangeCheck()) {
  748. stencilOptionsProps.floatValue = openStencilOptions? 1.0f : 0.0f;
  749. }
  750. if(openStencilOptions){
  751. // Stencil
  752. materialEditor.ShaderProperty(stencilProp, "Stencil Reference", 0);
  753. materialEditor.ShaderProperty(readMaskProp, "Read Mask", 0);
  754. materialEditor.ShaderProperty(writeMaskProp, "Write Mask", 0);
  755. materialEditor.ShaderProperty(stencilCompProp, "Stencil Comparison", 0);
  756. materialEditor.ShaderProperty(stencilOpProp, "Stencil Operation", 0);
  757. materialEditor.ShaderProperty(stencilFailProp, "Stencil Fail Op", 0);
  758. materialEditor.ShaderProperty(stenciZfailProp, "Stencil ZFail Op", 0);
  759. EditorGUILayout.Space();
  760. }
  761. EditorGUILayout.EndFoldoutHeaderGroup();
  762. // -----------------------
  763. // Advanced Settings
  764. openAdvancedOptions = (advancedOptionsProps.floatValue == 1.0f) ? true : false;
  765. EditorGUI.BeginChangeCheck();
  766. openAdvancedOptions = EditorGUILayout.BeginFoldoutHeaderGroup(openAdvancedOptions, "Advanced");
  767. if (EditorGUI.EndChangeCheck()) {
  768. advancedOptionsProps.floatValue = openAdvancedOptions? 1.0f : 0.0f;
  769. }
  770. if (openAdvancedOptions) {
  771. EditorGUI.BeginChangeCheck();
  772. materialEditor.ShaderProperty(SpecularHighlightsProps, "Specular Highlights", 0);
  773. materialEditor.ShaderProperty(EnvironmentReflectionsProps, "Environment Reflections", 0);
  774. materialEditor.EnableInstancingField();
  775. materialEditor.RenderQueueField();
  776. if (EditorGUI.EndChangeCheck()) {
  777. if(SpecularHighlightsProps.floatValue == 1) {
  778. material.DisableKeyword("_SPECULARHIGHLIGHTS_OFF");
  779. }
  780. else {
  781. material.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
  782. }
  783. if(EnvironmentReflectionsProps.floatValue == 1) {
  784. material.DisableKeyword("_ENVIRONMENTREFLECTIONS_OFF");
  785. }
  786. else {
  787. material.EnableKeyword("_ENVIRONMENTREFLECTIONS_OFF");
  788. }
  789. }
  790. EditorGUILayout.Space();
  791. }
  792. EditorGUILayout.EndFoldoutHeaderGroup();
  793. // Fix all the missing stuff
  794. // Needed to make the Selection Outline work
  795. // Lightmapper needs it for alpha testing?!
  796. if (material.HasProperty("_MainTex") && material.HasProperty("_BaseMap") ) {
  797. if (material.GetTexture("_BaseMap") != null) {
  798. material.SetTexture("_MainTex", material.GetTexture("_BaseMap"));
  799. }
  800. }
  801. }
  802. }
  803. }