UnderwaterDeferred.fx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2008 Electronic Arts Inc
  3. //
  4. // Deferred shader for rendering over underwater objects
  5. //////////////////////////////////////////////////////////////////////////////
  6. #define SUPPORT_GLOBAL_LIGHTS 1
  7. #include "Common.fxh"
  8. #include "Gamma.fxh"
  9. #include "CommonUnderwater.fxh"
  10. // ----------------------------------------------------------------------------
  11. SAMPLER_2D_BEGIN( DepthTexture,
  12. string SasBindAddress = "WW3D.DepthTexture";
  13. )
  14. MinFilter = Point;
  15. MagFilter = Point;
  16. MipFilter = Point;
  17. AddressU = Clamp;
  18. AddressV = Clamp;
  19. SAMPLER_2D_END
  20. // ----------------------------------------------------------------------------
  21. // Transforms
  22. // ----------------------------------------------------------------------------
  23. float4x4 ViewI : ViewInverse;
  24. float4x4 ProjectionI : ProjectionInverse;
  25. float Time : Time;
  26. // ----------------------------------------------------------------------------
  27. struct VSOutput
  28. {
  29. float4 Position : POSITION;
  30. float2 TexCoord : TEXCOORD0;
  31. float3 WorldEyeDir : TEXCOORD1;
  32. };
  33. // ----------------------------------------------------------------------------
  34. VSOutput DefaultVS(float3 Position : POSITION, float2 TexCoord : TEXCOORD0)
  35. {
  36. VSOutput Out;
  37. Out.Position = float4(Position, 1);
  38. Out.TexCoord = TexCoord;
  39. // We need to convert the view space depth values from the depth texture to world space positions.
  40. // First build a ray "through" the pixel in question
  41. float4 screenFarPlanePosition = float4(Position.xy, 1, 1);
  42. float4 viewFarPlanePosition4 = mul(screenFarPlanePosition, ProjectionI);
  43. float3 viewFarPlanePosition = viewFarPlanePosition4.xyz / viewFarPlanePosition4.w;
  44. // We don't really want a vector to the far plane. We want the vector with a z length of 1,
  45. // so that we know how much in x-y we need to step per z-depth that we get from the depth texture.
  46. float3 viewEyeDir = viewFarPlanePosition / viewFarPlanePosition.z;
  47. float3 worldEyeDir = mul(viewEyeDir, ViewI);
  48. Out.WorldEyeDir = worldEyeDir;
  49. return Out;
  50. }
  51. // ----------------------------------------------------------------------------
  52. // Helper functions
  53. // ----------------------------------------------------------------------------
  54. float3 ComputeWorldPosition(VSOutput In)
  55. {
  56. float depth = tex2D(SAMPLER(DepthTexture), In.TexCoord).x;
  57. float3 eyePosition = ViewI[3];
  58. float3 worldPosition = eyePosition + depth * In.WorldEyeDir;
  59. return worldPosition;
  60. }
  61. // ----------------------------------------------------------------------------
  62. float4 TintPS(VSOutput In) : COLOR
  63. {
  64. float3 worldPosition = ComputeWorldPosition(In);
  65. // Save a bit fill rate by not modifying pixels above the water surface
  66. clip(WaterLevel - worldPosition.z);
  67. return GetDepthLutValue(worldPosition);
  68. }
  69. // ----------------------------------------------------------------------------
  70. float4 TintPS_M(VSOutput In) : COLOR
  71. {
  72. float3 worldPosition = ComputeWorldPosition(In);
  73. // Save a bit fill rate by not modifying pixels above the water surface
  74. clip(WaterLevel - worldPosition.z);
  75. return GetDepthLutValue_M(worldPosition);
  76. }
  77. // ----------------------------------------------------------------------------
  78. float4 CausticsPS(VSOutput In, uniform bool isFullColor) : COLOR
  79. {
  80. float3 worldPosition = ComputeWorldPosition(In);
  81. // Save a bit fill rate by not modifying pixels above the water surface
  82. clip(WaterLevel - worldPosition.z);
  83. // Calculate the normal through derivatives of the world position.
  84. // Note that these vectors are "faceted" like flat shading.
  85. // The depth based vectors cannot provide a smoothed normal like a interpolated per-vertex normal.
  86. float3 worldTangent = ddy(worldPosition);
  87. float3 worldBinormal = ddx(worldPosition);
  88. float3 worldNormal = normalize(cross(worldTangent, worldBinormal));
  89. float3 caustics = GetCausticsColor(worldPosition, worldNormal, DirectionalLight[0], Time, isFullColor);
  90. return float4(caustics, 1);
  91. }
  92. // ----------------------------------------------------------------------------
  93. struct VSOutputNothing
  94. {
  95. float4 Position : POSITION;
  96. };
  97. // ----------------------------------------------------------------------------
  98. VSOutputNothing NothingVS()
  99. {
  100. VSOutputNothing Out;
  101. Out.Position = float4(0, 0, 0, 1);
  102. return Out;
  103. }
  104. // ----------------------------------------------------------------------------
  105. float4 NothingPS(VSOutputNothing In) : COLOR
  106. {
  107. return float4(0, 0, 0, 0);
  108. }
  109. // ----------------------------------------------------------------------------
  110. technique Tint
  111. {
  112. pass p0
  113. {
  114. VertexShader = compile VS_3_0 DefaultVS();
  115. PixelShader = compile PS_3_0 TintPS();
  116. ZEnable = false;
  117. ZWriteEnable = false;
  118. CullMode = None;
  119. AlphaTestEnable = false;
  120. AlphaBlendEnable = true;
  121. SrcBlend = DestColor;
  122. DestBlend = Zero;
  123. }
  124. }
  125. technique Caustics
  126. {
  127. pass p0
  128. {
  129. VertexShader = compile VS_3_0 DefaultVS();
  130. PixelShader = compile PS_3_0 CausticsPS(false);
  131. ZEnable = false;
  132. ZWriteEnable = false;
  133. CullMode = None;
  134. AlphaTestEnable = false;
  135. AlphaBlendEnable = true;
  136. SrcBlend = One;
  137. DestBlend = One;
  138. }
  139. }
  140. #if ENABLE_LOD
  141. technique Caustics_U
  142. {
  143. pass p0
  144. {
  145. VertexShader = compile VS_3_0 DefaultVS();
  146. PixelShader = compile PS_3_0 CausticsPS(true);
  147. ZEnable = false;
  148. ZWriteEnable = false;
  149. CullMode = None;
  150. AlphaTestEnable = false;
  151. AlphaBlendEnable = true;
  152. SrcBlend = One;
  153. DestBlend = One;
  154. }
  155. }
  156. technique _Tint_M
  157. {
  158. pass p0
  159. {
  160. VertexShader = compile VS_2_0 DefaultVS();
  161. PixelShader = compile PS_2_0 TintPS_M();
  162. ZEnable = false;
  163. ZWriteEnable = false;
  164. CullMode = None;
  165. AlphaTestEnable = false;
  166. AlphaBlendEnable = true;
  167. SrcBlend = DestColor;
  168. DestBlend = Zero;
  169. }
  170. }
  171. // No underwater caustics rendering in Medium LOD or lower
  172. technique _Caustics_M
  173. {
  174. // Normally to just not render something, an empty technique without passes would be enough.
  175. // This shader is used by a scrape renderquad command though, and that only supports one-pass shaders.
  176. // So just use a shader that doesn't generate any pixels, and it should be fine.
  177. pass p0
  178. {
  179. VertexShader = compile VS_2_0 NothingVS();
  180. PixelShader = compile PS_2_0 NothingPS();
  181. ZEnable = false;
  182. ZWriteEnable = false;
  183. CullMode = None;
  184. AlphaTestEnable = false;
  185. AlphaBlendEnable = false;
  186. }
  187. }
  188. #endif