Water.hlsl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "Uniforms.hlsl"
  2. #include "Samplers.hlsl"
  3. #include "Transform.hlsl"
  4. #include "ScreenPos.hlsl"
  5. #include "Fog.hlsl"
  6. #ifndef D3D11
  7. // D3D9 uniforms
  8. uniform float2 cNoiseSpeed;
  9. uniform float cNoiseTiling;
  10. uniform float cNoiseStrength;
  11. uniform float cFresnelPower;
  12. uniform float3 cWaterTint;
  13. #else
  14. // D3D11 constant buffers
  15. #ifdef COMPILEVS
  16. cbuffer CustomVS : register(b6)
  17. {
  18. float2 cNoiseSpeed;
  19. float cNoiseTiling;
  20. }
  21. #else
  22. cbuffer CustomPS : register(b6)
  23. {
  24. float cNoiseStrength;
  25. float cFresnelPower;
  26. float3 cWaterTint;
  27. }
  28. #endif
  29. #endif
  30. void VS(float4 iPos : POSITION,
  31. float3 iNormal: NORMAL,
  32. float2 iTexCoord : TEXCOORD0,
  33. out float4 oScreenPos : TEXCOORD0,
  34. out float2 oReflectUV : TEXCOORD1,
  35. out float2 oWaterUV : TEXCOORD2,
  36. out float3 oNormal : TEXCOORD3,
  37. out float4 oEyeVec : TEXCOORD4,
  38. #if defined(D3D11) && defined(CLIPPLANE)
  39. out float oClip : SV_CLIPDISTANCE0,
  40. #endif
  41. out float4 oPos : OUTPOSITION)
  42. {
  43. float4x3 modelMatrix = iModelMatrix;
  44. float3 worldPos = GetWorldPos(modelMatrix);
  45. oPos = GetClipPos(worldPos);
  46. oScreenPos = GetScreenPos(oPos);
  47. // GetQuadTexCoord() returns a float2 that is OK for quad rendering; multiply it with output W
  48. // coordinate to make it work with arbitrary meshes such as the water plane (perform divide in pixel shader)
  49. oReflectUV = GetQuadTexCoord(oPos) * oPos.w;
  50. oWaterUV = iTexCoord * cNoiseTiling + cElapsedTime * cNoiseSpeed;
  51. oNormal = GetWorldNormal(modelMatrix);
  52. oEyeVec = float4(cCameraPos - worldPos, GetDepth(oPos));
  53. #if defined(D3D11) && defined(CLIPPLANE)
  54. oClip = dot(oPos, cClipPlane);
  55. #endif
  56. }
  57. void PS(
  58. float4 iScreenPos : TEXCOORD0,
  59. float2 iReflectUV : TEXCOORD1,
  60. float2 iWaterUV : TEXCOORD2,
  61. float3 iNormal : TEXCOORD3,
  62. float4 iEyeVec : TEXCOORD4,
  63. #if defined(D3D11) && defined(CLIPPLANE)
  64. float iClip : SV_CLIPDISTANCE0,
  65. #endif
  66. out float4 oColor : OUTCOLOR0)
  67. {
  68. float2 refractUV = iScreenPos.xy / iScreenPos.w;
  69. float2 reflectUV = iReflectUV.xy / iScreenPos.w;
  70. float2 noise = (Sample2D(NormalMap, iWaterUV).rg - 0.5) * cNoiseStrength;
  71. refractUV += noise;
  72. // Do not shift reflect UV coordinate upward, because it will reveal the clipping of geometry below water
  73. if (noise.y < 0.0)
  74. noise.y = 0.0;
  75. reflectUV += noise;
  76. float fresnel = pow(1.0 - saturate(dot(normalize(iEyeVec.xyz), iNormal)), cFresnelPower);
  77. float3 refractColor = Sample2D(EnvMap, refractUV).rgb * cWaterTint;
  78. float3 reflectColor = Sample2D(DiffMap, reflectUV).rgb;
  79. float3 finalColor = lerp(refractColor, reflectColor, fresnel);
  80. oColor = float4(GetFog(finalColor, GetFogFactor(iEyeVec.w)), 1.0);
  81. }