123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- using Unity.Collections;
- using Unity.Jobs;
- using Unity.Mathematics;
-
- namespace UnityEngine.Rendering.Universal
- {
- internal struct DecalSubDrawCall
- {
- public int start;
- public int end;
- public int count { get => end - start; }
- }
-
- /// <summary>
- /// Contains information about <see cref="DecalEntity"/> draw calls.
- /// </summary>
- internal class DecalDrawCallChunk : DecalChunk
- {
- public NativeArray<float4x4> decalToWorlds;
- public NativeArray<float4x4> normalToDecals;
- public NativeArray<float> renderingLayerMasks;
- public NativeArray<DecalSubDrawCall> subCalls;
- public NativeArray<int> subCallCounts;
-
- public int subCallCount { set { subCallCounts[0] = value; } get => subCallCounts[0]; }
-
- public override void RemoveAtSwapBack(int entityIndex)
- {
- RemoveAtSwapBack(ref decalToWorlds, entityIndex, count);
- RemoveAtSwapBack(ref normalToDecals, entityIndex, count);
- RemoveAtSwapBack(ref renderingLayerMasks, entityIndex, count);
- RemoveAtSwapBack(ref subCalls, entityIndex, count);
- count--;
- }
-
- public override void SetCapacity(int newCapacity)
- {
- decalToWorlds.ResizeArray(newCapacity);
- normalToDecals.ResizeArray(newCapacity);
- renderingLayerMasks.ResizeArray(newCapacity);
- subCalls.ResizeArray(newCapacity);
- capacity = newCapacity;
- }
-
- public override void Dispose()
- {
- subCallCounts.Dispose();
-
- if (capacity == 0)
- return;
-
- decalToWorlds.Dispose();
- normalToDecals.Dispose();
- renderingLayerMasks.Dispose();
- subCalls.Dispose();
- count = 0;
- capacity = 0;
- }
- }
-
- /// <summary>
- /// Outputs draw calls into <see cref="DecalDrawCallChunk"/>.
- /// </summary>
- internal class DecalCreateDrawCallSystem
- {
- private DecalEntityManager m_EntityManager;
- private ProfilingSampler m_Sampler;
- private float m_MaxDrawDistance;
-
- /// <summary>
- /// Provides acces to the maximum draw distance.
- /// </summary>
- public float maxDrawDistance
- {
- get { return m_MaxDrawDistance; }
- set { m_MaxDrawDistance = value; }
- }
-
- public DecalCreateDrawCallSystem(DecalEntityManager entityManager, float maxDrawDistance)
- {
- m_EntityManager = entityManager;
- m_Sampler = new ProfilingSampler("DecalCreateDrawCallSystem.Execute");
- m_MaxDrawDistance = maxDrawDistance;
- }
-
- public void Execute()
- {
- using (new ProfilingScope(m_Sampler))
- {
- for (int i = 0; i < m_EntityManager.chunkCount; ++i)
- Execute(m_EntityManager.cachedChunks[i], m_EntityManager.culledChunks[i], m_EntityManager.drawCallChunks[i], m_EntityManager.cachedChunks[i].count);
- }
- }
-
- private void Execute(DecalCachedChunk cachedChunk, DecalCulledChunk culledChunk, DecalDrawCallChunk drawCallChunk, int count)
- {
- if (count == 0)
- return;
-
- DrawCallJob drawCallJob = new DrawCallJob()
- {
- decalToWorlds = cachedChunk.decalToWorlds,
- normalToWorlds = cachedChunk.normalToWorlds,
- sizeOffsets = cachedChunk.sizeOffsets,
- drawDistances = cachedChunk.drawDistances,
- angleFades = cachedChunk.angleFades,
- uvScaleBiases = cachedChunk.uvScaleBias,
- layerMasks = cachedChunk.layerMasks,
- sceneLayerMasks = cachedChunk.sceneLayerMasks,
- fadeFactors = cachedChunk.fadeFactors,
- boundingSpheres = cachedChunk.boundingSpheres,
- renderingLayerMasks = cachedChunk.renderingLayerMasks,
-
- cameraPosition = culledChunk.cameraPosition,
- sceneCullingMask = culledChunk.sceneCullingMask,
- cullingMask = culledChunk.cullingMask,
- visibleDecalIndices = culledChunk.visibleDecalIndices,
- visibleDecalCount = culledChunk.visibleDecalCount,
- maxDrawDistance = m_MaxDrawDistance,
-
- decalToWorldsDraw = drawCallChunk.decalToWorlds,
- normalToDecalsDraw = drawCallChunk.normalToDecals,
- renderingLayerMasksDraw = drawCallChunk.renderingLayerMasks,
- subCalls = drawCallChunk.subCalls,
- subCallCount = drawCallChunk.subCallCounts,
- };
-
- var handle = drawCallJob.Schedule(cachedChunk.currentJobHandle);
- drawCallChunk.currentJobHandle = handle;
- cachedChunk.currentJobHandle = handle;
- }
-
- #if ENABLE_BURST_1_0_0_OR_NEWER
- [Unity.Burst.BurstCompile]
- #endif
- struct DrawCallJob : IJob
- {
- [ReadOnly] public NativeArray<float4x4> decalToWorlds;
- [ReadOnly] public NativeArray<float4x4> normalToWorlds;
- [ReadOnly] public NativeArray<float4x4> sizeOffsets;
- [ReadOnly] public NativeArray<float2> drawDistances;
- [ReadOnly] public NativeArray<float2> angleFades;
- [ReadOnly] public NativeArray<float4> uvScaleBiases;
- [ReadOnly] public NativeArray<int> layerMasks;
- [ReadOnly] public NativeArray<ulong> sceneLayerMasks;
- [ReadOnly] public NativeArray<float> fadeFactors;
- [ReadOnly] public NativeArray<BoundingSphere> boundingSpheres;
- [ReadOnly] public NativeArray<uint> renderingLayerMasks;
-
- public Vector3 cameraPosition;
- public ulong sceneCullingMask;
- public int cullingMask;
- [ReadOnly] public NativeArray<int> visibleDecalIndices;
- public int visibleDecalCount;
- public float maxDrawDistance;
-
- [WriteOnly] public NativeArray<float4x4> decalToWorldsDraw;
- [WriteOnly] public NativeArray<float4x4> normalToDecalsDraw;
- [WriteOnly] public NativeArray<float> renderingLayerMasksDraw;
- [WriteOnly] public NativeArray<DecalSubDrawCall> subCalls;
- [WriteOnly] public NativeArray<int> subCallCount;
-
- public void Execute()
- {
- int subCallIndex = 0;
- int instanceIndex = 0;
- int instanceStart = 0;
-
- for (int i = 0; i < visibleDecalCount; ++i)
- {
- int decalIndex = visibleDecalIndices[i];
-
- #if UNITY_EDITOR
- ulong decalSceneCullingMask = sceneLayerMasks[decalIndex];
- if ((sceneCullingMask & decalSceneCullingMask) == 0)
- continue;
- #endif
- int decalMask = 1 << layerMasks[decalIndex];
- if ((cullingMask & decalMask) == 0)
- continue;
-
- BoundingSphere boundingSphere = boundingSpheres[decalIndex];
- float2 drawDistance = drawDistances[decalIndex];
-
- float distanceToDecal = (cameraPosition - boundingSphere.position).magnitude;
- float cullDistance = math.min(drawDistance.x, maxDrawDistance) + boundingSphere.radius;
- if (distanceToDecal > cullDistance)
- continue;
-
- decalToWorldsDraw[instanceIndex] = decalToWorlds[decalIndex];
-
- float fadeFactorScaler = fadeFactors[decalIndex];
- float2 angleFade = angleFades[decalIndex];
- float4 uvScaleBias = uvScaleBiases[decalIndex];
-
- float4x4 normalToDecals = normalToWorlds[decalIndex];
- // NormalToWorldBatchis a Matrix4x4x but is a Rotation matrix so bottom row and last column can be used for other data to save space
- float fadeFactor = fadeFactorScaler * math.clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - drawDistance.y)), 0.0f, 1.0f);
- normalToDecals.c0.w = uvScaleBias.x;
- normalToDecals.c1.w = uvScaleBias.y;
- normalToDecals.c2.w = uvScaleBias.z;
- normalToDecals.c3 = new float4(fadeFactor * 1.0f, angleFade.x, angleFade.y, uvScaleBias.w);
- normalToDecalsDraw[instanceIndex] = normalToDecals;
-
- renderingLayerMasksDraw[instanceIndex] = (float)renderingLayerMasks[decalIndex];
-
- instanceIndex++;
-
- int instanceCount = instanceIndex - instanceStart;
- bool isReachedMaximumBatchSize = instanceCount >= DecalDrawSystem.MaxBatchSize;
- if (isReachedMaximumBatchSize)
- {
- subCalls[subCallIndex++] = new DecalSubDrawCall()
- {
- start = instanceStart,
- end = instanceIndex,
- };
- instanceStart = instanceIndex;
- }
- }
-
- int remainingInstanceCount = instanceIndex - instanceStart;
- if (remainingInstanceCount != 0)
- {
- subCalls[subCallIndex++] = new DecalSubDrawCall()
- {
- start = instanceStart,
- end = instanceIndex,
- };
- }
-
- subCallCount[0] = subCallIndex;
- }
- }
- }
- }
|