Water.hlsl 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. #ifdef INSTANCED
  34. float4x3 iModelInstance : TEXCOORD4,
  35. #endif
  36. out float4 oScreenPos : TEXCOORD0,
  37. out float2 oReflectUV : TEXCOORD1,
  38. out float2 oWaterUV : TEXCOORD2,
  39. out float3 oNormal : TEXCOORD3,
  40. out float4 oEyeVec : TEXCOORD4,
  41. #if defined(D3D11) && defined(CLIPPLANE)
  42. out float oClip : SV_CLIPDISTANCE0,
  43. #endif
  44. out float4 oPos : OUTPOSITION)
  45. {
  46. float4x3 modelMatrix = iModelMatrix;
  47. float3 worldPos = GetWorldPos(modelMatrix);
  48. oPos = GetClipPos(worldPos);
  49. oScreenPos = GetScreenPos(oPos);
  50. // GetQuadTexCoord() returns a float2 that is OK for quad rendering; multiply it with output W
  51. // coordinate to make it work with arbitrary meshes such as the water plane (perform divide in pixel shader)
  52. oReflectUV = GetQuadTexCoord(oPos) * oPos.w;
  53. oWaterUV = iTexCoord * cNoiseTiling + cElapsedTime * cNoiseSpeed;
  54. oNormal = GetWorldNormal(modelMatrix);
  55. oEyeVec = float4(cCameraPos - worldPos, GetDepth(oPos));
  56. #if defined(D3D11) && defined(CLIPPLANE)
  57. oClip = dot(oPos, cClipPlane);
  58. #endif
  59. }
  60. void PS(
  61. float4 iScreenPos : TEXCOORD0,
  62. float2 iReflectUV : TEXCOORD1,
  63. float2 iWaterUV : TEXCOORD2,
  64. float3 iNormal : TEXCOORD3,
  65. float4 iEyeVec : TEXCOORD4,
  66. #if defined(D3D11) && defined(CLIPPLANE)
  67. float iClip : SV_CLIPDISTANCE0,
  68. #endif
  69. out float4 oColor : OUTCOLOR0)
  70. {
  71. float2 refractUV = iScreenPos.xy / iScreenPos.w;
  72. float2 reflectUV = iReflectUV.xy / iScreenPos.w;
  73. float2 noise = (Sample2D(NormalMap, iWaterUV).rg - 0.5) * cNoiseStrength;
  74. refractUV += noise;
  75. // Do not shift reflect UV coordinate upward, because it will reveal the clipping of geometry below water
  76. if (noise.y < 0.0)
  77. noise.y = 0.0;
  78. reflectUV += noise;
  79. float fresnel = pow(1.0 - saturate(dot(normalize(iEyeVec.xyz), iNormal)), cFresnelPower);
  80. float3 refractColor = Sample2D(EnvMap, refractUV).rgb * cWaterTint;
  81. float3 reflectColor = Sample2D(DiffMap, reflectUV).rgb;
  82. float3 finalColor = lerp(refractColor, reflectColor, fresnel);
  83. oColor = float4(GetFog(finalColor, GetFogFactor(iEyeVec.w)), 1.0);
  84. }