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