WaterInclude.cginc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #ifndef WATER_CG_INCLUDED
  2. #define WATER_CG_INCLUDED
  3. #include "UnityCG.cginc"
  4. half _GerstnerIntensity;
  5. inline half3 PerPixelNormal(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength)
  6. {
  7. half3 bump = (UnpackNormal(tex2D(bumpMap, coords.xy)) + UnpackNormal(tex2D(bumpMap, coords.zw))) * 0.5;
  8. half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1);
  9. return normalize(worldNormal);
  10. }
  11. inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength)
  12. {
  13. half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw);
  14. bump = bump * 0.5;
  15. half3 normal = UnpackNormal(bump);
  16. normal.xy *= bumpStrength;
  17. return normalize(normal);
  18. }
  19. inline half3 GetNormal(half4 tf) {
  20. #ifdef WATER_VERTEX_DISPLACEMENT_ON
  21. return half3(2,1,2) * tf.rbg - half3(1,0,1);
  22. #else
  23. return half3(0,1,0);
  24. #endif
  25. }
  26. inline half GetDistanceFadeout(half screenW, half speed) {
  27. return 1.0f / abs(0.5f + screenW * speed);
  28. }
  29. half4 GetDisplacement3(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB, sampler2D mapC)
  30. {
  31. half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed;
  32. #ifdef WATER_VERTEX_DISPLACEMENT_ON
  33. half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0));
  34. tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0));
  35. tf += tex2Dlod(mapC, half4(displacementUv.xw, 0.0,0.0));
  36. tf *= 0.333333;
  37. #else
  38. half4 tf = half4(0.5,0.5,0.5,0.0);
  39. #endif
  40. return tf;
  41. }
  42. half4 GetDisplacement2(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB)
  43. {
  44. half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed;
  45. #ifdef WATER_VERTEX_DISPLACEMENT_ON
  46. half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0));
  47. tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0));
  48. tf *= 0.5;
  49. #else
  50. half4 tf = half4(0.5,0.5,0.5,0.0);
  51. #endif
  52. return tf;
  53. }
  54. inline void ComputeScreenAndGrabPassPos (float4 pos, out float4 screenPos, out float4 grabPassPos)
  55. {
  56. #if UNITY_UV_STARTS_AT_TOP
  57. float scale = -1.0;
  58. #else
  59. float scale = 1.0f;
  60. #endif
  61. screenPos = ComputeNonStereoScreenPos(pos);
  62. grabPassPos.xy = ( float2( pos.x, pos.y*scale ) + pos.w ) * 0.5;
  63. grabPassPos.zw = pos.zw;
  64. }
  65. inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength, half2 perVertxOffset)
  66. {
  67. half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw);
  68. bump = bump * 0.5;
  69. half3 normal = UnpackNormal(bump);
  70. normal.xy *= bumpStrength;
  71. normal.xy += perVertxOffset;
  72. return normalize(normal);
  73. }
  74. inline half3 PerPixelNormalLite(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength)
  75. {
  76. half4 bump = tex2D(bumpMap, coords.xy);
  77. bump.xy = bump.wy - half2(0.5, 0.5);
  78. half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1);
  79. return normalize(worldNormal);
  80. }
  81. inline half4 Foam(sampler2D shoreTex, half4 coords, half amount)
  82. {
  83. half4 foam = ( tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw) ) - 0.125;
  84. foam.a = amount;
  85. return foam;
  86. }
  87. inline half4 Foam(sampler2D shoreTex, half4 coords)
  88. {
  89. half4 foam = (tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw)) - 0.125;
  90. return foam;
  91. }
  92. inline half Fresnel(half3 viewVector, half3 worldNormal, half bias, half power)
  93. {
  94. half facing = clamp(1.0-max(dot(-viewVector, worldNormal), 0.0), 0.0,1.0);
  95. half refl2Refr = saturate(bias+(1.0-bias) * pow(facing,power));
  96. return refl2Refr;
  97. }
  98. inline half FresnelViaTexture(half3 viewVector, half3 worldNormal, sampler2D fresnel)
  99. {
  100. half facing = saturate(dot(-viewVector, worldNormal));
  101. half fresn = tex2D(fresnel, half2(facing, 0.5f)).b;
  102. return fresn;
  103. }
  104. inline void VertexDisplacementHQ( sampler2D mapA, sampler2D mapB,
  105. sampler2D mapC, half4 uv,
  106. half vertexStrength, half3 normal,
  107. out half4 vertexOffset, out half2 normalOffset)
  108. {
  109. half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0));
  110. tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0));
  111. tf += tex2Dlod(mapC, half4(uv.xw, 0.0,0.0));
  112. tf /= 3.0;
  113. tf.rga = tf.rga-half3(0.5,0.5,0.0);
  114. // height displacement in alpha channel, normals info in rgb
  115. vertexOffset = tf.a * half4(normal.xyz, 0.0) * vertexStrength;
  116. normalOffset = tf.rg;
  117. }
  118. inline void VertexDisplacementLQ( sampler2D mapA, sampler2D mapB,
  119. sampler2D mapC, half4 uv,
  120. half vertexStrength, half normalsStrength,
  121. out half4 vertexOffset, out half2 normalOffset)
  122. {
  123. // @NOTE: for best performance, this should really be properly packed!
  124. half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0));
  125. tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0));
  126. tf *= 0.5;
  127. tf.rga = tf.rga-half3(0.5,0.5,0.0);
  128. // height displacement in alpha channel, normals info in rgb
  129. vertexOffset = tf.a * half4(0,1,0,0) * vertexStrength;
  130. normalOffset = tf.rg * normalsStrength;
  131. }
  132. half4 ExtinctColor (half4 baseColor, half extinctionAmount)
  133. {
  134. // tweak the extinction coefficient for different coloring
  135. return baseColor - extinctionAmount * half4(0.15, 0.03, 0.01, 0.0);
  136. }
  137. half3 GerstnerOffsets (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir)
  138. {
  139. half3 offsets;
  140. offsets.x =
  141. steepness * amp * dir.x *
  142. cos( freq * dot( dir, xzVtx ) + speed * _Time.x);
  143. offsets.z =
  144. steepness * amp * dir.y *
  145. cos( freq * dot( dir, xzVtx ) + speed * _Time.x);
  146. offsets.y =
  147. amp * sin ( freq * dot( dir, xzVtx ) + speed * _Time.x);
  148. return offsets;
  149. }
  150. half3 GerstnerOffset4 (half2 xzVtx, half4 steepness, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD)
  151. {
  152. half3 offsets;
  153. half4 AB = steepness.xxyy * amp.xxyy * dirAB.xyzw;
  154. half4 CD = steepness.zzww * amp.zzww * dirCD.xyzw;
  155. half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx));
  156. half4 TIME = _Time.yyyy * speed;
  157. half4 COS = cos (dotABCD + TIME);
  158. half4 SIN = sin (dotABCD + TIME);
  159. offsets.x = dot(COS, half4(AB.xz, CD.xz));
  160. offsets.z = dot(COS, half4(AB.yw, CD.yw));
  161. offsets.y = dot(SIN, amp);
  162. return offsets;
  163. }
  164. half3 GerstnerNormal (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir)
  165. {
  166. half3 nrml = half3(0,0,0);
  167. nrml.x -=
  168. dir.x * (amp * freq) *
  169. cos(freq * dot( dir, xzVtx ) + speed * _Time.x);
  170. nrml.z -=
  171. dir.y * (amp * freq) *
  172. cos(freq * dot( dir, xzVtx ) + speed * _Time.x);
  173. return nrml;
  174. }
  175. half3 GerstnerNormal4 (half2 xzVtx, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD)
  176. {
  177. half3 nrml = half3(0,2.0,0);
  178. half4 AB = freq.xxyy * amp.xxyy * dirAB.xyzw;
  179. half4 CD = freq.zzww * amp.zzww * dirCD.xyzw;
  180. half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx));
  181. half4 TIME = _Time.yyyy * speed;
  182. half4 COS = cos (dotABCD + TIME);
  183. nrml.x -= dot(COS, half4(AB.xz, CD.xz));
  184. nrml.z -= dot(COS, half4(AB.yw, CD.yw));
  185. nrml.xz *= _GerstnerIntensity;
  186. nrml = normalize (nrml);
  187. return nrml;
  188. }
  189. void Gerstner ( out half3 offs, out half3 nrml,
  190. half3 vtx, half3 tileableVtx,
  191. half4 amplitude, half4 frequency, half4 steepness,
  192. half4 speed, half4 directionAB, half4 directionCD )
  193. {
  194. #ifdef WATER_VERTEX_DISPLACEMENT_ON
  195. offs = GerstnerOffset4(tileableVtx.xz, steepness, amplitude, frequency, speed, directionAB, directionCD);
  196. nrml = GerstnerNormal4(tileableVtx.xz + offs.xz, amplitude, frequency, speed, directionAB, directionCD);
  197. #else
  198. offs = half3(0,0,0);
  199. nrml = half3(0,1,0);
  200. #endif
  201. }
  202. #endif