Ingen beskrivning
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VFXAbstractParticleURPLitOutput.cs 38KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. #if HAS_VFX_GRAPH
  2. using System;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.Rendering;
  7. using UnityEngine.Rendering.Universal;
  8. using UnityEngine.Serialization;
  9. namespace UnityEditor.VFX.URP
  10. {
  11. abstract class VFXAbstractParticleURPLitOutput : VFXShaderGraphParticleOutput
  12. {
  13. public enum MaterialType
  14. {
  15. Standard,
  16. SixWaySmokeLit,
  17. }
  18. public enum WorkflowMode
  19. {
  20. Metallic,
  21. Specular,
  22. }
  23. [Flags]
  24. public enum ColorMode
  25. {
  26. None = 0,
  27. BaseColor = 1 << 0,
  28. Emissive = 1 << 1,
  29. BaseColorAndEmissive = BaseColor | Emissive,
  30. }
  31. [Flags]
  32. public enum BaseColorMapMode
  33. {
  34. None = 0,
  35. Color = 1 << 0,
  36. Alpha = 1 << 1,
  37. ColorAndAlpha = Color | Alpha
  38. }
  39. public enum SmoothnessSource
  40. {
  41. None,
  42. MetallicAlpha,
  43. SpecularAlpha,
  44. AlbedoAlpha,
  45. }
  46. //TODO: Move these types to a utility in VFX package
  47. protected enum EmissiveMode
  48. {
  49. None,
  50. SingleChannel,
  51. Map,
  52. }
  53. protected enum LightmapRemapMode
  54. {
  55. None,
  56. ParametricContrast,
  57. CustomCurve,
  58. }
  59. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Header("Lighting"), Tooltip("Specifies the surface type of this output. Surface types determine how the particle will react to light.")]
  60. protected MaterialType materialType = MaterialType.Standard;
  61. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, FormerlySerializedAs("materialType"), Tooltip("Select a workflow that fits your textures. Choose between Metallic or Specular.")]
  62. protected WorkflowMode workflowMode = WorkflowMode.Metallic;
  63. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("Specified the smoothness map source. It can be the alpha channel of the Metallic Map or the Base Color Map if they are used in the output.")]
  64. protected SmoothnessSource smoothnessSource = SmoothnessSource.None;
  65. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("Specifies what parts of the base color map is applied to the particles. Particles can receive color, alpha, color and alpha, or not receive any values from the base color map.")]
  66. protected BaseColorMapMode useBaseColorMap = BaseColorMapMode.ColorAndAlpha;
  67. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the output will accept an occlusion to control how the particle receives lighting.")]
  68. protected bool useOcclusionMap = false;
  69. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the output will accept a metallic map to multiply the metallic value.")]
  70. protected bool useMetallicMap = false;
  71. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the output will accept a metallic map to multiply the metallic value.")]
  72. protected bool useSpecularMap = false;
  73. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the output will accept a Normal Map to simulate additional surface details when illuminated.")]
  74. protected bool useNormalMap = false;
  75. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the output will accept an Emissive Map to control how particles glow.")]
  76. protected bool useEmissiveMap = false;
  77. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("Specifies how the color attribute is applied to the particles. It can be disregarded, used for the base color, used for the emissiveness, or used for both the base color and the emissiveness.")]
  78. protected ColorMode colorMode = ColorMode.BaseColor;
  79. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Header("\nSix-way Smoke Lit Settings"), Tooltip("Specifies how to remap the values in the lightmaps.")]
  80. protected LightmapRemapMode lightmapRemapMode = LightmapRemapMode.None;
  81. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("Enables the modification of the light map ranges.")]
  82. protected bool lightmapRemapRanges = false;
  83. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the alpha of the particles can be remapped with the Alpha Remap curve.")]
  84. protected bool useAlphaRemap = false;
  85. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, an emissive color field becomes available in the output to make particles glow.")]
  86. protected bool useEmissive = false;
  87. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField,
  88. Tooltip("Specifies what information is used to control the emissive color of the particle. It can come from the Alpha channel of the Negative Axes Lightmap or from an Emissive map.")]
  89. protected EmissiveMode emissiveMode = EmissiveMode.None;
  90. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, you can scale the values in the emissive channel before applying the Emissive Gradient.")]
  91. protected bool useEmissiveChannelScale = false;
  92. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the lightmaps are used to simulate color absorption whose strength can be tuned with the Absorption Strength parameter.")]
  93. protected bool useColorAbsorption = true;
  94. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the normals of the particle are inverted when seen from behind, allowing quads with culling set to off to receive correct lighting information.")]
  95. protected bool doubleSided = false;
  96. [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField, Tooltip("When enabled, the particle will receive shadows.")]
  97. protected bool receiveShadows = true;
  98. protected bool useEmissiveColor
  99. {
  100. get
  101. {
  102. if (materialType == MaterialType.SixWaySmokeLit) //In the SingleChannel mode, we use the gradient to control the color of the emissive
  103. return emissiveMode == EmissiveMode.Map;
  104. return useEmissive;
  105. }
  106. }
  107. protected VFXAbstractParticleURPLitOutput(bool strip = false) : base(strip) {}
  108. protected virtual bool allowTextures => GetOrRefreshShaderGraphObject() == null;
  109. protected virtual bool useSmoothness => true;
  110. protected virtual bool useMetallic => workflowMode == WorkflowMode.Metallic;
  111. protected virtual bool useSpecular => workflowMode == WorkflowMode.Specular;
  112. protected virtual bool useNormalScale => true;
  113. public class URPLitInputProperties
  114. {
  115. [Range(0, 1), Tooltip("Controls the scale factor for the particle’s smoothness.")]
  116. public float smoothness = 0.5f;
  117. }
  118. public class StandardProperties
  119. {
  120. [Range(0, 1), Tooltip("Controls the scale factor for the particle’s metallicity.")]
  121. public float metallic = 0.0f;
  122. }
  123. public class SpecularColorProperties
  124. {
  125. [Tooltip("Sets the specular color of the particle.")]
  126. public Color specularColor = Color.gray;
  127. }
  128. public override sealed bool CanBeCompiled()
  129. {
  130. return (VFXLibrary.currentSRPBinder is VFXURPBinder) && base.CanBeCompiled();
  131. }
  132. private IEnumerable<SmoothnessSource> validSmoothnessSources
  133. {
  134. get
  135. {
  136. yield return SmoothnessSource.None;
  137. if (useBaseColorMap != BaseColorMapMode.None)
  138. yield return SmoothnessSource.AlbedoAlpha;
  139. if (workflowMode == WorkflowMode.Metallic && useMetallicMap)
  140. yield return SmoothnessSource.MetallicAlpha;
  141. if (workflowMode == WorkflowMode.Specular && useSpecularMap)
  142. yield return SmoothnessSource.SpecularAlpha;
  143. }
  144. }
  145. public override IEnumerable<int> GetFilteredOutEnumerators(string name)
  146. {
  147. if (name == nameof(smoothnessSource))
  148. {
  149. var all = Enum.GetValues(typeof(SmoothnessSource)).Cast<int>();
  150. var valid = validSmoothnessSources.Cast<int>();
  151. return all.Except(valid);
  152. }
  153. return base.GetFilteredOutEnumerators(name);
  154. }
  155. protected internal override void Invalidate(VFXModel model, InvalidationCause cause)
  156. {
  157. base.Invalidate(model, cause);
  158. if (cause == InvalidationCause.kSettingChanged
  159. && !validSmoothnessSources.Contains(smoothnessSource))
  160. {
  161. var fallbackSmoothness = SmoothnessSource.None;
  162. if (smoothnessSource == SmoothnessSource.MetallicAlpha && validSmoothnessSources.Contains(SmoothnessSource.SpecularAlpha))
  163. fallbackSmoothness = SmoothnessSource.SpecularAlpha;
  164. if (smoothnessSource == SmoothnessSource.SpecularAlpha && validSmoothnessSources.Contains(SmoothnessSource.MetallicAlpha))
  165. fallbackSmoothness = SmoothnessSource.MetallicAlpha;
  166. SetSettingValue(nameof(smoothnessSource), fallbackSmoothness);
  167. }
  168. }
  169. private static readonly string kBaseColorMap = "baseColorMap";
  170. protected IEnumerable<VFXPropertyWithValue> baseColorMapProperties
  171. {
  172. get
  173. {
  174. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kBaseColorMap, new TooltipAttribute("Specifies the base color (RGB) and opacity (A) of the particle.")), (usesFlipbook ? null : VFXResources.defaultResources.particleTexture));
  175. }
  176. }
  177. private static readonly string kOcclusionMap = "occlusionMap";
  178. protected IEnumerable<VFXPropertyWithValue> occlusionMapsProperties
  179. {
  180. get
  181. {
  182. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kOcclusionMap, new TooltipAttribute("Specifies the Occlusion Map for the particle - Ambient occlusion (G)")));
  183. }
  184. }
  185. private static readonly string kSpecularMap = "specularMap";
  186. protected IEnumerable<VFXPropertyWithValue> specularMapsProperties
  187. {
  188. get
  189. {
  190. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kSpecularMap, new TooltipAttribute("Specifies the Specular Map for the particle - Color (RGB) - (Optional A) Smoothness")));
  191. }
  192. }
  193. private static readonly string kMetallicMap = "metallicMap";
  194. protected IEnumerable<VFXPropertyWithValue> metallicMapsProperties
  195. {
  196. get
  197. {
  198. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kMetallicMap, new TooltipAttribute("Specifies the Metallic Map for the particle - Metallic (R) - (Optional A) Smoothness")));
  199. }
  200. }
  201. private static readonly string kNormalMap = "normalMap";
  202. private static readonly string kNormalScale = "normalScale";
  203. protected IEnumerable<VFXPropertyWithValue> normalMapsProperties
  204. {
  205. get
  206. {
  207. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kNormalMap, new TooltipAttribute("Specifies the Normal map to obtain normals in tangent space for the particle.")));
  208. if(useNormalScale)
  209. yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), kNormalScale, new TooltipAttribute("Sets the scale of the normals. Larger values increase the impact of the normals.")), 1.0f);
  210. }
  211. }
  212. private static readonly string kEmissiveMap = "emissiveMap";
  213. private static readonly string kEmissiveScale = "emissiveScale";
  214. protected IEnumerable<VFXPropertyWithValue> emissiveMapsProperties
  215. {
  216. get
  217. {
  218. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), kEmissiveMap, new TooltipAttribute("Specifies the Emissive map (RGB) used to make particles glow.")));
  219. yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), kEmissiveScale, new TooltipAttribute("Sets the scale of the emission obtained from the emissive map.")), 1.0f);
  220. }
  221. }
  222. public class BaseColorProperties
  223. {
  224. [Tooltip("Sets the base color of the particle.")]
  225. public Color baseColor = Color.white;
  226. }
  227. public class EmissiveColorProperties
  228. {
  229. [Tooltip("Sets the emissive color to make particles glow.")]
  230. public Color emissiveColor = Color.black;
  231. }
  232. public class SixWayParametricContrastProperties
  233. {
  234. [Range(-5, 5), Tooltip("Sets the contrast strength applied the lightmaps.")]
  235. public float contrastIntensity = 0.0f;
  236. [Range(0, 1), Tooltip("Specifies on which value of the lightmap the contrast transition happens. If Contrast Intensity is zero, this parameter has not effect.")]
  237. public float contrastPivot = 0.5f;
  238. }
  239. public class SixWayRemapRangeProperties
  240. {
  241. [Tooltip("Sets the source range of the lightmaps used for remapping.")]
  242. public Vector2 remapFrom = new Vector2(0, 1);
  243. [Tooltip("Sets the output range of the lightmaps.")]
  244. public Vector2 remapTo = new Vector2(0, 1);
  245. }
  246. protected override bool needsExposureWeight { get { return GetOrRefreshShaderGraphObject() == null && ((colorMode & ColorMode.Emissive) != 0 || useEmissive || useEmissiveMap); } }
  247. protected override bool bypassExposure { get { return false; } }
  248. protected override VFXOldShaderGraphHelpers.RPInfo currentRP => VFXOldShaderGraphHelpers.urpLitInfo;
  249. public override bool isLitShader => true;
  250. protected IEnumerable<VFXPropertyWithValue> sixWayMapsProperties
  251. {
  252. get
  253. {
  254. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), "positiveAxesLightmap", new TooltipAttribute("Specifies the lightmap for the positive axes, Right (R), Up (G), Back (B), and the opacity (A).")));
  255. yield return new VFXPropertyWithValue(new VFXProperty(GetTextureType(), "negativeAxesLightmap", new TooltipAttribute("Specifies the lightmap for the Negative axes: Left (R), Bottom (G), Front (B), and the Emissive mask (A) for Single Channel emission mode.")));
  256. if (lightmapRemapRanges)
  257. {
  258. foreach (var prop in PropertiesFromType("SixWayRemapRangeProperties"))
  259. yield return prop;
  260. }
  261. if (lightmapRemapMode == LightmapRemapMode.ParametricContrast)
  262. {
  263. foreach (var prop in PropertiesFromType("SixWayParametricContrastProperties"))
  264. yield return prop;
  265. }
  266. if (lightmapRemapMode == LightmapRemapMode.CustomCurve)
  267. yield return new VFXPropertyWithValue(new VFXProperty(typeof(AnimationCurve), "lightRemapCurve"),
  268. AnimationCurve.Linear(0, 0, 1, 1));
  269. if (!isBlendModeOpaque && useAlphaRemap)
  270. yield return new VFXPropertyWithValue(
  271. new VFXProperty(typeof(AnimationCurve), "alphaRemap",
  272. new TooltipAttribute("Remaps the alpha value.")), AnimationCurve.Linear(0, 0, 1, 1));
  273. if (emissiveMode == EmissiveMode.SingleChannel)
  274. {
  275. if(useEmissiveChannelScale)
  276. yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), "emissiveChannelScale", new TooltipAttribute("Multiplies the value contained in the Emission channel, before applying the gradient."), new RangeAttribute(0.0f, 1.0f)), 1.0f);
  277. yield return new VFXPropertyWithValue(
  278. new VFXProperty(typeof(Gradient), "emissiveGradient",
  279. new TooltipAttribute("Remaps the values of the Emission channel.")),
  280. VFXResources.defaultResources.gradientMapRamp);
  281. yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), "emissiveMultiplier", new TooltipAttribute("Multiplies the values set in the Emissive Gradient."), new MinAttribute(0.0f)), 1.0f);
  282. }
  283. if(useColorAbsorption)
  284. yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), "absorptionStrength", new TooltipAttribute("Sets the strength of the color absorption."), new RangeAttribute(0.0f, 1.0f)), 0.5f);
  285. }
  286. }
  287. protected override IEnumerable<VFXPropertyWithValue> inputProperties
  288. {
  289. get
  290. {
  291. var properties = base.inputProperties;
  292. if (GetOrRefreshShaderGraphObject() == null)
  293. {
  294. if (materialType == MaterialType.Standard)
  295. {
  296. if(useSmoothness)
  297. properties = properties.Concat(PropertiesFromType(nameof(URPLitInputProperties)));
  298. if(useMetallic)
  299. properties = properties.Concat(PropertiesFromType(nameof(StandardProperties)));
  300. if(useSpecular)
  301. properties = properties.Concat(PropertiesFromType(nameof(SpecularColorProperties)));
  302. }
  303. else if(materialType == MaterialType.SixWaySmokeLit)
  304. properties = properties.Concat(sixWayMapsProperties);
  305. if (allowTextures)
  306. {
  307. if (useBaseColorMap != BaseColorMapMode.None)
  308. properties = properties.Concat(baseColorMapProperties);
  309. }
  310. if ((colorMode & ColorMode.BaseColor) == 0) // particle color is not used as base color so add a slot
  311. properties = properties.Concat(PropertiesFromType(nameof(BaseColorProperties)));
  312. if (allowTextures)
  313. {
  314. if (useOcclusionMap)
  315. properties = properties.Concat(occlusionMapsProperties);
  316. if (useMetallicMap && workflowMode == WorkflowMode.Metallic)
  317. properties = properties.Concat(metallicMapsProperties);
  318. if (useSpecularMap && workflowMode == WorkflowMode.Specular)
  319. properties = properties.Concat(specularMapsProperties);
  320. if (useNormalMap)
  321. properties = properties.Concat(normalMapsProperties);
  322. if (useEmissiveMap)
  323. properties = properties.Concat(emissiveMapsProperties);
  324. }
  325. if (((colorMode & ColorMode.Emissive) == 0) && useEmissiveColor)
  326. properties = properties.Concat(PropertiesFromType(nameof(EmissiveColorProperties)));
  327. }
  328. return properties;
  329. }
  330. }
  331. protected override IEnumerable<VFXNamedExpression> CollectGPUExpressions(IEnumerable<VFXNamedExpression> slotExpressions)
  332. {
  333. foreach (var exp in base.CollectGPUExpressions(slotExpressions))
  334. yield return exp;
  335. if (GetOrRefreshShaderGraphObject() == null)
  336. {
  337. if (materialType == MaterialType.SixWaySmokeLit)
  338. {
  339. yield return slotExpressions.First(o => o.name == "positiveAxesLightmap");
  340. yield return slotExpressions.First(o => o.name == "negativeAxesLightmap");
  341. if (emissiveMode == EmissiveMode.SingleChannel)
  342. {
  343. yield return slotExpressions.First(o => o.name == "emissiveGradient");
  344. yield return slotExpressions.First(o => o.name == "emissiveMultiplier");
  345. if(useEmissiveChannelScale)
  346. yield return slotExpressions.First(o => o.name == "emissiveChannelScale");
  347. }
  348. if (!isBlendModeOpaque && useAlphaRemap)
  349. yield return slotExpressions.First(o => o.name == "alphaRemap");
  350. if (lightmapRemapRanges)
  351. {
  352. yield return slotExpressions.First(o => o.name == "remapFrom");
  353. yield return slotExpressions.First(o => o.name == "remapTo");
  354. }
  355. if (lightmapRemapMode == LightmapRemapMode.ParametricContrast)
  356. {
  357. var lightmapBrightnessExp = slotExpressions.First(o => o.name == "contrastPivot").exp;
  358. var rawLightMapContrastExp = slotExpressions.First(o => o.name == "contrastIntensity").exp;
  359. var lightmapContrastExp = VFXOperatorUtility.Exp(rawLightMapContrastExp, VFXOperatorUtility.Base.Base2);
  360. var lightmapControlsExp = new VFXExpressionCombine(lightmapBrightnessExp, lightmapContrastExp);
  361. yield return new VFXNamedExpression(lightmapControlsExp, "lightmapRemapControls");
  362. }
  363. if(lightmapRemapMode == LightmapRemapMode.CustomCurve)
  364. yield return slotExpressions.First(o => o.name == "lightRemapCurve");
  365. if (useColorAbsorption)
  366. {
  367. var absorptionStrenghtExp = slotExpressions.First(o => o.name == "absorptionStrength").exp;
  368. var absorptionRangeExp = (VFXValue.Constant(1 - 1.0f / Mathf.PI) * absorptionStrenghtExp + VFXValue.Constant(1.0f / Mathf.PI));
  369. yield return new VFXNamedExpression(absorptionRangeExp, "absorptionRange");
  370. }
  371. if (allowTextures)
  372. {
  373. if (useBaseColorMap != BaseColorMapMode.None)
  374. yield return slotExpressions.First(o => o.name == kBaseColorMap);
  375. if (useEmissiveMap)
  376. {
  377. yield return slotExpressions.First(o => o.name == kEmissiveMap);
  378. yield return slotExpressions.First(o => o.name == kEmissiveScale);
  379. }
  380. }
  381. }
  382. else
  383. {
  384. if(useSmoothness)
  385. yield return slotExpressions.First(o => o.name == nameof(URPLitInputProperties.smoothness));
  386. switch (workflowMode)
  387. {
  388. case WorkflowMode.Metallic:
  389. if(useMetallic)
  390. yield return slotExpressions.First(o => o.name == nameof(StandardProperties.metallic));
  391. break;
  392. case WorkflowMode.Specular:
  393. if(useSpecular)
  394. yield return slotExpressions.First(o => o.name == nameof(SpecularColorProperties.specularColor));
  395. break;
  396. default:
  397. break;
  398. }
  399. if (allowTextures)
  400. {
  401. if (useBaseColorMap != BaseColorMapMode.None)
  402. yield return slotExpressions.First(o => o.name == kBaseColorMap);
  403. if (useOcclusionMap)
  404. yield return slotExpressions.First(o => o.name == kOcclusionMap);
  405. if (useMetallicMap && workflowMode == WorkflowMode.Metallic)
  406. yield return slotExpressions.First(o => o.name == kMetallicMap);
  407. if (useSpecularMap && workflowMode == WorkflowMode.Specular)
  408. yield return slotExpressions.First(o => o.name == kSpecularMap);
  409. if (useNormalMap)
  410. {
  411. yield return slotExpressions.First(o => o.name == kNormalMap);
  412. if(useNormalScale)
  413. yield return slotExpressions.First(o => o.name == kNormalScale);
  414. }
  415. if (useEmissiveMap)
  416. {
  417. yield return slotExpressions.First(o => o.name == kEmissiveMap);
  418. yield return slotExpressions.First(o => o.name == kEmissiveScale);
  419. }
  420. }
  421. }
  422. if ((colorMode & ColorMode.BaseColor) == 0)
  423. yield return slotExpressions.First(o => o.name == nameof(BaseColorProperties.baseColor));
  424. if (((colorMode & ColorMode.Emissive) == 0) && useEmissiveColor)
  425. yield return slotExpressions.First(o =>
  426. o.name == nameof(EmissiveColorProperties.emissiveColor));
  427. }
  428. }
  429. public override IEnumerable<string> additionalDefines
  430. {
  431. get
  432. {
  433. foreach (var d in base.additionalDefines)
  434. yield return d;
  435. yield return "URP_LIT";
  436. if (GetOrRefreshShaderGraphObject() == null)
  437. {
  438. if (!receiveShadows)
  439. yield return "_RECEIVE_SHADOWS_OFF";
  440. if (materialType == MaterialType.SixWaySmokeLit)
  441. {
  442. yield return "VFX_MATERIAL_TYPE_SIX_WAY_SMOKE";
  443. if (emissiveMode == EmissiveMode.SingleChannel)
  444. {
  445. yield return "VFX_SIX_WAY_USE_ONE_EMISSIVE_CHANNEL";
  446. if (useEmissiveChannelScale)
  447. yield return "VFX_SIX_WAY_EMISSIVE_CHANNEL_SCALE";
  448. }
  449. if (!isBlendModeOpaque && useAlphaRemap)
  450. yield return "VFX_SIX_WAY_USE_ALPHA_REMAP";
  451. if(lightmapRemapMode != LightmapRemapMode.None || lightmapRemapRanges)
  452. yield return "VFX_SIX_WAY_REMAP";
  453. if (lightmapRemapRanges)
  454. yield return "VFX_SIX_WAY_REMAP_RANGES";
  455. if (useColorAbsorption)
  456. {
  457. yield return "VFX_SIX_WAY_COLOR_ABSORPTION";
  458. }
  459. switch (lightmapRemapMode)
  460. {
  461. case LightmapRemapMode.ParametricContrast:
  462. yield return "VFX_SIX_WAY_REMAP_NONLIN";
  463. break;
  464. case LightmapRemapMode.CustomCurve:
  465. yield return "VFX_SIX_WAY_REMAP_CURVE";
  466. break;
  467. }
  468. }
  469. else
  470. {
  471. switch (workflowMode)
  472. {
  473. case WorkflowMode.Metallic:
  474. yield return "URP_WORKFLOW_MODE_METALLIC";
  475. break;
  476. case WorkflowMode.Specular:
  477. yield return "URP_WORKFLOW_MODE_SPECULAR";
  478. break;
  479. }
  480. }
  481. }
  482. if (allowTextures)
  483. {
  484. if (useBaseColorMap != BaseColorMapMode.None)
  485. yield return "URP_USE_BASE_COLOR_MAP";
  486. if ((useBaseColorMap & BaseColorMapMode.Color) != 0)
  487. yield return "URP_USE_BASE_COLOR_MAP_COLOR";
  488. if ((useBaseColorMap & BaseColorMapMode.Alpha) != 0)
  489. yield return "URP_USE_BASE_COLOR_MAP_ALPHA";
  490. if (useOcclusionMap)
  491. yield return "URP_USE_OCCLUSION_MAP";
  492. if (useMetallicMap && workflowMode == WorkflowMode.Metallic)
  493. yield return "URP_USE_METALLIC_MAP";
  494. if (useSpecularMap && workflowMode == WorkflowMode.Specular)
  495. yield return "URP_USE_SPECULAR_MAP";
  496. if (useNormalMap)
  497. yield return "USE_NORMAL_MAP";
  498. if (useEmissiveMap)
  499. yield return "URP_USE_EMISSIVE_MAP";
  500. }
  501. if (GetOrRefreshShaderGraphObject() == null)
  502. {
  503. if ((colorMode & ColorMode.BaseColor) != 0)
  504. yield return "URP_USE_BASE_COLOR";
  505. else
  506. yield return "URP_USE_ADDITIONAL_BASE_COLOR";
  507. if ((colorMode & ColorMode.Emissive) != 0)
  508. yield return "URP_USE_EMISSIVE_COLOR";
  509. else if (useEmissiveColor)
  510. yield return "URP_USE_ADDITIONAL_EMISSIVE_COLOR";
  511. switch (smoothnessSource)
  512. {
  513. case SmoothnessSource.None: yield return "URP_USE_SMOOTHNESS_IN_NONE"; break;
  514. case SmoothnessSource.MetallicAlpha: yield return "URP_USE_SMOOTHNESS_IN_METALLIC"; break;
  515. case SmoothnessSource.SpecularAlpha: yield return "URP_USE_SMOOTHNESS_IN_SPECULAR"; break;
  516. case SmoothnessSource.AlbedoAlpha: yield return "URP_USE_SMOOTHNESS_IN_ALBEDO"; break;
  517. }
  518. }
  519. if (doubleSided)
  520. yield return "USE_DOUBLE_SIDED";
  521. }
  522. }
  523. protected override IEnumerable<string> filteredOutSettings
  524. {
  525. get
  526. {
  527. foreach (var setting in base.filteredOutSettings)
  528. yield return setting;
  529. yield return nameof(colorMapping);
  530. if (!allowTextures)
  531. {
  532. yield return nameof(useBaseColorMap);
  533. yield return nameof(useOcclusionMap);
  534. yield return nameof(useMetallicMap);
  535. yield return nameof(useSpecularMap);
  536. yield return nameof(useNormalMap);
  537. yield return nameof(useEmissiveMap);
  538. }
  539. if (workflowMode != WorkflowMode.Metallic)
  540. yield return nameof(useMetallicMap);
  541. if (workflowMode != WorkflowMode.Specular)
  542. yield return nameof(useSpecularMap);
  543. if (materialType == MaterialType.SixWaySmokeLit)
  544. {
  545. yield return nameof(doubleSided);
  546. yield return nameof(useMetallicMap);
  547. yield return nameof(useOcclusionMap);
  548. yield return nameof(useSpecularMap);
  549. yield return nameof(useNormalMap);
  550. yield return nameof(useEmissiveMap);
  551. yield return nameof(useEmissive);
  552. yield return nameof(smoothnessSource);
  553. yield return nameof(workflowMode);
  554. if (emissiveMode != EmissiveMode.SingleChannel)
  555. yield return nameof(useEmissiveChannelScale);
  556. yield return "normalBending";
  557. }
  558. else
  559. {
  560. yield return nameof(useColorAbsorption);
  561. yield return nameof(emissiveMode);
  562. yield return nameof(useEmissiveChannelScale);
  563. yield return nameof(lightmapRemapMode);
  564. yield return nameof(useAlphaRemap);
  565. yield return nameof(lightmapRemapRanges);
  566. }
  567. if (GetOrRefreshShaderGraphObject() != null)
  568. {
  569. yield return nameof(workflowMode);
  570. yield return nameof(useEmissive);
  571. yield return nameof(colorMode);
  572. yield return nameof(smoothnessSource);
  573. yield return nameof(useColorAbsorption);
  574. yield return nameof(emissiveMode);
  575. yield return nameof(useEmissiveChannelScale);
  576. yield return nameof(lightmapRemapMode);
  577. yield return nameof(useAlphaRemap);
  578. yield return nameof(lightmapRemapRanges);
  579. yield return nameof(receiveShadows);
  580. }
  581. else if ((colorMode & ColorMode.Emissive) != 0)
  582. yield return nameof(useEmissive);
  583. yield return nameof(excludeFromTUAndAA);
  584. }
  585. }
  586. public override IEnumerable<VFXAttributeInfo> attributes
  587. {
  588. get
  589. {
  590. yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
  591. if (colorMode != ColorMode.None)
  592. yield return new VFXAttributeInfo(VFXAttribute.Color, VFXAttributeMode.Read);
  593. yield return new VFXAttributeInfo(VFXAttribute.Alpha, VFXAttributeMode.Read);
  594. yield return new VFXAttributeInfo(VFXAttribute.Alive, VFXAttributeMode.Read);
  595. yield return new VFXAttributeInfo(VFXAttribute.AxisX, VFXAttributeMode.Read);
  596. yield return new VFXAttributeInfo(VFXAttribute.AxisY, VFXAttributeMode.Read);
  597. yield return new VFXAttributeInfo(VFXAttribute.AxisZ, VFXAttributeMode.Read);
  598. yield return new VFXAttributeInfo(VFXAttribute.AngleX, VFXAttributeMode.Read);
  599. yield return new VFXAttributeInfo(VFXAttribute.AngleY, VFXAttributeMode.Read);
  600. yield return new VFXAttributeInfo(VFXAttribute.AngleZ, VFXAttributeMode.Read);
  601. yield return new VFXAttributeInfo(VFXAttribute.PivotX, VFXAttributeMode.Read);
  602. yield return new VFXAttributeInfo(VFXAttribute.PivotY, VFXAttributeMode.Read);
  603. yield return new VFXAttributeInfo(VFXAttribute.PivotZ, VFXAttributeMode.Read);
  604. yield return new VFXAttributeInfo(VFXAttribute.Size, VFXAttributeMode.Read);
  605. yield return new VFXAttributeInfo(VFXAttribute.ScaleX, VFXAttributeMode.Read);
  606. yield return new VFXAttributeInfo(VFXAttribute.ScaleY, VFXAttributeMode.Read);
  607. yield return new VFXAttributeInfo(VFXAttribute.ScaleZ, VFXAttributeMode.Read);
  608. foreach (var attribute in flipbookAttributes)
  609. yield return attribute;
  610. }
  611. }
  612. public override void OnEnable()
  613. {
  614. colorMapping = ColorMappingMode.Default;
  615. base.OnEnable();
  616. }
  617. public override void OnSettingModified(VFXSetting setting)
  618. {
  619. base.OnSettingModified(setting);
  620. if (setting.name == nameof(materialType) && (MaterialType)setting.value == MaterialType.SixWaySmokeLit)
  621. {
  622. useOcclusionMap = false;
  623. useMetallicMap = false;
  624. useSpecularMap = false;
  625. useNormalMap = false;
  626. useBaseColorMap = BaseColorMapMode.None;
  627. shaderGraph = null;
  628. doubleSided = true;
  629. }
  630. if (setting.name == nameof(emissiveMode))
  631. {
  632. switch ((EmissiveMode)setting.value)
  633. {
  634. case EmissiveMode.None:
  635. useEmissive = false;
  636. useEmissiveMap = false;
  637. break;
  638. case EmissiveMode.SingleChannel:
  639. useEmissive = true;
  640. useEmissiveMap = false;
  641. break;
  642. case EmissiveMode.Map:
  643. useEmissive = true;
  644. useEmissiveMap = true;
  645. break;
  646. }
  647. }
  648. }
  649. public override IEnumerable<KeyValuePair<string, VFXShaderWriter>> additionalReplacements
  650. {
  651. get
  652. {
  653. foreach (var kvp in base.additionalReplacements)
  654. yield return kvp;
  655. // URP Forward specific defines
  656. var forwardDefines = new VFXShaderWriter();
  657. if (workflowMode == WorkflowMode.Specular)
  658. forwardDefines.Write("#define _SPECULAR_SETUP");
  659. yield return new KeyValuePair<string, VFXShaderWriter>("${VFXURPForwardDefines}", forwardDefines);
  660. // URP GBuffer specific defines
  661. var gbufferDefines = new VFXShaderWriter();
  662. if (workflowMode == WorkflowMode.Specular)
  663. gbufferDefines.Write("#define _SPECULAR_SETUP");
  664. yield return new KeyValuePair<string, VFXShaderWriter>("${VFXURPGBufferDefines}", gbufferDefines);
  665. var forwardPassName = new VFXShaderWriter();
  666. forwardPassName.Write(materialType == MaterialType.SixWaySmokeLit ? "UniversalForwardOnly" : "UniversalForward");
  667. yield return new KeyValuePair<string, VFXShaderWriter>("${VFXURPForwardPassName}", forwardPassName);
  668. }
  669. }
  670. }
  671. }
  672. #endif