PointLights.cginc 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #ifndef VOLUMETRIC_FOG_2_POINT_LIGHTS
  2. #define VOLUMETRIC_FOG_2_POINT_LIGHTS
  3. #if VF2_POINT_LIGHTS
  4. //#define FAST_POINT_LIGHTS_OCCLUSION
  5. #define FOG_MAX_POINT_LIGHTS 16
  6. CBUFFER_START(VolumetricFog2PointLightBuffers)
  7. float4 _VF2_FogPointLightPosition[FOG_MAX_POINT_LIGHTS];
  8. half4 _VF2_PointLightColor[FOG_MAX_POINT_LIGHTS];
  9. float _VF2_PointLightInsideAtten;
  10. int _VF2_PointLightCount;
  11. CBUFFER_END
  12. #define dot2(x) dot(x,x)
  13. float minimum_distance_sqr(float fogLengthSqr, float3 w, float3 p) {
  14. // Return minimum distance between line segment vw and point p
  15. float t = saturate(dot(p, w) / fogLengthSqr);
  16. float3 projection = t * w;
  17. float distSqr = dot2(p - projection);
  18. return distSqr;
  19. }
  20. void AddPointLights(float3 rayStart, float3 rayDir, inout half4 sum, float t0, float fogLength) {
  21. float3 fogCeilingCut = rayStart + rayDir * t0;
  22. fogCeilingCut += rayDir * _VF2_PointLightInsideAtten;
  23. fogLength -= _VF2_PointLightInsideAtten;
  24. rayDir *= fogLength;
  25. float fogLengthSqr = fogLength * fogLength;
  26. for (int k=0;k<_VF2_PointLightCount;k++) {
  27. float3 pointLightPosition = _VF2_FogPointLightPosition[k].xyz;
  28. #if defined(FAST_POINT_LIGHTS_OCCLUSION)
  29. float4 clipPos = TransformWorldToHClip(pointLightPosition);
  30. float4 scrPos = ComputeScreenPos(clipPos);
  31. float depth = LinearEyeDepth(SampleSceneDepth(scrPos.xy / scrPos.w), _ZBufferParams);
  32. if (depth < clipPos.w) continue;
  33. #endif
  34. half pointLightInfluence = minimum_distance_sqr(fogLengthSqr, rayDir, pointLightPosition - fogCeilingCut) / _VF2_PointLightColor[k].w;
  35. half scattering = sum.a / (1.0 + pointLightInfluence);
  36. sum.rgb += _VF2_PointLightColor[k].rgb * scattering;
  37. }
  38. }
  39. half3 GetPointLights(float3 wpos) {
  40. half3 color = half3(0,0,0);
  41. for (int k=0;k<_VF2_PointLightCount;k++) {
  42. float3 toLight = _VF2_FogPointLightPosition[k].xyz - wpos;
  43. float dist = dot2(toLight);
  44. color += _VF2_PointLightColor[k].rgb * _VF2_PointLightColor[k].w / dist;
  45. }
  46. return color;
  47. }
  48. #endif // VF2_POINT_LIGHTS
  49. #endif // VOLUMETRIC_FOG_2_POINT_LIGHTS