暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Light2DCullResult.cs 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using System.Collections.Generic;
  2. using Unity.Mathematics;
  3. using UnityEngine.Profiling;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. internal struct LightStats
  7. {
  8. public int totalLights;
  9. public int totalShadowLights;
  10. public int totalShadows;
  11. public int totalNormalMapUsage;
  12. public int totalVolumetricUsage;
  13. public int totalVolumetricShadowUsage;
  14. public uint blendStylesUsed;
  15. public uint blendStylesWithLights;
  16. public bool useAnyLights { get { return totalLights + totalShadowLights > 0; } }
  17. public bool useLights { get { return totalLights > 0; } }
  18. public bool useShadows { get { return totalShadows > 0; } }
  19. public bool useVolumetricLights { get { return totalVolumetricUsage > 0; } }
  20. public bool useVolumetricShadowLights { get { return totalVolumetricShadowUsage > 0; } }
  21. public bool useNormalMap { get { return totalNormalMapUsage > 0; } }
  22. }
  23. internal interface ILight2DCullResult
  24. {
  25. List<Light2D> visibleLights { get; }
  26. HashSet<ShadowCasterGroup2D> visibleShadows { get; }
  27. LightStats GetLightStatsByLayer(int layerID, ref LayerBatch layer);
  28. bool IsSceneLit();
  29. #if UNITY_EDITOR
  30. // Determine if culling result is based of game camera
  31. bool IsGameView();
  32. #endif
  33. }
  34. internal class Light2DCullResult : ILight2DCullResult
  35. {
  36. private List<Light2D> m_VisibleLights = new List<Light2D>();
  37. public List<Light2D> visibleLights => m_VisibleLights;
  38. private HashSet<ShadowCasterGroup2D> m_VisibleShadows = new HashSet<ShadowCasterGroup2D>();
  39. public HashSet<ShadowCasterGroup2D> visibleShadows => m_VisibleShadows;
  40. #if UNITY_EDITOR
  41. bool m_IsGameView;
  42. #endif
  43. public bool IsSceneLit()
  44. {
  45. return Light2DManager.lights.Count > 0;
  46. }
  47. #if UNITY_EDITOR
  48. public bool IsGameView()
  49. {
  50. return m_IsGameView;
  51. }
  52. #endif
  53. public LightStats GetLightStatsByLayer(int layerID, ref LayerBatch layer)
  54. {
  55. layer.lights.Clear();
  56. layer.shadowLights.Clear();
  57. layer.shadowCasters.Clear();
  58. var returnStats = new LightStats();
  59. foreach (var light in visibleLights)
  60. {
  61. if (!light.IsLitLayer(layerID))
  62. continue;
  63. if (light.normalMapQuality != Light2D.NormalMapQuality.Disabled)
  64. returnStats.totalNormalMapUsage++;
  65. if (light.volumeIntensity > 0 && light.volumetricEnabled)
  66. returnStats.totalVolumetricUsage++;
  67. if (light.volumeIntensity > 0 && light.volumetricEnabled && RendererLighting.CanCastShadows(light, layerID))
  68. returnStats.totalVolumetricShadowUsage++;
  69. returnStats.blendStylesUsed |= (uint)(1 << light.blendStyleIndex);
  70. if (light.lightType != Light2D.LightType.Global)
  71. returnStats.blendStylesWithLights |= (uint)(1 << light.blendStyleIndex);
  72. // Check if layer has shadows
  73. bool isShadowed = false;
  74. if (RendererLighting.CanCastShadows(light, layerID))
  75. {
  76. foreach (var group in visibleShadows)
  77. {
  78. var shadowCasters = group.GetShadowCasters();
  79. if (shadowCasters != null)
  80. {
  81. foreach (var shadowCaster in shadowCasters)
  82. {
  83. if (shadowCaster.IsLit(light) && shadowCaster.IsShadowedLayer(layerID))
  84. {
  85. isShadowed = true;
  86. returnStats.totalShadows++;
  87. if (!layer.shadowCasters.Contains(group))
  88. layer.shadowCasters.Add(group);
  89. }
  90. }
  91. }
  92. }
  93. }
  94. if (isShadowed)
  95. {
  96. returnStats.totalShadowLights++;
  97. layer.shadowLights.Add(light);
  98. }
  99. else
  100. {
  101. returnStats.totalLights++;
  102. layer.lights.Add(light);
  103. }
  104. }
  105. return returnStats;
  106. }
  107. public void SetupCulling(ref ScriptableCullingParameters cullingParameters, Camera camera)
  108. {
  109. #if UNITY_EDITOR
  110. m_IsGameView = UniversalRenderPipeline.IsGameCamera(camera);
  111. #endif
  112. Profiler.BeginSample("Cull 2D Lights and Shadow Casters");
  113. m_VisibleLights.Clear();
  114. foreach (var light in Light2DManager.lights)
  115. {
  116. if ((camera.cullingMask & (1 << light.gameObject.layer)) == 0)
  117. continue;
  118. #if UNITY_EDITOR
  119. if (!UnityEditor.SceneManagement.StageUtility.IsGameObjectRenderedByCamera(light.gameObject, camera))
  120. continue;
  121. #endif
  122. if (light.lightType == Light2D.LightType.Global)
  123. {
  124. m_VisibleLights.Add(light);
  125. continue;
  126. }
  127. Profiler.BeginSample("Test Planes");
  128. var position = light.boundingSphere.position;
  129. var culled = false;
  130. for (var i = 0; i < cullingParameters.cullingPlaneCount; ++i)
  131. {
  132. var plane = cullingParameters.GetCullingPlane(i);
  133. // most of the time is spent getting world position
  134. var distance = math.dot(position, plane.normal) + plane.distance;
  135. if (distance < -light.boundingSphere.radius)
  136. {
  137. culled = true;
  138. break;
  139. }
  140. }
  141. Profiler.EndSample();
  142. if (culled)
  143. continue;
  144. m_VisibleLights.Add(light);
  145. }
  146. // must be sorted here because light order could change
  147. m_VisibleLights.Sort((l1, l2) => l1.lightOrder - l2.lightOrder);
  148. m_VisibleShadows.Clear();
  149. if (ShadowCasterGroup2DManager.shadowCasterGroups != null)
  150. {
  151. foreach (var group in ShadowCasterGroup2DManager.shadowCasterGroups)
  152. {
  153. var shadowCasters = group.GetShadowCasters();
  154. if (shadowCasters != null)
  155. {
  156. foreach (var shadowCaster in shadowCasters)
  157. {
  158. // Cull against visible lights in the scene
  159. foreach (var light in m_VisibleLights)
  160. {
  161. if (shadowCaster.IsLit(light) && !m_VisibleShadows.Contains(group))
  162. {
  163. m_VisibleShadows.Add(group);
  164. break;
  165. }
  166. }
  167. if (m_VisibleShadows.Contains(group))
  168. break;
  169. }
  170. }
  171. }
  172. }
  173. Profiler.EndSample();
  174. }
  175. }
  176. }