Sin descripción
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.

ZBinningJob.cs 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using Unity.Burst;
  3. using Unity.Collections;
  4. using Unity.Jobs;
  5. using Unity.Mathematics;
  6. namespace UnityEngine.Rendering.Universal
  7. {
  8. [BurstCompile(FloatMode = FloatMode.Fast, DisableSafetyChecks = true, OptimizeFor = OptimizeFor.Performance)]
  9. struct ZBinningJob : IJobFor
  10. {
  11. // Do not use this for the innerloopBatchCount (use 1 for that). Use for dividing the arrayLength when scheduling.
  12. public const int batchSize = 128;
  13. public const int headerLength = 2;
  14. [NativeDisableParallelForRestriction]
  15. public NativeArray<uint> bins;
  16. [ReadOnly]
  17. public NativeArray<float2> minMaxZs;
  18. public float zBinScale;
  19. public float zBinOffset;
  20. public int binCount;
  21. public int wordsPerTile;
  22. public int lightCount;
  23. public int reflectionProbeCount;
  24. public int batchCount;
  25. public int viewCount;
  26. public bool isOrthographic;
  27. static uint EncodeHeader(uint min, uint max)
  28. {
  29. return (min & 0xFFFF) | ((max & 0xFFFF) << 16);
  30. }
  31. static (uint, uint) DecodeHeader(uint zBin)
  32. {
  33. return (zBin & 0xFFFF, (zBin >> 16) & 0xFFFF);
  34. }
  35. public void Execute(int jobIndex)
  36. {
  37. var batchIndex = jobIndex % batchCount;
  38. var viewIndex = jobIndex / batchCount;
  39. var binStart = batchSize * batchIndex;
  40. var binEnd = math.min(binStart + batchSize, binCount) - 1;
  41. var binOffset = viewIndex * binCount;
  42. var emptyHeader = EncodeHeader(ushort.MaxValue, ushort.MinValue);
  43. for (var binIndex = binStart; binIndex <= binEnd; binIndex++)
  44. {
  45. bins[(binOffset + binIndex) * (headerLength + wordsPerTile) + 0] = emptyHeader;
  46. bins[(binOffset + binIndex) * (headerLength + wordsPerTile) + 1] = emptyHeader;
  47. }
  48. // Regarding itemOffset: minMaxZs contains [lights view 0, lights view 1, probes view 0, probes view 1] when
  49. // using XR single pass instanced, and otherwise [lights, probes]. So we figure out what the offset is based
  50. // on the view count and index.
  51. // Fill ZBins for lights.
  52. FillZBins(binStart, binEnd, 0, lightCount, 0, viewIndex * lightCount, binOffset);
  53. // Fill ZBins for reflection probes.
  54. FillZBins(binStart, binEnd, lightCount, lightCount + reflectionProbeCount, 1, lightCount * (viewCount - 1) + viewIndex * reflectionProbeCount, binOffset);
  55. }
  56. void FillZBins(int binStart, int binEnd, int itemStart, int itemEnd, int headerIndex, int itemOffset, int binOffset)
  57. {
  58. for (var index = itemStart; index < itemEnd; index++)
  59. {
  60. var minMax = minMaxZs[itemOffset + index];
  61. var minBin = math.max((int)((isOrthographic ? minMax.x : math.log2(minMax.x)) * zBinScale + zBinOffset), binStart);
  62. var maxBin = math.min((int)((isOrthographic ? minMax.y : math.log2(minMax.y)) * zBinScale + zBinOffset), binEnd);
  63. var wordIndex = index / 32;
  64. var bitMask = 1u << (index % 32);
  65. for (var binIndex = minBin; binIndex <= maxBin; binIndex++)
  66. {
  67. var baseIndex = (binOffset + binIndex) * (headerLength + wordsPerTile);
  68. var (minIndex, maxIndex) = DecodeHeader(bins[baseIndex + headerIndex]);
  69. minIndex = math.min(minIndex, (uint)index);
  70. maxIndex = math.max(maxIndex, (uint)index);
  71. bins[baseIndex + headerIndex] = EncodeHeader(minIndex, maxIndex);
  72. bins[baseIndex + headerLength + wordIndex] |= bitMask;
  73. }
  74. }
  75. }
  76. }
  77. }