暫無描述
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.

DecalCreateDrawCallSystem.cs 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using Unity.Collections;
  2. using Unity.Jobs;
  3. using Unity.Mathematics;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. internal struct DecalSubDrawCall
  7. {
  8. public int start;
  9. public int end;
  10. public int count { get => end - start; }
  11. }
  12. /// <summary>
  13. /// Contains information about <see cref="DecalEntity"/> draw calls.
  14. /// </summary>
  15. internal class DecalDrawCallChunk : DecalChunk
  16. {
  17. public NativeArray<float4x4> decalToWorlds;
  18. public NativeArray<float4x4> normalToDecals;
  19. public NativeArray<float> renderingLayerMasks;
  20. public NativeArray<DecalSubDrawCall> subCalls;
  21. public NativeArray<int> subCallCounts;
  22. public int subCallCount { set { subCallCounts[0] = value; } get => subCallCounts[0]; }
  23. public override void RemoveAtSwapBack(int entityIndex)
  24. {
  25. RemoveAtSwapBack(ref decalToWorlds, entityIndex, count);
  26. RemoveAtSwapBack(ref normalToDecals, entityIndex, count);
  27. RemoveAtSwapBack(ref renderingLayerMasks, entityIndex, count);
  28. RemoveAtSwapBack(ref subCalls, entityIndex, count);
  29. count--;
  30. }
  31. public override void SetCapacity(int newCapacity)
  32. {
  33. decalToWorlds.ResizeArray(newCapacity);
  34. normalToDecals.ResizeArray(newCapacity);
  35. renderingLayerMasks.ResizeArray(newCapacity);
  36. subCalls.ResizeArray(newCapacity);
  37. capacity = newCapacity;
  38. }
  39. public override void Dispose()
  40. {
  41. subCallCounts.Dispose();
  42. if (capacity == 0)
  43. return;
  44. decalToWorlds.Dispose();
  45. normalToDecals.Dispose();
  46. renderingLayerMasks.Dispose();
  47. subCalls.Dispose();
  48. count = 0;
  49. capacity = 0;
  50. }
  51. }
  52. /// <summary>
  53. /// Outputs draw calls into <see cref="DecalDrawCallChunk"/>.
  54. /// </summary>
  55. internal class DecalCreateDrawCallSystem
  56. {
  57. private DecalEntityManager m_EntityManager;
  58. private ProfilingSampler m_Sampler;
  59. private float m_MaxDrawDistance;
  60. /// <summary>
  61. /// Provides acces to the maximum draw distance.
  62. /// </summary>
  63. public float maxDrawDistance
  64. {
  65. get { return m_MaxDrawDistance; }
  66. set { m_MaxDrawDistance = value; }
  67. }
  68. public DecalCreateDrawCallSystem(DecalEntityManager entityManager, float maxDrawDistance)
  69. {
  70. m_EntityManager = entityManager;
  71. m_Sampler = new ProfilingSampler("DecalCreateDrawCallSystem.Execute");
  72. m_MaxDrawDistance = maxDrawDistance;
  73. }
  74. public void Execute()
  75. {
  76. using (new ProfilingScope(m_Sampler))
  77. {
  78. for (int i = 0; i < m_EntityManager.chunkCount; ++i)
  79. Execute(m_EntityManager.cachedChunks[i], m_EntityManager.culledChunks[i], m_EntityManager.drawCallChunks[i], m_EntityManager.cachedChunks[i].count);
  80. }
  81. }
  82. private void Execute(DecalCachedChunk cachedChunk, DecalCulledChunk culledChunk, DecalDrawCallChunk drawCallChunk, int count)
  83. {
  84. if (count == 0)
  85. return;
  86. DrawCallJob drawCallJob = new DrawCallJob()
  87. {
  88. decalToWorlds = cachedChunk.decalToWorlds,
  89. normalToWorlds = cachedChunk.normalToWorlds,
  90. sizeOffsets = cachedChunk.sizeOffsets,
  91. drawDistances = cachedChunk.drawDistances,
  92. angleFades = cachedChunk.angleFades,
  93. uvScaleBiases = cachedChunk.uvScaleBias,
  94. layerMasks = cachedChunk.layerMasks,
  95. sceneLayerMasks = cachedChunk.sceneLayerMasks,
  96. fadeFactors = cachedChunk.fadeFactors,
  97. boundingSpheres = cachedChunk.boundingSpheres,
  98. renderingLayerMasks = cachedChunk.renderingLayerMasks,
  99. cameraPosition = culledChunk.cameraPosition,
  100. sceneCullingMask = culledChunk.sceneCullingMask,
  101. cullingMask = culledChunk.cullingMask,
  102. visibleDecalIndices = culledChunk.visibleDecalIndices,
  103. visibleDecalCount = culledChunk.visibleDecalCount,
  104. maxDrawDistance = m_MaxDrawDistance,
  105. decalToWorldsDraw = drawCallChunk.decalToWorlds,
  106. normalToDecalsDraw = drawCallChunk.normalToDecals,
  107. renderingLayerMasksDraw = drawCallChunk.renderingLayerMasks,
  108. subCalls = drawCallChunk.subCalls,
  109. subCallCount = drawCallChunk.subCallCounts,
  110. };
  111. var handle = drawCallJob.Schedule(cachedChunk.currentJobHandle);
  112. drawCallChunk.currentJobHandle = handle;
  113. cachedChunk.currentJobHandle = handle;
  114. }
  115. #if ENABLE_BURST_1_0_0_OR_NEWER
  116. [Unity.Burst.BurstCompile]
  117. #endif
  118. struct DrawCallJob : IJob
  119. {
  120. [ReadOnly] public NativeArray<float4x4> decalToWorlds;
  121. [ReadOnly] public NativeArray<float4x4> normalToWorlds;
  122. [ReadOnly] public NativeArray<float4x4> sizeOffsets;
  123. [ReadOnly] public NativeArray<float2> drawDistances;
  124. [ReadOnly] public NativeArray<float2> angleFades;
  125. [ReadOnly] public NativeArray<float4> uvScaleBiases;
  126. [ReadOnly] public NativeArray<int> layerMasks;
  127. [ReadOnly] public NativeArray<ulong> sceneLayerMasks;
  128. [ReadOnly] public NativeArray<float> fadeFactors;
  129. [ReadOnly] public NativeArray<BoundingSphere> boundingSpheres;
  130. [ReadOnly] public NativeArray<uint> renderingLayerMasks;
  131. public Vector3 cameraPosition;
  132. public ulong sceneCullingMask;
  133. public int cullingMask;
  134. [ReadOnly] public NativeArray<int> visibleDecalIndices;
  135. public int visibleDecalCount;
  136. public float maxDrawDistance;
  137. [WriteOnly] public NativeArray<float4x4> decalToWorldsDraw;
  138. [WriteOnly] public NativeArray<float4x4> normalToDecalsDraw;
  139. [WriteOnly] public NativeArray<float> renderingLayerMasksDraw;
  140. [WriteOnly] public NativeArray<DecalSubDrawCall> subCalls;
  141. [WriteOnly] public NativeArray<int> subCallCount;
  142. public void Execute()
  143. {
  144. int subCallIndex = 0;
  145. int instanceIndex = 0;
  146. int instanceStart = 0;
  147. for (int i = 0; i < visibleDecalCount; ++i)
  148. {
  149. int decalIndex = visibleDecalIndices[i];
  150. #if UNITY_EDITOR
  151. ulong decalSceneCullingMask = sceneLayerMasks[decalIndex];
  152. if ((sceneCullingMask & decalSceneCullingMask) == 0)
  153. continue;
  154. #endif
  155. int decalMask = 1 << layerMasks[decalIndex];
  156. if ((cullingMask & decalMask) == 0)
  157. continue;
  158. BoundingSphere boundingSphere = boundingSpheres[decalIndex];
  159. float2 drawDistance = drawDistances[decalIndex];
  160. float distanceToDecal = (cameraPosition - boundingSphere.position).magnitude;
  161. float cullDistance = math.min(drawDistance.x, maxDrawDistance) + boundingSphere.radius;
  162. if (distanceToDecal > cullDistance)
  163. continue;
  164. decalToWorldsDraw[instanceIndex] = decalToWorlds[decalIndex];
  165. float fadeFactorScaler = fadeFactors[decalIndex];
  166. float2 angleFade = angleFades[decalIndex];
  167. float4 uvScaleBias = uvScaleBiases[decalIndex];
  168. float4x4 normalToDecals = normalToWorlds[decalIndex];
  169. // NormalToWorldBatchis a Matrix4x4x but is a Rotation matrix so bottom row and last column can be used for other data to save space
  170. float fadeFactor = fadeFactorScaler * math.clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - drawDistance.y)), 0.0f, 1.0f);
  171. normalToDecals.c0.w = uvScaleBias.x;
  172. normalToDecals.c1.w = uvScaleBias.y;
  173. normalToDecals.c2.w = uvScaleBias.z;
  174. normalToDecals.c3 = new float4(fadeFactor * 1.0f, angleFade.x, angleFade.y, uvScaleBias.w);
  175. normalToDecalsDraw[instanceIndex] = normalToDecals;
  176. renderingLayerMasksDraw[instanceIndex] = (float)renderingLayerMasks[decalIndex];
  177. instanceIndex++;
  178. int instanceCount = instanceIndex - instanceStart;
  179. bool isReachedMaximumBatchSize = instanceCount >= DecalDrawSystem.MaxBatchSize;
  180. if (isReachedMaximumBatchSize)
  181. {
  182. subCalls[subCallIndex++] = new DecalSubDrawCall()
  183. {
  184. start = instanceStart,
  185. end = instanceIndex,
  186. };
  187. instanceStart = instanceIndex;
  188. }
  189. }
  190. int remainingInstanceCount = instanceIndex - instanceStart;
  191. if (remainingInstanceCount != 0)
  192. {
  193. subCalls[subCallIndex++] = new DecalSubDrawCall()
  194. {
  195. start = instanceStart,
  196. end = instanceIndex,
  197. };
  198. }
  199. subCallCount[0] = subCallIndex;
  200. }
  201. }
  202. }
  203. }