RendererLighting.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. using System.Collections.Generic;
  2. using UnityEngine.Rendering;
  3. using UnityEngine.Rendering.Universal;
  4. namespace UnityEngine.Experimental.Rendering.Universal
  5. {
  6. internal static class RendererLighting
  7. {
  8. static readonly ShaderTagId k_NormalsRenderingPassName = new ShaderTagId("NormalsRendering");
  9. static readonly Color k_NormalClearColor = new Color(0.5f, 0.5f, 1.0f, 1.0f);
  10. static readonly string k_SpriteLightKeyword = "SPRITE_LIGHT";
  11. static readonly string k_UsePointLightCookiesKeyword = "USE_POINT_LIGHT_COOKIES";
  12. static readonly string k_LightQualityFastKeyword = "LIGHT_QUALITY_FAST";
  13. static readonly string k_UseNormalMap = "USE_NORMAL_MAP";
  14. static readonly string k_UseAdditiveBlendingKeyword = "USE_ADDITIVE_BLENDING";
  15. const int k_NumberOfLightMaterials = 1 << 5 + 3; // 5 keywords + volume bit, shape bit
  16. static readonly string[] k_UseBlendStyleKeywords =
  17. {
  18. "USE_SHAPE_LIGHT_TYPE_0", "USE_SHAPE_LIGHT_TYPE_1", "USE_SHAPE_LIGHT_TYPE_2", "USE_SHAPE_LIGHT_TYPE_3"
  19. };
  20. static readonly string[] k_BlendFactorsPropNames =
  21. {
  22. "_ShapeLightBlendFactors0", "_ShapeLightBlendFactors1", "_ShapeLightBlendFactors2", "_ShapeLightBlendFactors3"
  23. };
  24. static readonly string[] k_MaskFilterPropNames =
  25. {
  26. "_ShapeLightMaskFilter0", "_ShapeLightMaskFilter1", "_ShapeLightMaskFilter2", "_ShapeLightMaskFilter3"
  27. };
  28. static readonly string[] k_InvertedFilterPropNames =
  29. {
  30. "_ShapeLightInvertedFilter0", "_ShapeLightInvertedFilter1", "_ShapeLightInvertedFilter2", "_ShapeLightInvertedFilter3"
  31. };
  32. static Renderer2DData s_Renderer2DData;
  33. static RenderingData s_RenderingData;
  34. static Light2DBlendStyle[] s_BlendStyles;
  35. static RenderTargetHandle[] s_LightRenderTargets;
  36. static bool[] s_LightRenderTargetsDirty;
  37. static RenderTargetHandle s_ShadowsRenderTarget;
  38. static RenderTargetHandle s_NormalsTarget;
  39. static Texture s_LightLookupTexture;
  40. static Texture s_FalloffLookupTexture;
  41. static Material[] s_LightMaterials;
  42. static Material[] s_ShadowMaterials;
  43. static Material[] s_RemoveSelfShadowMaterials;
  44. static RenderTextureFormat s_RenderTextureFormatToUse = RenderTextureFormat.ARGB32;
  45. static bool s_HasSetupRenderTextureFormatToUse;
  46. static public void Setup(RenderingData renderingData, Renderer2DData renderer2DData)
  47. {
  48. s_Renderer2DData = renderer2DData;
  49. s_BlendStyles = renderer2DData.lightBlendStyles;
  50. s_RenderingData = renderingData;
  51. if (s_LightRenderTargets == null)
  52. {
  53. s_LightRenderTargets = new RenderTargetHandle[s_BlendStyles.Length];
  54. s_LightRenderTargets[0].Init("_ShapeLightTexture0");
  55. s_LightRenderTargets[1].Init("_ShapeLightTexture1");
  56. s_LightRenderTargets[2].Init("_ShapeLightTexture2");
  57. s_LightRenderTargets[3].Init("_ShapeLightTexture3");
  58. s_LightRenderTargetsDirty = new bool[s_BlendStyles.Length];
  59. }
  60. if (s_NormalsTarget.id == 0)
  61. s_NormalsTarget.Init("_NormalMap");
  62. if (s_ShadowsRenderTarget.id == 0)
  63. s_ShadowsRenderTarget.Init("_ShadowTex");
  64. // The array size should be determined by the number of 'feature bit' the material index has. See GetLightMaterialIndex().
  65. // Not all slots must be filled because certain combinations of the feature bits don't make sense (e.g. sprite bit on + shape bit off).
  66. if (s_LightMaterials == null)
  67. s_LightMaterials = new Material[k_NumberOfLightMaterials];
  68. // This really needs to be deleted and replaced with a material block
  69. const int totalMaterials = 256;
  70. if (s_ShadowMaterials == null)
  71. s_ShadowMaterials = new Material[totalMaterials];
  72. if (s_RemoveSelfShadowMaterials == null)
  73. s_RemoveSelfShadowMaterials = new Material[totalMaterials];
  74. }
  75. static public void CreateNormalMapRenderTexture(CommandBuffer cmd)
  76. {
  77. if (!s_HasSetupRenderTextureFormatToUse)
  78. {
  79. if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB111110Float))
  80. s_RenderTextureFormatToUse = RenderTextureFormat.RGB111110Float;
  81. else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
  82. s_RenderTextureFormatToUse = RenderTextureFormat.ARGBHalf;
  83. s_HasSetupRenderTextureFormatToUse = true;
  84. }
  85. RenderTextureDescriptor descriptor = new RenderTextureDescriptor(s_RenderingData.cameraData.cameraTargetDescriptor.width, s_RenderingData.cameraData.cameraTargetDescriptor.height);
  86. descriptor.colorFormat = s_RenderTextureFormatToUse;
  87. descriptor.sRGB = false;
  88. descriptor.useMipMap = false;
  89. descriptor.autoGenerateMips = false;
  90. descriptor.depthBufferBits = 0;
  91. descriptor.msaaSamples = 1;
  92. descriptor.dimension = TextureDimension.Tex2D;
  93. cmd.GetTemporaryRT(s_NormalsTarget.id, descriptor, FilterMode.Bilinear);
  94. }
  95. static public void CreateBlendStyleRenderTexture(CommandBuffer cmd, int blendStyleIndex)
  96. {
  97. if (!s_HasSetupRenderTextureFormatToUse)
  98. {
  99. if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB111110Float))
  100. s_RenderTextureFormatToUse = RenderTextureFormat.RGB111110Float;
  101. else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
  102. s_RenderTextureFormatToUse = RenderTextureFormat.ARGBHalf;
  103. s_HasSetupRenderTextureFormatToUse = true;
  104. }
  105. float renderTextureScale = Mathf.Clamp(s_BlendStyles[blendStyleIndex].renderTextureScale, 0.01f, 1.0f);
  106. int width = (int)(s_RenderingData.cameraData.cameraTargetDescriptor.width * renderTextureScale);
  107. int height = (int)(s_RenderingData.cameraData.cameraTargetDescriptor.height * renderTextureScale);
  108. RenderTextureDescriptor descriptor = new RenderTextureDescriptor(width, height);
  109. descriptor.colorFormat = s_RenderTextureFormatToUse;
  110. descriptor.sRGB = false;
  111. descriptor.useMipMap = false;
  112. descriptor.autoGenerateMips = false;
  113. descriptor.depthBufferBits = 0;
  114. descriptor.msaaSamples = 1;
  115. descriptor.dimension = TextureDimension.Tex2D;
  116. cmd.GetTemporaryRT(s_LightRenderTargets[blendStyleIndex].id, descriptor, FilterMode.Bilinear);
  117. cmd.EnableShaderKeyword(k_UseBlendStyleKeywords[blendStyleIndex]);
  118. s_LightRenderTargetsDirty[blendStyleIndex] = true;
  119. }
  120. static public void CreateShadowRenderTexture(CommandBuffer cmd, int blendStyleIndex)
  121. {
  122. float renderTextureScale = Mathf.Clamp(s_BlendStyles[blendStyleIndex].renderTextureScale, 0.01f, 1.0f);
  123. int width = (int)(s_RenderingData.cameraData.cameraTargetDescriptor.width * renderTextureScale);
  124. int height = (int)(s_RenderingData.cameraData.cameraTargetDescriptor.height * renderTextureScale);
  125. RenderTextureDescriptor descriptor = new RenderTextureDescriptor(width, height);
  126. descriptor.colorFormat = RenderTextureFormat.ARGB32;
  127. descriptor.sRGB = false;
  128. descriptor.useMipMap = false;
  129. descriptor.autoGenerateMips = false;
  130. descriptor.depthBufferBits = 24;
  131. descriptor.graphicsFormat = GraphicsFormat.R8G8B8A8_UNorm;
  132. descriptor.msaaSamples = 1;
  133. descriptor.dimension = TextureDimension.Tex2D;
  134. cmd.GetTemporaryRT(s_ShadowsRenderTarget.id, descriptor, FilterMode.Bilinear);
  135. }
  136. static public void ReleaseShadowRenderTexture(CommandBuffer cmd)
  137. {
  138. cmd.ReleaseTemporaryRT(s_ShadowsRenderTarget.id);
  139. }
  140. static public void ReleaseRenderTextures(CommandBuffer cmd)
  141. {
  142. for (int i = 0; i < s_BlendStyles.Length; ++i)
  143. {
  144. cmd.ReleaseTemporaryRT(s_LightRenderTargets[i].id);
  145. }
  146. cmd.ReleaseTemporaryRT(s_NormalsTarget.id);
  147. cmd.ReleaseTemporaryRT(s_ShadowsRenderTarget.id);
  148. }
  149. static private void RenderShadows(CommandBuffer cmdBuffer, int layerToRender, Light2D light, float shadowIntensity, RenderTargetIdentifier renderTexture)
  150. {
  151. cmdBuffer.SetGlobalFloat("_ShadowIntensity", 1 - light.shadowIntensity);
  152. cmdBuffer.SetGlobalFloat("_ShadowVolumeIntensity", 1 - light.shadowVolumeIntensity);
  153. if (shadowIntensity > 0)
  154. {
  155. CreateShadowRenderTexture(cmdBuffer, light.blendStyleIndex);
  156. cmdBuffer.SetRenderTarget(s_ShadowsRenderTarget.Identifier()); // This isn't efficient if this light doesn't cast shadow.
  157. cmdBuffer.ClearRenderTarget(true, true, Color.black);
  158. BoundingSphere lightBounds = light.GetBoundingSphere(); // Gets the local bounding sphere...
  159. cmdBuffer.SetGlobalVector("_LightPos", light.transform.position);
  160. cmdBuffer.SetGlobalFloat("_LightRadius", lightBounds.radius);
  161. Material shadowMaterial = GetShadowMaterial(1);
  162. Material removeSelfShadowMaterial = GetRemoveSelfShadowMaterial(1);
  163. List<ShadowCasterGroup2D> shadowCasterGroups = ShadowCasterGroup2DManager.shadowCasterGroups;
  164. if (shadowCasterGroups != null && shadowCasterGroups.Count > 0)
  165. {
  166. int previousShadowGroupIndex = -1;
  167. int incrementingGroupIndex = 0;
  168. for (int group = 0; group < shadowCasterGroups.Count; group++)
  169. {
  170. ShadowCasterGroup2D shadowCasterGroup = shadowCasterGroups[group];
  171. List<ShadowCaster2D> shadowCasters = shadowCasterGroup.GetShadowCasters();
  172. int shadowGroupIndex = shadowCasterGroup.GetShadowGroup();
  173. if (LightUtility.CheckForChange(shadowGroupIndex, ref previousShadowGroupIndex) || shadowGroupIndex == 0)
  174. {
  175. incrementingGroupIndex++;
  176. shadowMaterial = GetShadowMaterial(incrementingGroupIndex);
  177. removeSelfShadowMaterial = GetRemoveSelfShadowMaterial(incrementingGroupIndex);
  178. }
  179. if (shadowCasters != null)
  180. {
  181. // Draw the shadow casting group first, then draw the silhouttes..
  182. for (int i = 0; i < shadowCasters.Count; i++)
  183. {
  184. ShadowCaster2D shadowCaster = (ShadowCaster2D)shadowCasters[i];
  185. if (shadowCaster != null && shadowMaterial != null && shadowCaster.IsShadowedLayer(layerToRender))
  186. {
  187. if (shadowCaster.castsShadows)
  188. cmdBuffer.DrawMesh(shadowCaster.mesh, shadowCaster.transform.localToWorldMatrix, shadowMaterial);
  189. }
  190. }
  191. for (int i = 0; i < shadowCasters.Count; i++)
  192. {
  193. ShadowCaster2D shadowCaster = (ShadowCaster2D)shadowCasters[i];
  194. if (shadowCaster != null && shadowMaterial != null && shadowCaster.IsShadowedLayer(layerToRender))
  195. {
  196. if (shadowCaster.useRendererSilhouette)
  197. {
  198. Renderer renderer = shadowCaster.GetComponent<Renderer>();
  199. if (renderer != null)
  200. {
  201. if (!shadowCaster.selfShadows)
  202. cmdBuffer.DrawRenderer(renderer, removeSelfShadowMaterial);
  203. else
  204. cmdBuffer.DrawRenderer(renderer, shadowMaterial, 0, 1);
  205. }
  206. }
  207. else
  208. {
  209. if (!shadowCaster.selfShadows)
  210. {
  211. Matrix4x4 meshMat = shadowCaster.transform.localToWorldMatrix;
  212. cmdBuffer.DrawMesh(shadowCaster.mesh, meshMat, removeSelfShadowMaterial);
  213. }
  214. }
  215. }
  216. }
  217. }
  218. }
  219. }
  220. ReleaseShadowRenderTexture(cmdBuffer);
  221. cmdBuffer.SetRenderTarget(renderTexture);
  222. }
  223. }
  224. static private bool RenderLightSet(Camera camera, int blendStyleIndex, CommandBuffer cmdBuffer, int layerToRender, RenderTargetIdentifier renderTexture, List<Light2D> lights)
  225. {
  226. bool renderedAnyLight = false;
  227. foreach (var light in lights)
  228. {
  229. if (light != null && light.lightType != Light2D.LightType.Global && light.blendStyleIndex == blendStyleIndex && light.IsLitLayer(layerToRender) && light.IsLightVisible(camera))
  230. {
  231. // Render light
  232. Material lightMaterial = GetLightMaterial(light, false);
  233. if (lightMaterial != null)
  234. {
  235. Mesh lightMesh = light.GetMesh();
  236. if (lightMesh != null)
  237. {
  238. RenderShadows(cmdBuffer, layerToRender, light, light.shadowIntensity, renderTexture);
  239. renderedAnyLight = true;
  240. if (light.lightType == Light2D.LightType.Sprite && light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
  241. cmdBuffer.SetGlobalTexture("_CookieTex", light.lightCookieSprite.texture);
  242. cmdBuffer.SetGlobalFloat("_FalloffIntensity", light.falloffIntensity);
  243. cmdBuffer.SetGlobalFloat("_FalloffDistance", light.shapeLightFalloffSize);
  244. cmdBuffer.SetGlobalVector("_FalloffOffset", light.shapeLightFalloffOffset);
  245. cmdBuffer.SetGlobalColor("_LightColor", light.intensity * light.color);
  246. cmdBuffer.SetGlobalFloat("_VolumeOpacity", light.volumeOpacity);
  247. if(light.useNormalMap || light.lightType == Light2D.LightType.Point)
  248. RendererLighting.SetPointLightShaderGlobals(cmdBuffer, light);
  249. // Light code could be combined...
  250. if (light.lightType == Light2D.LightType.Parametric || light.lightType == Light2D.LightType.Freeform || light.lightType == Light2D.LightType.Sprite)
  251. {
  252. cmdBuffer.DrawMesh(lightMesh, light.transform.localToWorldMatrix, lightMaterial);
  253. }
  254. else if(light.lightType == Light2D.LightType.Point)
  255. {
  256. Vector3 scale = new Vector3(light.pointLightOuterRadius, light.pointLightOuterRadius, light.pointLightOuterRadius);
  257. Matrix4x4 matrix = Matrix4x4.TRS(light.transform.position, Quaternion.identity, scale);
  258. cmdBuffer.DrawMesh(lightMesh, matrix, lightMaterial);
  259. }
  260. }
  261. }
  262. }
  263. }
  264. return renderedAnyLight;
  265. }
  266. static private void RenderLightVolumeSet(Camera camera, int blendStyleIndex, CommandBuffer cmdBuffer, int layerToRender, RenderTargetIdentifier renderTexture, List<Light2D> lights)
  267. {
  268. if (lights.Count > 0)
  269. {
  270. for (int i = 0; i < lights.Count; i++)
  271. {
  272. Light2D light = lights[i];
  273. int topMostLayer = light.GetTopMostLitLayer();
  274. if (layerToRender == topMostLayer)
  275. {
  276. if (light != null && light.lightType != Light2D.LightType.Global && light.volumeOpacity > 0.0f && light.blendStyleIndex == blendStyleIndex && light.IsLitLayer(layerToRender) && light.IsLightVisible(camera))
  277. {
  278. Material lightVolumeMaterial = GetLightMaterial(light, true);
  279. if (lightVolumeMaterial != null)
  280. {
  281. Mesh lightMesh = light.GetMesh();
  282. if (lightMesh != null)
  283. {
  284. RenderShadows(cmdBuffer, layerToRender, light, light.shadowVolumeIntensity, renderTexture);
  285. if (light.lightType == Light2D.LightType.Sprite && light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
  286. cmdBuffer.SetGlobalTexture("_CookieTex", light.lightCookieSprite.texture);
  287. cmdBuffer.SetGlobalFloat("_FalloffIntensity", light.falloffIntensity);
  288. cmdBuffer.SetGlobalFloat("_FalloffDistance", light.shapeLightFalloffSize);
  289. cmdBuffer.SetGlobalVector("_FalloffOffset", light.shapeLightFalloffOffset);
  290. cmdBuffer.SetGlobalColor("_LightColor", light.intensity * light.color);
  291. cmdBuffer.SetGlobalFloat("_VolumeOpacity", light.volumeOpacity);
  292. // Is this needed
  293. if (light.useNormalMap || light.lightType == Light2D.LightType.Point)
  294. RendererLighting.SetPointLightShaderGlobals(cmdBuffer, light);
  295. // Could be combined...
  296. if (light.lightType == Light2D.LightType.Parametric || light.lightType == Light2D.LightType.Freeform || light.lightType == Light2D.LightType.Sprite)
  297. {
  298. cmdBuffer.DrawMesh(lightMesh, light.transform.localToWorldMatrix, lightVolumeMaterial);
  299. }
  300. else if (light.lightType == Light2D.LightType.Point)
  301. {
  302. Vector3 scale = new Vector3(light.pointLightOuterRadius, light.pointLightOuterRadius, light.pointLightOuterRadius);
  303. Matrix4x4 matrix = Matrix4x4.TRS(light.transform.position, Quaternion.identity, scale);
  304. cmdBuffer.DrawMesh(lightMesh, matrix, lightVolumeMaterial);
  305. }
  306. }
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. static public void SetShapeLightShaderGlobals(CommandBuffer cmdBuffer)
  314. {
  315. for (int i = 0; i < s_BlendStyles.Length; ++i)
  316. {
  317. if (i >= k_UseBlendStyleKeywords.Length)
  318. break;
  319. string keyword = k_UseBlendStyleKeywords[i];
  320. cmdBuffer.DisableShaderKeyword(keyword);
  321. cmdBuffer.SetGlobalVector(k_BlendFactorsPropNames[i], s_BlendStyles[i].blendFactors);
  322. cmdBuffer.SetGlobalVector(k_MaskFilterPropNames[i], s_BlendStyles[i].maskTextureChannelFilter.mask);
  323. cmdBuffer.SetGlobalVector(k_InvertedFilterPropNames[i], s_BlendStyles[i].maskTextureChannelFilter.inverted);
  324. }
  325. cmdBuffer.SetGlobalTexture("_FalloffLookup", GetFalloffLookupTexture());
  326. }
  327. static Texture GetLightLookupTexture()
  328. {
  329. if (s_LightLookupTexture == null)
  330. s_LightLookupTexture = Light2DLookupTexture.CreatePointLightLookupTexture();
  331. return s_LightLookupTexture;
  332. }
  333. static Texture GetFalloffLookupTexture()
  334. {
  335. if (s_FalloffLookupTexture == null)
  336. s_FalloffLookupTexture = Light2DLookupTexture.CreateFalloffLookupTexture();
  337. return s_FalloffLookupTexture;
  338. }
  339. static public float GetNormalizedInnerRadius(Light2D light)
  340. {
  341. return light.pointLightInnerRadius / light.pointLightOuterRadius;
  342. }
  343. static public float GetNormalizedAngle(float angle)
  344. {
  345. return (angle / 360.0f);
  346. }
  347. static public void GetScaledLightInvMatrix(Light2D light, out Matrix4x4 retMatrix, bool includeRotation)
  348. {
  349. float outerRadius = light.pointLightOuterRadius;
  350. Vector3 lightScale = Vector3.one;
  351. Vector3 outerRadiusScale = new Vector3(lightScale.x * outerRadius, lightScale.y * outerRadius, lightScale.z * outerRadius);
  352. Quaternion rotation;
  353. if (includeRotation)
  354. rotation = light.transform.rotation;
  355. else
  356. rotation = Quaternion.identity;
  357. Matrix4x4 scaledLightMat = Matrix4x4.TRS(light.transform.position, rotation, outerRadiusScale);
  358. retMatrix = Matrix4x4.Inverse(scaledLightMat);
  359. }
  360. static public void SetPointLightShaderGlobals(CommandBuffer cmdBuffer, Light2D light)
  361. {
  362. // This is used for the lookup texture
  363. Matrix4x4 lightInverseMatrix;
  364. Matrix4x4 lightNoRotInverseMatrix;
  365. GetScaledLightInvMatrix(light, out lightInverseMatrix, true);
  366. GetScaledLightInvMatrix(light, out lightNoRotInverseMatrix, false);
  367. float innerRadius = GetNormalizedInnerRadius(light);
  368. float innerAngle = GetNormalizedAngle(light.pointLightInnerAngle);
  369. float outerAngle = GetNormalizedAngle(light.pointLightOuterAngle);
  370. float innerRadiusMult = 1 / (1 - innerRadius);
  371. cmdBuffer.SetGlobalVector("_LightPosition", light.transform.position);
  372. cmdBuffer.SetGlobalMatrix("_LightInvMatrix", lightInverseMatrix);
  373. cmdBuffer.SetGlobalMatrix("_LightNoRotInvMatrix", lightNoRotInverseMatrix);
  374. cmdBuffer.SetGlobalFloat("_InnerRadiusMult", innerRadiusMult);
  375. cmdBuffer.SetGlobalFloat("_OuterAngle", outerAngle);
  376. cmdBuffer.SetGlobalFloat("_InnerAngleMult", 1 / (outerAngle - innerAngle));
  377. cmdBuffer.SetGlobalTexture("_LightLookup", GetLightLookupTexture());
  378. cmdBuffer.SetGlobalTexture("_FalloffLookup", GetFalloffLookupTexture());
  379. cmdBuffer.SetGlobalFloat("_FalloffIntensity", light.falloffIntensity);
  380. cmdBuffer.SetGlobalFloat("_IsFullSpotlight", innerAngle == 1 ? 1.0f : 0.0f);
  381. cmdBuffer.SetGlobalFloat("_LightZDistance", light.pointLightDistance);
  382. if (light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
  383. cmdBuffer.SetGlobalTexture("_PointLightCookieTex", light.lightCookieSprite.texture);
  384. }
  385. static public void ClearDirtyLighting(CommandBuffer cmdBuffer, uint blendStylesUsed)
  386. {
  387. for (int i = 0; i < s_BlendStyles.Length; ++i)
  388. {
  389. if ((blendStylesUsed & (uint)(1 << i)) == 0)
  390. continue;
  391. if (s_LightRenderTargetsDirty[i])
  392. {
  393. cmdBuffer.SetRenderTarget(s_LightRenderTargets[i].Identifier());
  394. cmdBuffer.ClearRenderTarget(false, true, Color.black);
  395. s_LightRenderTargetsDirty[i] = false;
  396. }
  397. }
  398. }
  399. static public void RenderNormals(ScriptableRenderContext renderContext, CullingResults cullResults, DrawingSettings drawSettings, FilteringSettings filterSettings)
  400. {
  401. var cmd = CommandBufferPool.Get("Clear Normals");
  402. cmd.SetRenderTarget(s_NormalsTarget.Identifier());
  403. cmd.ClearRenderTarget(true, true, k_NormalClearColor);
  404. renderContext.ExecuteCommandBuffer(cmd);
  405. CommandBufferPool.Release(cmd);
  406. drawSettings.SetShaderPassName(0, k_NormalsRenderingPassName);
  407. renderContext.DrawRenderers(cullResults, ref drawSettings, ref filterSettings);
  408. }
  409. static public void RenderLights(Camera camera, CommandBuffer cmdBuffer, int layerToRender, uint blendStylesUsed)
  410. {
  411. for (int i = 0; i < s_BlendStyles.Length; ++i)
  412. {
  413. if ((blendStylesUsed & (uint)(1<<i)) == 0)
  414. continue;
  415. string sampleName = s_BlendStyles[i].name;
  416. cmdBuffer.BeginSample(sampleName);
  417. cmdBuffer.SetRenderTarget(s_LightRenderTargets[i].Identifier());
  418. bool rtDirty = false;
  419. Color clearColor;
  420. if (!Light2DManager.GetGlobalColor(layerToRender, i, out clearColor))
  421. clearColor = Color.black;
  422. else
  423. rtDirty = true;
  424. if (s_LightRenderTargetsDirty[i] || rtDirty)
  425. cmdBuffer.ClearRenderTarget(false, true, clearColor);
  426. rtDirty |= RenderLightSet(
  427. camera,
  428. i,
  429. cmdBuffer,
  430. layerToRender,
  431. s_LightRenderTargets[i].Identifier(),
  432. Light2D.GetLightsByBlendStyle(i)
  433. );
  434. s_LightRenderTargetsDirty[i] = rtDirty;
  435. cmdBuffer.EndSample(sampleName);
  436. }
  437. }
  438. static public void RenderLightVolumes(Camera camera, CommandBuffer cmdBuffer, int layerToRender, RenderTargetIdentifier renderTarget, uint blendStylesUsed)
  439. {
  440. for (int i = 0; i < s_BlendStyles.Length; ++i)
  441. {
  442. if ((blendStylesUsed & (uint)(1 << i)) == 0)
  443. continue;
  444. string sampleName = s_BlendStyles[i].name;
  445. cmdBuffer.BeginSample(sampleName);
  446. RenderLightVolumeSet(
  447. camera,
  448. i,
  449. cmdBuffer,
  450. layerToRender,
  451. renderTarget,
  452. Light2D.GetLightsByBlendStyle(i)
  453. );
  454. cmdBuffer.EndSample(sampleName);
  455. }
  456. }
  457. static void SetBlendModes(Material material, BlendMode src, BlendMode dst)
  458. {
  459. material.SetFloat("_SrcBlend", (float)src);
  460. material.SetFloat("_DstBlend", (float)dst);
  461. }
  462. static uint GetLightMaterialIndex(Light2D light, bool isVolume)
  463. {
  464. int bitIndex = 0;
  465. uint volumeBit = isVolume ? 1u << bitIndex : 0u;
  466. bitIndex++;
  467. uint shapeBit = light.IsShapeLight() ? 1u << bitIndex : 0u;
  468. bitIndex++;
  469. uint additiveBit = light.alphaBlendOnOverlap ? 0u : 1u << bitIndex;
  470. bitIndex++;
  471. uint spriteBit = light.lightType == Light2D.LightType.Sprite ? 1u << bitIndex : 0u;
  472. bitIndex++;
  473. uint pointCookieBit = (!light.IsShapeLight() && light.lightCookieSprite != null && light.lightCookieSprite.texture != null) ? 1u << bitIndex : 0u;
  474. bitIndex++;
  475. uint pointFastQualityBit = (!light.IsShapeLight() && light.pointLightQuality == Light2D.PointLightQuality.Fast) ? 1u << bitIndex : 0u;
  476. bitIndex++;
  477. uint useNormalMap = light.useNormalMap ? 1u << bitIndex : 0u;
  478. return pointFastQualityBit | pointCookieBit | spriteBit | additiveBit | shapeBit | volumeBit | useNormalMap;
  479. }
  480. static Material CreateLightMaterial(Light2D light, bool isVolume)
  481. {
  482. bool isShape = light.IsShapeLight();
  483. Material material;
  484. if (isVolume)
  485. material = CoreUtils.CreateEngineMaterial(isShape ? s_Renderer2DData.shapeLightVolumeShader : s_Renderer2DData.pointLightVolumeShader);
  486. else
  487. {
  488. material = CoreUtils.CreateEngineMaterial(isShape ? s_Renderer2DData.shapeLightShader : s_Renderer2DData.pointLightShader);
  489. if (!light.alphaBlendOnOverlap)
  490. {
  491. SetBlendModes(material, BlendMode.One, BlendMode.One);
  492. material.EnableKeyword(k_UseAdditiveBlendingKeyword);
  493. }
  494. else
  495. SetBlendModes(material, BlendMode.SrcAlpha, BlendMode.OneMinusSrcAlpha);
  496. }
  497. if (light.lightType == Light2D.LightType.Sprite)
  498. material.EnableKeyword(k_SpriteLightKeyword);
  499. if (!isShape && light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
  500. material.EnableKeyword(k_UsePointLightCookiesKeyword);
  501. if (!isShape && light.pointLightQuality == Light2D.PointLightQuality.Fast)
  502. material.EnableKeyword(k_LightQualityFastKeyword);
  503. if (light.useNormalMap)
  504. material.EnableKeyword(k_UseNormalMap);
  505. return material;
  506. }
  507. static Material GetLightMaterial(Light2D light, bool isVolume)
  508. {
  509. uint materialIndex = GetLightMaterialIndex(light, isVolume);
  510. if (s_LightMaterials[materialIndex] == null)
  511. s_LightMaterials[materialIndex] = CreateLightMaterial(light, isVolume);
  512. return s_LightMaterials[materialIndex];
  513. }
  514. static Material GetShadowMaterial(int index)
  515. {
  516. int shadowMaterialIndex = index % 255;
  517. if(s_ShadowMaterials[shadowMaterialIndex] == null)
  518. {
  519. s_ShadowMaterials[shadowMaterialIndex] = CoreUtils.CreateEngineMaterial(s_Renderer2DData.shadowGroupShader);
  520. s_ShadowMaterials[shadowMaterialIndex].SetFloat("_ShadowStencilGroup", index);
  521. }
  522. return s_ShadowMaterials[shadowMaterialIndex];
  523. }
  524. static Material GetRemoveSelfShadowMaterial(int index)
  525. {
  526. int shadowMaterialIndex = index % 255;
  527. if (s_RemoveSelfShadowMaterials[shadowMaterialIndex] == null)
  528. {
  529. s_RemoveSelfShadowMaterials[shadowMaterialIndex] = CoreUtils.CreateEngineMaterial(s_Renderer2DData.removeSelfShadowShader);
  530. s_RemoveSelfShadowMaterials[shadowMaterialIndex].SetFloat("_ShadowStencilGroup", index);
  531. }
  532. return s_RemoveSelfShadowMaterials[shadowMaterialIndex];
  533. }
  534. }
  535. }