Fog.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. #define MAX_DENSITY 0.98f // was "1-EPS_GPU" but big values generate unnatural focus points in the FogBall Center
  6. /******************************************************************************/
  7. FogClass Fog;
  8. /******************************************************************************/
  9. FogClass::FogClass()
  10. {
  11. draw =false;
  12. affect_sky=false;
  13. density =0.02f;
  14. color =0.5f ;
  15. }
  16. /******************************************************************************/
  17. void FogClass::Draw(Bool after_sky)
  18. {
  19. if(after_sky==affect_sky)
  20. {
  21. if(draw && Renderer.canReadDepth() && Sh.h_Fog[0])
  22. {
  23. Int multi=(Renderer._ds->multiSample() ? (Renderer._cur_type==RT_DEFERRED ? 1 : 2) : 0);
  24. Renderer.set(Renderer._col(), Renderer._ds(), true, NEED_DEPTH_READ); // use DS because it may be used for 'D.depth2D' optimization and stencil tests
  25. Renderer.setMainViewport();
  26. Sh.h_FogColor_Density->set(Vec4(color, Mid(density, 0.0f, MAX_DENSITY))); // avoid 1 in case "Pow(1-density, ..)" in shader would cause NaN or slow-downs
  27. D .alpha(ALPHA_BLEND_DEC);
  28. if(multi && Sh.h_Fog[multi])
  29. {
  30. if(Renderer.hasStencilAttached())
  31. {
  32. D.stencil(STENCIL_MSAA_TEST);
  33. REPS(Renderer._eye, Renderer._eye_num)
  34. {
  35. Rect *rect=Renderer.setEyeParams();
  36. D.stencilRef(STENCIL_REF_MSAA); /*if(!affect_sky && multi!=1)D.depth2DOn();*/ Sh.h_Fog[multi]->draw(null, rect); D.depth2DOff(); // never enable 'depth2DOn' for deferred renderer as it's needed, it was tested that enabling this for forward renderer actually makes it slower (19 vs 25 fps on 200 draws)
  37. D.stencilRef( 0); if(!affect_sky )D.depth2DOn(); Sh.h_Fog[0 ]->draw(null, rect); if(!affect_sky)D.depth2DOff();
  38. }
  39. D.stencil(STENCIL_NONE);
  40. }else // if don't have stencil available then have to write all as multi-sampled
  41. {
  42. REPS(Renderer._eye, Renderer._eye_num)Sh.h_Fog[multi]->draw(null, Renderer.setEyeParams());
  43. }
  44. return;
  45. }else
  46. if(Sh.h_Fog[0])
  47. {
  48. if(!affect_sky)D.depth2DOn (); REPS(Renderer._eye, Renderer._eye_num)Sh.h_Fog[0]->draw(null, Renderer.setEyeParams());
  49. if(!affect_sky)D.depth2DOff();
  50. return;
  51. }
  52. }
  53. // clear because BlendLight shaders always use Fog
  54. Sh.h_FogColor_Density->set(Vec4Zero);
  55. }
  56. }
  57. /******************************************************************************/
  58. void FogDraw(C OBox &obox, Flt density, C Vec &color)
  59. {
  60. if(Frustum(obox) && Renderer.canReadDepth())
  61. {
  62. Sh.loadFogBoxShaders();
  63. Renderer.needDepthRead();
  64. D .alpha(ALPHA_BLEND_DEC);
  65. Sh.h_LocalFogColor_Density->set(Vec4(color, Mid(density, 0.0f, MAX_DENSITY))); // avoid 1 in case "Pow(1-density, ..)" in shader would cause NaN or slow-downs
  66. Vec delta=CamMatrix.pos-obox.center(), inside;
  67. inside.x=Dot(delta, obox.matrix.x);
  68. inside.y=Dot(delta, obox.matrix.y);
  69. inside.z=Dot(delta, obox.matrix.z);
  70. Vec size=obox.box.size()*0.5f;
  71. Matrix temp;
  72. temp.pos=obox.center();
  73. temp.x =obox.matrix.x*size.x;
  74. temp.y =obox.matrix.y*size.y;
  75. temp.z =obox.matrix.z*size.z;
  76. SetOneMatrix(temp);
  77. Flt e=Frustum.view_quad_max_dist;
  78. if(inside.x>=-size.x-e && inside.x<=size.x+e
  79. && inside.y>=-size.y-e && inside.y<=size.y+e
  80. && inside.z>=-size.z-e && inside.z<=size.z+e)
  81. {
  82. Sh.h_LocalFogInside->set(inside);
  83. if(inside.x>=-size.x+e && inside.x<=size.x-e
  84. && inside.y>=-size.y+e && inside.y<=size.y-e
  85. && inside.z>=-size.z+e && inside.z<=size.z-e)Sh.h_FogBox1->draw(Renderer._ds_1s);
  86. else Sh.h_FogBox0->draw(Renderer._ds_1s);
  87. }else
  88. {
  89. D .depth (true );
  90. D .depthWrite(false);
  91. D .cull (true );
  92. Sh.h_FogBox->begin(); MshrBox.set().drawFull();
  93. ShaderEnd();
  94. }
  95. }
  96. }
  97. /******************************************************************************/
  98. void FogDraw(C Ball &ball, Flt density, C Vec &color)
  99. {
  100. if(Frustum(ball) && Renderer.canReadDepth())
  101. {
  102. Sh.loadFogBallShaders();
  103. Renderer.needDepthRead();
  104. D .alpha(ALPHA_BLEND_DEC);
  105. Sh.h_LocalFogColor_Density->set(Vec4(color, Mid(density, 0.0f, MAX_DENSITY))); // avoid 1 in case "Pow(1-density, ..)" in shader would cause NaN or slow-downs
  106. Vec inside=CamMatrix.pos-ball.pos;
  107. Matrix temp;
  108. temp.pos=ball.pos;
  109. temp.x .set(ball.r, 0, 0);
  110. temp.y .set(0, ball.r, 0);
  111. temp.z .set(0, 0, ball.r);
  112. SetOneMatrix(temp);
  113. Flt e=Frustum.view_quad_max_dist,
  114. i=inside.length();
  115. if( i<=ball.r+e)
  116. {
  117. Sh.h_LocalFogInside->set(inside);
  118. if(i<=ball.r-e)Sh.h_FogBall1->draw(Renderer._ds_1s);
  119. else Sh.h_FogBall0->draw(Renderer._ds_1s);
  120. }else
  121. {
  122. D .depth (true );
  123. D .depthWrite(false);
  124. D .cull (true );
  125. Sh.h_FogBall->begin(); MshrBall.set().drawFull();
  126. ShaderEnd();
  127. }
  128. }
  129. }
  130. /******************************************************************************/
  131. void HeightFogDraw(C OBox &obox, Flt density, C Vec &color)
  132. {
  133. if(Frustum(obox) && Renderer.canReadDepth())
  134. {
  135. Sh.loadFogHgtShaders();
  136. Renderer.needDepthRead();
  137. D .alpha(ALPHA_BLEND_DEC);
  138. Sh.h_LocalFogColor_Density->set(Vec4(color, Mid(density, 0.0f, MAX_DENSITY))); // avoid 1 in case "Pow(1-density, ..)" in shader would cause NaN or slow-downs
  139. Vec delta=CamMatrix.pos-obox.center(), inside;
  140. inside.x=Dot(delta, obox.matrix.x);
  141. inside.y=Dot(delta, obox.matrix.y);
  142. inside.z=Dot(delta, obox.matrix.z);
  143. Vec size=obox.box.size()*0.5f;
  144. Matrix temp;
  145. temp.pos=obox.center();
  146. temp.x =obox.matrix.x*size.x;
  147. temp.y =obox.matrix.y*size.y;
  148. temp.z =obox.matrix.z*size.z;
  149. SetOneMatrix(temp);
  150. Flt e=Frustum.view_quad_max_dist;
  151. if(inside.x>=-size.x-e && inside.x<=size.x+e
  152. && inside.y>=-size.y-e && inside.y<=size.y+e
  153. && inside.z>=-size.z-e && inside.z<=size.z+e)
  154. {
  155. Sh.h_LocalFogInside->set(inside);
  156. if(inside.x>=-size.x+e && inside.x<=size.x-e
  157. && inside.y>=-size.y+e && inside.y<=size.y-e
  158. && inside.z>=-size.z+e && inside.z<=size.z-e)Sh.h_FogHgt1->draw(Renderer._ds_1s);
  159. else Sh.h_FogHgt0->draw(Renderer._ds_1s);
  160. }else
  161. {
  162. D .depth (true );
  163. D .depthWrite(false);
  164. D .cull (true );
  165. Sh.h_FogHgt->begin(); MshrBox.set().drawFull();
  166. ShaderEnd();
  167. }
  168. }
  169. }
  170. /******************************************************************************/
  171. }
  172. /******************************************************************************/