Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

LightMinMaxZJob.cs 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using Unity.Burst;
  2. using Unity.Collections;
  3. using Unity.Jobs;
  4. using Unity.Mathematics;
  5. namespace UnityEngine.Rendering.Universal
  6. {
  7. [BurstCompile]
  8. struct LightMinMaxZJob : IJobFor
  9. {
  10. public Fixed2<float4x4> worldToViews;
  11. [ReadOnly]
  12. public NativeArray<VisibleLight> lights;
  13. public NativeArray<float2> minMaxZs;
  14. public void Execute(int index)
  15. {
  16. var lightIndex = index % lights.Length;
  17. var light = lights[lightIndex];
  18. var lightToWorld = (float4x4)light.localToWorldMatrix;
  19. var originWS = lightToWorld.c3.xyz;
  20. var viewIndex = index / lights.Length;
  21. var worldToView = worldToViews[viewIndex];
  22. var originVS = math.mul(worldToView, math.float4(originWS, 1)).xyz;
  23. originVS.z *= -1;
  24. var minMax = math.float2(originVS.z - light.range, originVS.z + light.range);
  25. if (light.lightType == LightType.Spot)
  26. {
  27. // Based on https://iquilezles.org/www/articles/diskbbox/diskbbox.htm
  28. var angleA = math.radians(light.spotAngle) * 0.5f;
  29. float cosAngleA = math.cos(angleA);
  30. float coneHeight = light.range * cosAngleA;
  31. float3 spotDirectionWS = lightToWorld.c2.xyz;
  32. var endPointWS = originWS + spotDirectionWS * coneHeight;
  33. var endPointVS = math.mul(worldToView, math.float4(endPointWS, 1)).xyz;
  34. endPointVS.z *= -1;
  35. var angleB = math.PI * 0.5f - angleA;
  36. var coneRadius = light.range * cosAngleA * math.sin(angleA) / math.sin(angleB);
  37. var a = endPointVS - originVS;
  38. var e = math.sqrt(1.0f - a.z * a.z / math.dot(a, a));
  39. // `-a.z` and `a.z` is `dot(a, {0, 0, -1}).z` and `dot(a, {0, 0, 1}).z` optimized
  40. // `cosAngleA` is multiplied by `coneHeight` to avoid normalizing `a`, which we know has length `coneHeight`
  41. if (-a.z < coneHeight * cosAngleA) minMax.x = math.min(originVS.z, endPointVS.z - e * coneRadius);
  42. if (a.z < coneHeight * cosAngleA) minMax.y = math.max(originVS.z, endPointVS.z + e * coneRadius);
  43. }
  44. else if (light.lightType != LightType.Point)
  45. {
  46. // Currently we support only spot, point and directional lights in URP. This job only deals with the
  47. // first two. If any other light type is found, skip that light.
  48. minMax.x = float.MaxValue;
  49. minMax.y = float.MinValue;
  50. }
  51. minMax.x = math.max(minMax.x, 0);
  52. minMax.y = math.max(minMax.y, 0);
  53. minMaxZs[index] = minMax;
  54. }
  55. }
  56. }