You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
7.7 KiB

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