Volumetric Lights.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /******************************************************************************/
  2. #include "!Header.h"
  3. #include "Sky.h"
  4. /******************************************************************************/
  5. BUFFER(VolLight)
  6. Vec VolMax=Vec(1, 1, 1);
  7. Flt Light_point_range;
  8. BUFFER_END
  9. /******************************************************************************/
  10. Vec4 VolDir_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  11. NOPERSP Vec2 inPosXY:TEXCOORD1,
  12. NOPERSP PIXEL ,
  13. uniform Int num ,
  14. uniform Bool cloud ):COLOR
  15. {
  16. Vec obj =GetPosLinear(inTex, inPosXY); // use linear filtering because we may be drawing to a smaller RT
  17. Flt power =0,
  18. length=Length(obj);
  19. if( length>ShdRange)
  20. {
  21. obj *=ShdRange/length;
  22. length=ShdRange;
  23. }
  24. VecH2 jitter_value=ShadowJitter(pixel.xy);
  25. Int steps=80;
  26. LOOP for(Int i=0; i<steps; i++)
  27. {
  28. Vec pos=ShadowDirTransform(obj*(Flt(i+1)/(steps+1)), num);
  29. if(cloud)power+=CompareDepth(pos, jitter_value, true)*CompareDepth2(pos);
  30. else power+=CompareDepth(pos, jitter_value, true);
  31. }
  32. power =Pow(power /steps , Light_dir.vol_exponent_steam.y);
  33. power*=Pow(length/ShdRange, Light_dir.vol_exponent_steam.y*(1-Light_dir.vol_exponent_steam.z));
  34. power*=Light_dir.vol_exponent_steam.x;
  35. return Vec4(Light_dir.color.rgb*power, 0);
  36. }
  37. /******************************************************************************/
  38. Vec4 VolPnt_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  39. NOPERSP Vec2 inPosXY:TEXCOORD1,
  40. NOPERSP PIXEL ):COLOR
  41. {
  42. Vec obj =GetPosLinear(inTex, inPosXY); // use linear filtering because we may be drawing to a smaller RT
  43. Flt power =0,
  44. length=Length(obj);
  45. if( length>Viewport.range)
  46. {
  47. obj *=Viewport.range/length;
  48. length=Viewport.range;
  49. }
  50. Vec from =ShdMatrix[3],
  51. to =Transform(obj, ShdMatrix);
  52. VecH2 jitter_value=ShadowJitter(pixel.xy);
  53. Int steps=48;
  54. LOOP for(Int i=0; i<steps; i++)
  55. {
  56. // TODO: optimize
  57. Vec pos=Lerp(from, to, Flt(i)/Flt(steps));
  58. power+=ShadowPointValue(obj*(Flt(i)/steps), jitter_value, true)*LightSqrDist(pos, Light_point_range);
  59. }
  60. return Vec4(Light_point.color.rgb*Min(Light_point.vol_max, Light_point.vol*power*(length/steps)), 0);
  61. }
  62. /******************************************************************************/
  63. Vec4 VolSqr_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  64. NOPERSP Vec2 inPosXY:TEXCOORD1,
  65. NOPERSP PIXEL ):COLOR
  66. {
  67. Vec obj =GetPosLinear(inTex, inPosXY); // use linear filtering because we may be drawing to a smaller RT
  68. Flt power =0,
  69. length=Length(obj);
  70. if( length>Viewport.range)
  71. {
  72. obj *=Viewport.range/length;
  73. length=Viewport.range;
  74. }
  75. Vec from =ShdMatrix[3],
  76. to =Transform(obj, ShdMatrix);
  77. Int steps=48;
  78. VecH2 jitter_value=ShadowJitter(pixel.xy);
  79. LOOP for(Int i=0; i<steps; i++)
  80. {
  81. // TODO: optimize
  82. Vec pos=Lerp(from, to, Flt(i)/Flt(steps));
  83. power+=ShadowPointValue(obj*(Flt(i)/steps), jitter_value, true)*LightSqrDist(pos);
  84. }
  85. return Vec4(Light_sqr.color.rgb*Min(Light_sqr.vol_max, Light_sqr.vol*power*(length/steps)), 0);
  86. }
  87. /******************************************************************************/
  88. Vec4 VolCone_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  89. NOPERSP Vec2 inPosXY:TEXCOORD1,
  90. NOPERSP PIXEL ):COLOR
  91. {
  92. Vec obj =GetPosLinear(inTex, inPosXY), // use linear filtering because we may be drawing to a smaller RT
  93. scale =Vec(Light_cone.scale, Light_cone.scale, 1);
  94. Flt power =0,
  95. length=Length(obj);
  96. if( length>Viewport.range)
  97. {
  98. obj *=Viewport.range/length;
  99. length=Viewport.range;
  100. }
  101. Vec from =ShdMatrix[3],
  102. to =Transform(obj, ShdMatrix);
  103. Int steps=48;
  104. VecH2 jitter_value=ShadowJitter(pixel.xy);
  105. LOOP for(Int i=0; i<steps; i++)
  106. {
  107. // TODO: optimize
  108. Vec pos=Lerp(from, to, Flt(i)/Flt(steps));
  109. Flt cur=Max(Abs(pos));
  110. if( pos.z>=cur)
  111. {
  112. power+=ShadowConeValue(obj*(Flt(i)/steps), jitter_value, true)*LightConeDist(pos*scale)*LightConeAngle(pos.xy/pos.z);
  113. }
  114. }
  115. return Vec4(Light_cone.color.rgb*Min(Light_cone.vol_max, Light_cone.vol*power*(length/steps)), 0);
  116. }
  117. /******************************************************************************/
  118. Vec4 Volumetric_PS(NOPERSP Vec2 inTex:TEXCOORD,
  119. uniform Bool add ,
  120. uniform Int samples=6 ):COLOR
  121. {
  122. Vec vol=TexLod(Col, inTex).rgb; // use linear filtering because Col may be smaller
  123. UNROLL for(Int i=0; i<samples; i++)
  124. {
  125. Vec2 t;
  126. if(samples== 4)t=ColSize.xy*BlendOfs4 [i]+inTex;
  127. //if(samples== 5)t=ColSize.xy*BlendOfs5 [i]+inTex;
  128. if(samples== 6)t=ColSize.xy*BlendOfs6 [i]+inTex;
  129. if(samples== 8)t=ColSize.xy*BlendOfs8 [i]+inTex;
  130. //if(samples== 9)t=ColSize.xy*BlendOfs9 [i]+inTex;
  131. if(samples==12)t=ColSize.xy*BlendOfs12[i]+inTex;
  132. //if(samples==13)t=ColSize.xy*BlendOfs13[i]+inTex;
  133. vol+=TexLod(Col, t).rgb; // use linear filtering because Col may be smaller and texcoords are not rounded
  134. }
  135. vol/=samples+1;
  136. vol =Min(vol, VolMax);
  137. if(add)return Vec4(vol, 0); // alpha blending : ALPHA_ADD
  138. else {Flt max=Max(vol); return Vec4(vol/(EPS+max), max);} // alpha blending : ALPHA_BLEND_DEC
  139. }
  140. /******************************************************************************/
  141. // TECHNIQUES
  142. /******************************************************************************/
  143. TECHNIQUE(VolDir1, DrawPosXY_VS(), VolDir_PS(1, false)); TECHNIQUE(VolDir1C, DrawPosXY_VS(), VolDir_PS(1, true));
  144. TECHNIQUE(VolDir2, DrawPosXY_VS(), VolDir_PS(2, false)); TECHNIQUE(VolDir2C, DrawPosXY_VS(), VolDir_PS(2, true));
  145. TECHNIQUE(VolDir3, DrawPosXY_VS(), VolDir_PS(3, false)); TECHNIQUE(VolDir3C, DrawPosXY_VS(), VolDir_PS(3, true));
  146. TECHNIQUE(VolDir4, DrawPosXY_VS(), VolDir_PS(4, false)); TECHNIQUE(VolDir4C, DrawPosXY_VS(), VolDir_PS(4, true));
  147. TECHNIQUE(VolDir5, DrawPosXY_VS(), VolDir_PS(5, false)); TECHNIQUE(VolDir5C, DrawPosXY_VS(), VolDir_PS(5, true));
  148. TECHNIQUE(VolDir6, DrawPosXY_VS(), VolDir_PS(6, false)); TECHNIQUE(VolDir6C, DrawPosXY_VS(), VolDir_PS(6, true));
  149. TECHNIQUE(VolPnt , DrawPosXY_VS(), VolPnt_PS ());
  150. TECHNIQUE(VolSqr , DrawPosXY_VS(), VolSqr_PS ());
  151. TECHNIQUE(VolCone, DrawPosXY_VS(), VolCone_PS());
  152. TECHNIQUE(Volumetric , Draw_VS(), Volumetric_PS(false));
  153. TECHNIQUE(VolumetricA, Draw_VS(), Volumetric_PS(true ));
  154. /******************************************************************************/