Water.hlsl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "Uniforms.hlsl"
  2. #include "Samplers.hlsl"
  3. #include "Transform.hlsl"
  4. #include "ScreenPos.hlsl"
  5. #include "Fog.hlsl"
  6. uniform float2 cNoiseSpeed;
  7. uniform float cNoiseTiling;
  8. uniform float cNoiseStrength;
  9. uniform float cFresnelPower;
  10. uniform float3 cWaterTint;
  11. void VS(float4 iPos : POSITION,
  12. float3 iNormal: NORMAL,
  13. float2 iTexCoord : TEXCOORD0,
  14. out float4 oScreenPos : TEXCOORD0,
  15. out float2 oReflectUV : TEXCOORD1,
  16. out float2 oWaterUV : TEXCOORD2,
  17. out float3 oNormal : TEXCOORD3,
  18. out float4 oEyeVec : TEXCOORD4,
  19. out float4 oPos : POSITION)
  20. {
  21. float4x3 modelMatrix = iModelMatrix;
  22. float3 worldPos = GetWorldPos(modelMatrix);
  23. oPos = GetClipPos(worldPos);
  24. oScreenPos = GetScreenPos(oPos);
  25. // GetQuadTexCoord() returns a float2 that is OK for quad rendering; multiply it with output W
  26. // coordinate to make it work with arbitrary meshes such as the water plane (perform divide in pixel shader)
  27. oReflectUV = GetQuadTexCoord(oPos) * oPos.w;
  28. oWaterUV = iTexCoord * cNoiseTiling + cElapsedTime * cNoiseSpeed;
  29. oNormal = GetWorldNormal(modelMatrix);
  30. oEyeVec = float4(cCameraPos - worldPos, GetDepth(oPos));
  31. }
  32. void PS(
  33. float4 iScreenPos : TEXCOORD0,
  34. float2 iReflectUV : TEXCOORD1,
  35. float2 iWaterUV : TEXCOORD2,
  36. float3 iNormal : TEXCOORD3,
  37. float4 iEyeVec : TEXCOORD4,
  38. out float4 oColor : COLOR0)
  39. {
  40. float2 refractUV = iScreenPos.xy / iScreenPos.w;
  41. float2 reflectUV = iReflectUV.xy / iScreenPos.w;
  42. float2 noise = (tex2D(sNormalMap, iWaterUV).rg - 0.5) * cNoiseStrength;
  43. refractUV += noise;
  44. // Do not shift reflect UV coordinate upward, because it will reveal the clipping of geometry below water
  45. if (noise.y < 0.0)
  46. noise.y = 0.0;
  47. reflectUV += noise;
  48. float fresnel = pow(1.0 - saturate(dot(normalize(iEyeVec.xyz), iNormal)), cFresnelPower);
  49. float3 refractColor = tex2D(sEnvMap, refractUV).rgb * cWaterTint;
  50. float3 reflectColor = tex2D(sDiffMap, reflectUV).rgb;
  51. float3 finalColor = lerp(refractColor, reflectColor, fresnel);
  52. oColor = float4(GetFog(finalColor, GetFogFactor(iEyeVec.w)), 1.0);
  53. }