Water.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /******************************************************************************/
  2. #include "!Header.h"
  3. #include "Ambient Occlusion.h"
  4. #include "Water.h"
  5. /******************************************************************************/
  6. #define DEFAULT_DEPTH 1.0f
  7. /******************************************************************************/
  8. void Surface_VS
  9. (
  10. VtxInput vtx,
  11. out Vec outPos :TEXCOORD0,
  12. out Vec2 outTex :TEXCOORD1,
  13. out Vec4 outTexN0:TEXCOORD2,
  14. out Vec4 outTexN1:TEXCOORD3,
  15. out Vec4 outTexB :TEXCOORD4,
  16. out Flt outPDF :TEXCOORD5,
  17. out Vec4 outVtx :POSITION ,
  18. uniform Bool waves,
  19. uniform Bool river,
  20. uniform Bool light=false
  21. )
  22. {
  23. Vec pos=vtx.pos();
  24. if(waves)
  25. {
  26. pos.y=pos.y*WaterYMulAdd.x + WaterYMulAdd.y;
  27. Vec dir =Normalize(Vec(FracToPosXY(pos.xy), 1));
  28. Flt dist=-DistPointPlaneRay(Vec(0, 0, 0), WaterPlnPos, WaterPlnNrm, dir);
  29. if( dist>0)
  30. {
  31. pos=dir*dist;
  32. }else
  33. {
  34. pos=PointOnPlane(dir*Viewport.range, WaterPlnPos, WaterPlnNrm);
  35. }
  36. outPos=pos;
  37. pos =Transform(pos, CamMatrix);
  38. }
  39. if(river)
  40. {
  41. Vec2 tex=vtx.tex(); tex.y-=WaterFlow;
  42. outTex =( tex )/WaterScaleDif + WaterOfs ;
  43. outTexN0.xy=( tex )/WaterScaleNrm + WaterOfs ;
  44. outTexN0.zw=(-tex )/WaterScaleNrm + WaterOfs ;
  45. outTexN1.xy=( tex/8)/WaterScaleNrm + Perp(WaterOfs);
  46. outTexN1.zw=(-tex/8)/WaterScaleNrm + Perp(WaterOfs);
  47. outTexB .xy=( tex )/WaterScaleBump + WaterOfs ;
  48. outTexB .zw=(-tex )/WaterScaleBump + WaterOfs ;
  49. }else
  50. {
  51. outTex =( pos.xz )/WaterScaleDif + WaterOfs ;
  52. outTexN0.xy=( pos.xz )/WaterScaleNrm + WaterOfs ;
  53. outTexN0.zw=(-pos.xz )/WaterScaleNrm + WaterOfs ;
  54. outTexN1.xy=( pos.xz/8)/WaterScaleNrm + Perp(WaterOfs);
  55. outTexN1.zw=(-pos.xz/8)/WaterScaleNrm + Perp(WaterOfs);
  56. outTexB .xy=( pos.xz )/WaterScaleBump + WaterOfs ;
  57. outTexB .zw=(-pos.xz )/WaterScaleBump + WaterOfs ;
  58. }
  59. if(waves)
  60. {
  61. Flt dist_scale=LerpRS(Sqr(150.0f), Sqr(100.0f), Length2(outPos)),
  62. #if DX9
  63. bump =Dot(TexLod(Nrm1, outTexB.xy)+TexLod(Nrm1, outTexB.zw), WaterBumpDot);
  64. #else
  65. bump =TexLod(Col, outTexB.xy).a+TexLod(Col, outTexB.zw).a;
  66. #endif
  67. bump =bump-1; // Avg(a,b)*2-1 = (a+b)-1
  68. outPos +=(WaterPlnNrm*WaterWave)*bump*dist_scale;
  69. }else
  70. {
  71. outPos=TransformPos(pos);
  72. }
  73. if(light)outPDF=2-Abs(DistPointPlane(outPos, WaterPlnPos, WaterPlnNrm)); // plane distance factor, must be = 1 for dist=0..1 (wave scale)
  74. outVtx=Project(outPos);
  75. }
  76. /******************************************************************************/
  77. void Surface_PS
  78. (
  79. Vec inPos :TEXCOORD0,
  80. Vec2 inTex :TEXCOORD1,
  81. Vec4 inTexN0:TEXCOORD2,
  82. Vec4 inTexN1:TEXCOORD3,
  83. Vec4 inTexB :TEXCOORD4,
  84. Flt inPDF :TEXCOORD5,
  85. PIXEL,
  86. out Vec4 O_col:COLOR0,
  87. out Vec4 O_nrm:COLOR1,
  88. uniform Bool waves ,
  89. uniform Bool river ,
  90. uniform Bool light ,
  91. uniform Bool fake_reflection=false,
  92. uniform Int shadow =0 ,
  93. uniform Bool soft =false
  94. )
  95. {
  96. Vec nrm; // #MaterialTextureChannelOrder
  97. nrm.xy =(Tex(Nrm, inTexN0.xy).xy - Tex(Nrm, inTexN0.zw).xy + Tex(Nrm, inTexN1.xy).xy - Tex(Nrm, inTexN1.zw).xy)*WaterRgh_2; // (Avg(Tex(Nrm, inTexN0.xy).xy, 1-Tex(Nrm, inTexN0.zw).xy, Tex(Nrm, inTexN1.xy).xy, 1-Tex(Nrm, inTexN1.zw).xy)*2-1)*WaterRgh
  98. if(waves)nrm.xy+=(Tex(Nrm, inTexB .xy).xy - Tex(Nrm, inTexB .zw).xy )*WaterWave ; // (Avg(Tex(Nrm, inTexB .xy).xy, 1-Tex(Nrm, inTexB .zw).xy )*2-1)*WaterWave
  99. nrm.z =CalcZ(nrm.xy);
  100. Matrix3 mtrx;
  101. mtrx[0]=MatrixX(ViewMatrix[0]);
  102. mtrx[1]=MatrixZ(ViewMatrix[0]);
  103. mtrx[2]=MatrixY(ViewMatrix[0]);
  104. Vec fresnel_nrm =nrm;
  105. fresnel_nrm.xy*=WaterFresnelRough;
  106. fresnel_nrm.z =CalcZ(fresnel_nrm.xy);
  107. fresnel_nrm =Transform(fresnel_nrm, mtrx); // convert to view space
  108. Vec view_nrm =Transform(nrm , mtrx); // convert to view space
  109. Vec view=Normalize(inPos);
  110. Vec4 col=Vec4(WaterCol*Tex(Col, inTex).rgb, 0);
  111. {
  112. if(fake_reflection) // add fake reflection
  113. {
  114. col.rgb+=TexCube(Rfl, Transform3(reflect(view, view_nrm), CamMatrix)).rgb*WaterRflFake;
  115. }
  116. // fresnel
  117. {
  118. Flt dot_prod=Sat(-Dot(view, fresnel_nrm)),
  119. fresnel =Pow(1-dot_prod, WaterFresnelPow);
  120. col.rgb+=fresnel*WaterFresnelColor;
  121. }
  122. }
  123. col.rgb=Sat(col.rgb);
  124. if(!light)
  125. {
  126. O_col=col; // in O_col.w you can encode: reflection, refraction, glow
  127. #if SIGNED_NRM_RT
  128. O_nrm.xyz=view_nrm;
  129. #else
  130. O_nrm.xyz=view_nrm*0.5f+0.5f; // -1..1 -> 0..1
  131. #endif
  132. #if SIGNED_NRM_RT && FULL_PRECISION_SPEC
  133. O_nrm.w=WaterSpc*2-1; // 0..1 -> -1..1
  134. #else
  135. O_nrm.w=WaterSpc;
  136. #endif
  137. }else
  138. {
  139. inTex =PIXEL_TO_SCREEN;
  140. Flt water_z=inPos.z,
  141. solid_z=(soft ? LinearizeDepth(TexPoint(Det, inTex).x) : water_z+DEFAULT_DEPTH), alpha=0;
  142. Vec2 col_tex=inTex;
  143. Vec4 water_col=col;
  144. Vec2 refract=nrm.xy*Viewport.size;
  145. Flt dz =(soft ? solid_z-water_z : DEFAULT_DEPTH);
  146. alpha=Sat(AccumulatedDensity(WaterDns.x, dz) + WaterDns.y)*Sat(dz/0.03f);
  147. Vec2 test_tex=Mid(col_tex+refract*WaterRfr*alpha/Max(1, water_z), WaterClamp.xy, WaterClamp.zw);
  148. if(soft)
  149. {
  150. Flt test_z=LinearizeDepth(TexLodClamp(Det, test_tex).x); // use linear filtering because texcoords are not rounded
  151. if( test_z>water_z)
  152. {
  153. solid_z=test_z;
  154. col_tex=test_tex;
  155. }
  156. dz =solid_z-water_z;
  157. alpha=Sat(AccumulatedDensity(WaterDns.x, dz) + WaterDns.y)*Sat(dz/0.03f);
  158. }else
  159. {
  160. col_tex=test_tex;
  161. }
  162. if(soft)if(solid_z>=Viewport.range*0.96f)alpha=1; // always force full opacity when there's no solid pixel set to avoid remains in the RenderTarget from previous usage
  163. // light
  164. Vec4 lum;
  165. {
  166. // shadow
  167. Flt shd; if(shadow)shd=Sat(ShadowDirValue(inPos, ShadowJitter(pixel.xy), true, shadow, false));
  168. // diffuse
  169. Flt diffuse=LightDiffuse(view_nrm, Light_dir.dir); if(shadow)diffuse*=shd;
  170. // specular
  171. Flt specular=LightSpecular(view_nrm, WaterSpc, Light_dir.dir, -view); if(shadow)specular*=shd;
  172. lum=Vec4(Light_dir.color.rgb*diffuse, Light_dir.color.a*specular);
  173. }
  174. // col light
  175. water_col.rgb*=lum.rgb+AmbColor;
  176. // reflection
  177. Flt rfl=WaterRfl*Sat(inPDF);
  178. inTex=Mid ((inTex+refract*WaterRfrRfl)*WaterRflMulAdd.xy+WaterRflMulAdd.zw, WaterClamp.xy, WaterClamp.zw);
  179. water_col=Lerp(water_col, TexLodClamp(Col1, inTex), rfl); // use LOD to avoid anisotropic going out of clamp region
  180. // glow and specular
  181. water_col.a +=lum.w* 0.5f; // glow
  182. water_col.rgb+=lum.w*lum.w*0.5f; // specular
  183. if(soft)
  184. {
  185. Vec4 solid_col=TexLodClamp(Col2, col_tex);
  186. O_col=Lerp(solid_col, water_col, alpha);
  187. }else
  188. {
  189. O_col=water_col;
  190. }
  191. }
  192. }
  193. /******************************************************************************/
  194. Vec4 Apply_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  195. NOPERSP Vec2 inPosXY:TEXCOORD1,
  196. out Flt depth :DEPTH ,
  197. uniform Bool refract ,
  198. uniform Bool set_depth=false ):COLOR
  199. {
  200. Flt water_z=TexPoint (Det, inTex).x,
  201. solid_z=TexDepthRawPoint( inTex), alpha=0;
  202. if(set_depth)depth=water_z;
  203. if(refract)
  204. {
  205. Vec2 col_tex=inTex;
  206. Vec4 water_col=0;
  207. #if FLOW
  208. BRANCH if(DEPTH_SMALLER(water_z, solid_z)) // branch works faster when most of the screen is above water
  209. #endif
  210. {
  211. water_z=LinearizeDepth(water_z);
  212. solid_z=LinearizeDepth(solid_z);
  213. water_col=TexLod(Col3, inTex);
  214. Vec4 lum=TexLod(Lum , inTex); // water surface light
  215. VecH nrm=GetNormal(inTex, false).xyz; // water surface normals
  216. Matrix3 mtrx;
  217. mtrx[0]=MatrixX(ViewMatrix[0]);
  218. mtrx[1]=MatrixZ(ViewMatrix[0]);
  219. mtrx[2]=MatrixY(ViewMatrix[0]);
  220. nrm=mul(mtrx, nrm);
  221. Vec2 refract=nrm.xy*Viewport.size;
  222. Flt dz =solid_z-water_z;
  223. alpha=Sat(AccumulatedDensity(WaterDns.x, dz) + WaterDns.y)*Sat(dz/0.03f);
  224. Vec2 test_tex=Mid(col_tex+refract*WaterRfr*alpha/Max(1, water_z), WaterClamp.xy, WaterClamp.zw);
  225. Flt test_z =TexDepthLinear(test_tex); // use linear filtering because texcoords are not rounded
  226. if( test_z >water_z)
  227. {
  228. solid_z=test_z;
  229. col_tex=test_tex;
  230. }
  231. dz =solid_z-water_z;
  232. alpha=Sat(AccumulatedDensity(WaterDns.x, dz) + WaterDns.y)*Sat(dz/0.03f);
  233. // col light
  234. water_col.rgb*=lum.rgb;
  235. // reflection
  236. Vec pos=Vec(inPosXY*water_z, water_z);
  237. Flt pdf=Sat(2-Abs(DistPointPlane(pos, WaterPlnPos, WaterPlnNrm))), // plane distance factor, must be = 1 for dist=0..1 (wave scale)
  238. rfl=WaterRfl*pdf;
  239. inTex=Mid ((inTex+refract*WaterRfrRfl)*WaterRflMulAdd.xy+WaterRflMulAdd.zw, WaterClamp.xy, WaterClamp.zw);
  240. water_col=Lerp(water_col, TexLodClamp(Col1, inTex), rfl); // use LOD to avoid anisotropic going out of clamp region
  241. // glow and specular
  242. water_col.rgb+=lum.w*lum.w*0.5f; // specular
  243. water_col.a +=lum.w* 0.5f; // glow
  244. }
  245. Vec4 solid_col=TexClamp(Col2, col_tex);
  246. return Lerp(solid_col, water_col, alpha);
  247. }else
  248. {
  249. Vec4 solid_col=TexLod(Col2, inTex);
  250. #if FLOW
  251. BRANCH if(DEPTH_SMALLER(water_z, solid_z)) // branch works faster when most of the screen is above water
  252. #endif
  253. {
  254. water_z=LinearizeDepth(water_z);
  255. solid_z=LinearizeDepth(solid_z);
  256. Flt dz =solid_z-water_z;
  257. alpha=Sat(AccumulatedDensity(WaterDns.x, dz) + WaterDns.y)*Sat(dz/0.03f);
  258. Vec4 water_col=TexLod(Col3, inTex),
  259. lum=TexLod(Lum , inTex); // water surface light
  260. VecH nrm=GetNormal(inTex, false).xyz; // water surface normals
  261. Matrix3 mtrx;
  262. mtrx[0]=MatrixX(ViewMatrix[0]);
  263. mtrx[1]=MatrixZ(ViewMatrix[0]);
  264. mtrx[2]=MatrixY(ViewMatrix[0]);
  265. nrm=mul(mtrx, nrm);
  266. Vec2 refract=nrm.xy*Viewport.size;
  267. // col light
  268. water_col.rgb*=lum.rgb;
  269. // reflection
  270. Vec pos=Vec(inPosXY*water_z, water_z);
  271. Flt pdf=Sat(2-Abs(DistPointPlane(pos, WaterPlnPos, WaterPlnNrm))), // plane distance factor, needs to be = 1 for dist=0..1 (wave scale)
  272. rfl=WaterRfl*pdf;
  273. inTex=Mid ((inTex+refract*WaterRfrRfl)*WaterRflMulAdd.xy+WaterRflMulAdd.zw, WaterClamp.xy, WaterClamp.zw);
  274. water_col=Lerp(water_col, TexLod(Col1, inTex), rfl);
  275. // glow and specular
  276. water_col.rgb+=lum.w*lum.w*0.5f; // specular
  277. water_col.a +=lum.w* 0.5f; // glow
  278. solid_col=Lerp(solid_col, water_col, alpha);
  279. }
  280. return solid_col;
  281. }
  282. }
  283. /******************************************************************************/
  284. Vec4 Under_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  285. NOPERSP Vec2 inPosXY:TEXCOORD1,
  286. uniform Bool refract ):COLOR
  287. {
  288. // underwater refraction
  289. if(refract)
  290. {
  291. Flt dist =Viewport.range;
  292. Flt to_surface=-DistPointPlaneRay(Vec(0, 0, 0), WaterPlnPos, WaterPlnNrm, Normalize(Vec(inPosXY, 1)));
  293. if( to_surface>0)dist=Min(to_surface, dist);
  294. Flt refract=Sat(AccumulatedDensity(WaterDns.x, dist)+WaterDns.y)*WaterUnderRfr;
  295. #if 1 // viewport size adjusted
  296. inTex+=Sin(inTex.yx*14/Viewport.size+Half(Step))*refract*Viewport.size; // add refraction
  297. inTex =(inTex-Viewport.center)/(1+2*refract)+Viewport.center; // scale texture coordinates to avoid clamping
  298. #else
  299. inTex+=Sin(inTex.yx*14+Half(Step))*refract; // add refraction
  300. inTex =(inTex-0.5f)/(1+2*refract)+0.5f; // scale texture coordinates to avoid clamping
  301. #endif
  302. }
  303. Vec pos =(refract ? GetPosLinear(inTex) : GetPosPoint(inTex, inPosXY));
  304. Flt dist =Length(pos);
  305. Vec ray =pos/dist; // Normalize(pos); should be no NaN because pos.z should be always >0
  306. Flt to_surface=-DistPointPlaneRay(Vec(0, 0, 0), WaterPlnPos, WaterPlnNrm, ray);
  307. if( to_surface>0)dist=Min(to_surface, dist);
  308. Flt opacity=Sat(AccumulatedDensity(WaterDns.x, dist)+WaterDns.y)*WaterUnder;
  309. Flt depth_0=-DistPointPlane(Vec(0, 0, 0), WaterPlnPos, WaterPlnNrm),
  310. depth_1=-DistPointPlane(ray*dist , WaterPlnPos, WaterPlnNrm);
  311. Flt water_density;
  312. /* Proper function:
  313. {
  314. water_density=0;
  315. Int steps =Mid(dist, 1, 255);
  316. Flt opacity =1,
  317. total_opacity=0;
  318. LOOP for(Int i=0; i<steps; i++)
  319. {
  320. Flt depth=Lerp(depth_0, depth_1, i/Flt(steps-1));
  321. Flt d =AccumulatedDensity(WaterDns.x, depth);
  322. opacity *=1-WaterDns.x;
  323. water_density+=opacity*d;
  324. total_opacity+=opacity;
  325. }
  326. water_density/=total_opacity;
  327. }
  328. if(BOOL)
  329. /**/
  330. // approximation:
  331. {
  332. Flt density_0=AccumulatedDensity(WaterDns.x, depth_0),
  333. density_1=AccumulatedDensity(WaterDns.x, depth_1),
  334. blend =0.5f/(1+dist*(WaterDns.x/3));
  335. water_density=Lerp(density_0, density_1, blend);
  336. }
  337. Vec water_col=Lerp(WaterUnderCol0, WaterUnderCol1, water_density);
  338. return refract ? Lerp(TexLod(Col, inTex), Vec4(water_col, 0), opacity)
  339. : Vec4(water_col , opacity);
  340. }
  341. /******************************************************************************/
  342. TECHNIQUE(Apply , DrawPosXY_VS(), Apply_PS(false));
  343. TECHNIQUE(ApplyR, DrawPosXY_VS(), Apply_PS(true ));
  344. #if DX11
  345. TECHNIQUE(ApplyD , DrawPosXY_VS(), Apply_PS(false, true));
  346. TECHNIQUE(ApplyRD, DrawPosXY_VS(), Apply_PS(true , true));
  347. #endif
  348. TECHNIQUE(Under , DrawPosXY_VS(), Under_PS(false));
  349. TECHNIQUE(UnderR, DrawPosXY_VS(), Under_PS(true ));
  350. TECHNIQUE(River , Surface_VS(false, true ), Surface_PS(false, true , false, false));
  351. TECHNIQUE(RiverF, Surface_VS(false, true ), Surface_PS(false, true , false, true ));
  352. TECHNIQUE(Lake , Surface_VS(false, false), Surface_PS(false, false, false, false));
  353. TECHNIQUE(LakeF , Surface_VS(false, false), Surface_PS(false, false, false, true ));
  354. TECHNIQUE(Ocean , Surface_VS(true , false), Surface_PS(true , false, false, false));
  355. TECHNIQUE(OceanF, Surface_VS(true , false), Surface_PS(true , false, false, true ));
  356. TECHNIQUE(RiverL0 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 0, false));
  357. TECHNIQUE(RiverL0F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 0, false));
  358. TECHNIQUE(RiverL1 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 1, false));
  359. TECHNIQUE(RiverL1F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 1, false));
  360. TECHNIQUE(RiverL2 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 2, false));
  361. TECHNIQUE(RiverL2F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 2, false));
  362. TECHNIQUE(RiverL3 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 3, false));
  363. TECHNIQUE(RiverL3F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 3, false));
  364. TECHNIQUE(RiverL4 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 4, false));
  365. TECHNIQUE(RiverL4F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 4, false));
  366. TECHNIQUE(RiverL5 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 5, false));
  367. TECHNIQUE(RiverL5F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 5, false));
  368. TECHNIQUE(RiverL6 , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 6, false));
  369. TECHNIQUE(RiverL6F , Surface_VS(false, true , true), Surface_PS(false, true , true, true , 6, false));
  370. TECHNIQUE(RiverL0S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 0, true ));
  371. TECHNIQUE(RiverL0SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 0, true ));
  372. TECHNIQUE(RiverL1S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 1, true ));
  373. TECHNIQUE(RiverL1SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 1, true ));
  374. TECHNIQUE(RiverL2S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 2, true ));
  375. TECHNIQUE(RiverL2SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 2, true ));
  376. TECHNIQUE(RiverL3S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 3, true ));
  377. TECHNIQUE(RiverL3SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 3, true ));
  378. TECHNIQUE(RiverL4S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 4, true ));
  379. TECHNIQUE(RiverL4SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 4, true ));
  380. TECHNIQUE(RiverL5S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 5, true ));
  381. TECHNIQUE(RiverL5SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 5, true ));
  382. TECHNIQUE(RiverL6S , Surface_VS(false, true , true), Surface_PS(false, true , true, false, 6, true ));
  383. TECHNIQUE(RiverL6SF, Surface_VS(false, true , true), Surface_PS(false, true , true, true , 6, true ));
  384. TECHNIQUE(LakeL0 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 0, false));
  385. TECHNIQUE(LakeL0F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 0, false));
  386. TECHNIQUE(LakeL1 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 1, false));
  387. TECHNIQUE(LakeL1F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 1, false));
  388. TECHNIQUE(LakeL2 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 2, false));
  389. TECHNIQUE(LakeL2F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 2, false));
  390. TECHNIQUE(LakeL3 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 3, false));
  391. TECHNIQUE(LakeL3F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 3, false));
  392. TECHNIQUE(LakeL4 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 4, false));
  393. TECHNIQUE(LakeL4F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 4, false));
  394. TECHNIQUE(LakeL5 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 5, false));
  395. TECHNIQUE(LakeL5F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 5, false));
  396. TECHNIQUE(LakeL6 , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 6, false));
  397. TECHNIQUE(LakeL6F , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 6, false));
  398. TECHNIQUE(LakeL0S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 0, true ));
  399. TECHNIQUE(LakeL0SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 0, true ));
  400. TECHNIQUE(LakeL1S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 1, true ));
  401. TECHNIQUE(LakeL1SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 1, true ));
  402. TECHNIQUE(LakeL2S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 2, true ));
  403. TECHNIQUE(LakeL2SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 2, true ));
  404. TECHNIQUE(LakeL3S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 3, true ));
  405. TECHNIQUE(LakeL3SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 3, true ));
  406. TECHNIQUE(LakeL4S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 4, true ));
  407. TECHNIQUE(LakeL4SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 4, true ));
  408. TECHNIQUE(LakeL5S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 5, true ));
  409. TECHNIQUE(LakeL5SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 5, true ));
  410. TECHNIQUE(LakeL6S , Surface_VS(false, false, true), Surface_PS(false, false, true, false, 6, true ));
  411. TECHNIQUE(LakeL6SF , Surface_VS(false, false, true), Surface_PS(false, false, true, true , 6, true ));
  412. TECHNIQUE(OceanL0 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 0, false));
  413. TECHNIQUE(OceanL0F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 0, false));
  414. TECHNIQUE(OceanL1 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 1, false));
  415. TECHNIQUE(OceanL1F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 1, false));
  416. TECHNIQUE(OceanL2 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 2, false));
  417. TECHNIQUE(OceanL2F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 2, false));
  418. TECHNIQUE(OceanL3 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 3, false));
  419. TECHNIQUE(OceanL3F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 3, false));
  420. TECHNIQUE(OceanL4 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 4, false));
  421. TECHNIQUE(OceanL4F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 4, false));
  422. TECHNIQUE(OceanL5 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 5, false));
  423. TECHNIQUE(OceanL5F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 5, false));
  424. TECHNIQUE(OceanL6 , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 6, false));
  425. TECHNIQUE(OceanL6F , Surface_VS(true , false, true), Surface_PS(true , false, true, true , 6, false));
  426. TECHNIQUE(OceanL0S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 0, true ));
  427. TECHNIQUE(OceanL0SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 0, true ));
  428. TECHNIQUE(OceanL1S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 1, true ));
  429. TECHNIQUE(OceanL1SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 1, true ));
  430. TECHNIQUE(OceanL2S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 2, true ));
  431. TECHNIQUE(OceanL2SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 2, true ));
  432. TECHNIQUE(OceanL3S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 3, true ));
  433. TECHNIQUE(OceanL3SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 3, true ));
  434. TECHNIQUE(OceanL4S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 4, true ));
  435. TECHNIQUE(OceanL4SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 4, true ));
  436. TECHNIQUE(OceanL5S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 5, true ));
  437. TECHNIQUE(OceanL5SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 5, true ));
  438. TECHNIQUE(OceanL6S , Surface_VS(true , false, true), Surface_PS(true , false, true, false, 6, true ));
  439. TECHNIQUE(OceanL6SF, Surface_VS(true , false, true), Surface_PS(true , false, true, true , 6, true ));
  440. /******************************************************************************/