No Description
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.

MostRepresentativePoint.hlsl 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #ifndef UNITY_AREA_MRP_INCLUDED
  2. #define UNITY_AREA_MRP_INCLUDED
  3. // Ref: Moving Frostbite to PBR (Listing 11).
  4. // Returns the solid angle of a rectangle at the point.
  5. float SolidAngleRectangle(float3 positionWS, float4x3 lightVerts)
  6. {
  7. float3 v0 = lightVerts[0] - positionWS;
  8. float3 v1 = lightVerts[1] - positionWS;
  9. float3 v2 = lightVerts[2] - positionWS;
  10. float3 v3 = lightVerts[3] - positionWS;
  11. float3 n0 = normalize(cross(v0, v1));
  12. float3 n1 = normalize(cross(v1, v2));
  13. float3 n2 = normalize(cross(v2, v3));
  14. float3 n3 = normalize(cross(v3, v0));
  15. float g0 = FastACos(dot(-n0, n1));
  16. float g1 = FastACos(dot(-n1, n2));
  17. float g2 = FastACos(dot(-n2, n3));
  18. float g3 = FastACos(dot(-n3, n0));
  19. return g0 + g1 + g2 + g3 - TWO_PI;
  20. }
  21. // Optimized (and approximate) solid angle routine. Doesn't handle the horizon.
  22. float SolidAngleRightPyramid(float positionWS, float lightPositionWS, float halfWidth, float halfHeight)
  23. {
  24. const float a = halfWidth;
  25. const float b = halfHeight;
  26. const float h = length(positionWS - lightPositionWS);
  27. return 4.0 * FastASin(a * b / sqrt (( a * a + h * h) * (b * b + h * h) ));
  28. }
  29. float FlatAngleSegment(float3 positionWS, float3 lightP1, float3 lightP2)
  30. {
  31. float3 v0 = normalize(lightP1 - positionWS);
  32. float3 v1 = normalize(lightP2 - positionWS);
  33. return FastACos(dot(v0,v1));
  34. }
  35. // Ref: Moving Frostbite to PBR (Appendix E, Listing E.2)
  36. // Returns the closest point to a rectangular shape defined by right and up (and the rect extents).
  37. float3 ClosestPointRectangle(float3 positionWS, float3 planeOrigin, float3 left, float3 up, float halfWidth, float halfHeight)
  38. {
  39. float3 dir = positionWS - planeOrigin;
  40. // Project into the 2D light plane.
  41. float2 dist2D = float2(dot(dir, left), dot(dir, up));
  42. // Clamp within the rectangle.
  43. const float2 halfSize = float2(halfWidth, halfHeight);
  44. dist2D = clamp(dist2D, -halfSize, halfSize);
  45. // Compute the new world position.
  46. return planeOrigin + dist2D.x * left + dist2D.y * up;
  47. }
  48. // Ref: Moving Frostbite to PBR (Listing 13)
  49. float3 ClosestPointLine(float3 a, float3 b, float3 c)
  50. {
  51. float3 ab = b - a;
  52. float t = dot(c - a, ab) / dot(ab, ab);
  53. return a + t * ab;
  54. }
  55. float3 ClosestPointSegment(float3 a, float3 b, float3 c)
  56. {
  57. float3 ab = b - a;
  58. float t = dot(c - a, ab) / dot(ab, ab);
  59. return a + saturate(t) * ab;
  60. }
  61. #endif // UNITY_AREA_MRP_INCLUDED