Advertisement
Guest User

Ocean water shader

a guest
Oct 2nd, 2014
752
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.37 KB | None | 0 0
  1. struct S_VSOutputWater2
  2. {
  3.     float4  Pos                 : POSITION;
  4.     float4  WorldPosAndDepth    : TEXCOORD0;
  5.     float3  Normal              : TEXCOORD1;
  6.     float3  NormalSmooth        : TEXCOORD2;
  7.     float4  UVScreenProj        : TEXCOORD3;
  8.     float3  ToViewer            : TEXCOORD4;
  9.     float4  UV0UV1              : TEXCOORD5;
  10.     float4  UV2UV3              : TEXCOORD6;
  11.     float   Foam                : TEXCOORD7;
  12. };
  13.  
  14. struct S_VSOutputTerrainDynWater
  15. {
  16.     float4  Pos                 : POSITION;
  17.     float4  WorldPosAndDepth    : TEXCOORD0;
  18.     float3  Normal              : TEXCOORD1;
  19.     float3  ToViewer            : TEXCOORD2;
  20.     float4  UVScreenProj        : TEXCOORD3;
  21.     float4  UV0                 : TEXCOORD4;
  22.     float4  UV1                 : TEXCOORD5;
  23.  
  24.     // xy - terrain surface tex UV
  25.     float4  UVTerrain           : TEXCOORD6;
  26.  
  27.     // x - layer0 flow blend param
  28.     // y - layer1 flow blend param
  29.     // z - water height
  30.     // w - noise
  31.     float4  Params              : TEXCOORD7;
  32.  
  33.     // xy - water velocity
  34.     float4  Params2             : TEXCOORD8;
  35. };
  36.  
  37.  
  38. struct S_WavesEvalCtx
  39. {
  40.     float3  PosOffs;
  41.     float3  Normal;
  42.     float3  NormalSmooth;
  43.     float3  Tangent;
  44.     float3  Binormal;
  45.     float   FoamAmount;
  46. };
  47.  
  48. struct S_WaterShadingParams
  49. {
  50.     float4  WorldPosAndDepth;
  51.     half3   Normal;
  52.     half3   NormalBump;
  53.     float3  ToViewer;
  54.     float   WaterDepth;
  55.     float2  UVScreen;
  56.     half4   RefrColorFlat;
  57.     half4   RefrColorBump;
  58.     half    Opacity;
  59. };
  60.  
  61. //
  62. // ResetWavesEvalCtx()
  63. //
  64. //
  65. //*********************************************************************************************
  66. void ResetWavesEvalCtx(in out S_WavesEvalCtx ctx)
  67. {
  68.     ctx.PosOffs     = 0;
  69.     ctx.Binormal    = float3(0,0,1);
  70.     ctx.Tangent     = float3(1,0,0);
  71.     ctx.Normal      = float3(0,1,0);
  72.     ctx.NormalSmooth= float3(0,1,0);
  73.     ctx.FoamAmount  = 0;
  74. }
  75. //*********************************************************************************************
  76.  
  77.  
  78. //
  79. // RemapVelocityToAngularSeg()
  80. //
  81. //
  82. //*******************************************************************************************
  83. float2 RemapVelocityToAngularSeg(float2 vel,float segSizeRad,float offs)
  84. {
  85.     const float coeff_1 = PI / 4;
  86.     const float coeff_2 = 3 * coeff_1;
  87.  
  88.     float x     = vel.x;
  89.     float y     = vel.y;
  90.     float abs_y = abs(y) + 1e-10f; // kludge to prevent 0/0 condition
  91.     float angle;
  92.  
  93.     if (x >= 0)
  94.     {
  95.         angle = coeff_1 - coeff_1 * (x - abs_y) / (x + abs_y);
  96.     }
  97.     else
  98.     {
  99.         angle = coeff_2 - coeff_1 * (x + abs_y) / (abs_y - x);
  100.     }
  101.  
  102.     angle = y < 0 ?  2 * PI - angle : angle;
  103.  
  104.     float2 res;
  105.  
  106.     angle = (angle + offs) / segSizeRad;
  107.  
  108.     res.x = floor(angle);
  109.     res.y = angle - res.x;
  110.  
  111.     return res;
  112. }
  113. //*******************************************************************************************
  114.  
  115.  
  116. //
  117. // EvalOceanWaves()
  118. //
  119. //
  120. //*********************************************************************************************
  121. void EvalOceanWaves(float2  pos,
  122.                     float   time,
  123.                     float4  waveSteepness,
  124.                     float4  waveDirX,
  125.                     float4  waveDirY,
  126.                     float4  wavePhases,
  127.                     float4  waveLengths,
  128.                     float4  waveSpeeds,
  129.                     float4  waveAmps,
  130.                     in out S_WavesEvalCtx ctx)
  131. {
  132.     float4  dirAngleSin     = waveDirY;
  133.     float4  dirAngleCos     = waveDirX;
  134.  
  135.     float4  wavePos         = pos.xxxx * dirAngleCos + pos.yyyy * dirAngleSin;
  136.     float4  waveFreqs       = 2 * PI / waveLengths;
  137.     float4  waveInputs      = waveFreqs * (wavePos + waveSpeeds * time);
  138.     float4  sinWaves;
  139.     float4  cosWaves;
  140.  
  141.     sincos(wavePhases + waveInputs,sinWaves,cosWaves);
  142.  
  143.     sinWaves *= waveAmps;
  144.     cosWaves *= waveAmps;
  145.  
  146.     float4  gerstnerOffs    = waveSteepness * cosWaves;
  147.     float3  posDiff         = float3(   dot(gerstnerOffs * dirAngleCos,1),
  148.                                         dot(sinWaves,1),
  149.                                         dot(gerstnerOffs * dirAngleSin,1));
  150.  
  151.     ctx.PosOffs += posDiff;
  152.  
  153.     float   dNx = -dot(dirAngleCos * cosWaves * waveFreqs,1);
  154.     float   dNz = -dot(dirAngleSin * cosWaves * waveFreqs,1);
  155.  
  156.     ctx.Normal.x += dNx;
  157.     ctx.Normal.y -= dot(waveSteepness * waveFreqs * sinWaves,1);
  158.     ctx.Normal.z += dNz;
  159.  
  160.     ctx.NormalSmooth.x += dNx;
  161.     ctx.NormalSmooth.z += dNz;
  162.  
  163.     ctx.Binormal.x -= dot(waveSteepness * dirAngleCos * dirAngleSin * waveFreqs * sinWaves,1);
  164.     ctx.Binormal.y += dot(dirAngleSin * waveFreqs * cosWaves,1);
  165.     ctx.Binormal.z -= dot(waveSteepness * dirAngleSin * dirAngleSin * waveFreqs * sinWaves,1);
  166.  
  167.     ctx.Tangent.x -= dot(waveSteepness * dirAngleCos * dirAngleCos * waveFreqs * sinWaves,1);
  168.     ctx.Tangent.y += dot(dirAngleCos * waveFreqs * cosWaves,1);
  169.     ctx.Tangent.z -= dot(waveSteepness * dirAngleCos * dirAngleSin * waveFreqs * sinWaves,1);
  170. }
  171. //*********************************************************************************************
  172.  
  173.  
  174. //
  175. // CalcLayerUV()
  176. //
  177. //
  178. //*********************************************************************************************
  179. float2 CalcLayerUV(float3 worldPos,float4 layerParams,float time)
  180. {
  181.     float2  uvDirU;
  182.     float2  uvDirV;
  183.  
  184.     sincos(layerParams.x,uvDirU.y,uvDirU.x);
  185.  
  186.     uvDirV = uvDirU.yx * float2(-1,1);
  187.  
  188.     return float2(  dot(worldPos.xz,uvDirU) * layerParams.z,
  189.                     dot(worldPos.xz,uvDirV) * layerParams.z + layerParams.y * time);
  190. }
  191. //*********************************************************************************************
  192.  
  193. //
  194. // EvalWavesByVelocity()
  195. //
  196. //
  197. //*********************************************************************************************
  198. void EvalWavesByVelocity(float3 worldPos,float2 waterVelocity,float waterHeight,float time,float noise,float minWaveLength,in out S_WavesEvalCtx ctx)
  199. {
  200.     const float ANGULAR_SEGMENT_SIZE    = PI / 24;
  201.     const float G                       = 9.81f;
  202.     const float WAVELENGTH_TO_AMP       = 1.0f / 300;
  203.  
  204. #if 0
  205.     float2  waveInputPos    = worldPos.xz - GPU_PARAM_ID_WRLD_CAM_OFFS.xz;
  206.     float4  waveDirX        = 1;
  207.     float4  waveDirY        = 0;
  208.     float4  waveSteepness   = 2;//1.5;
  209.     float4  waveLengths     = float4(1,1,1,1) * 8;
  210.     float4  waveSpeeds      = sqrt((waveLengths * G) / (2 * PI));
  211.     float4  waveAmplitudes  = float4(1,1,1,1) * 0.15f;
  212.     float4  phaseOffs       = 0;
  213.     float4  dirAngles       = float4(0,PI / 4, 2 * PI / 4, 3 * PI / 4);
  214.    
  215.     sincos(dirAngles,waveDirY,waveDirX);
  216.  
  217.     EvalOceanWaves(waveInputPos,time,waveSteepness,waveDirX,waveDirY,phaseOffs,waveLengths,waveSpeeds,waveAmplitudes,ctx);
  218. #else
  219.  
  220.     float   xxNoise = (0.8f + 0.4f * noise);
  221.     float2  angRange = RemapVelocityToAngularSeg(waterVelocity,ANGULAR_SEGMENT_SIZE,(noise * 2 - 1) * PI / 10);
  222. //  float2  angRange = RemapVelocityToAngularSeg(waterVelocity,ANGULAR_SEGMENT_SIZE,0);
  223.  
  224.     float   waveLengthsScaler = 60;
  225.     float   minWaveLengthInv = rcp(2 * minWaveLength);
  226.  
  227.  
  228.     const float4 angJitter0         = float4(-0.2,0.2,-0.4,0.4) * 2;
  229.     const float4 waveSpeedsJitter   = float4(1,1.4f,0.8f,1.2f);
  230.  
  231.     float4  phaseOffs0      = float4(23.488591f,67.153645f,87.654664f,73.334413f);// + noise * PI;//(PI / 10); 
  232.     float4  waveLengths0    = float4(1,1.15f,1.2f,1.25f) * waveLengthsScaler;
  233.  
  234.     float   dirBlend        = SmoothStep(angRange.y);
  235.  
  236.     float4  waveAmpsBase    = waveLengths0 * WAVELENGTH_TO_AMP * xxNoise;
  237.     float4  waveAmplitudes0 = waveAmpsBase * (1 - dirBlend);
  238.     float4  waveAmplitudes1 = waveAmpsBase * dirBlend;
  239.     float4  waveSpeeds      = sqrt((waveLengths0 * G) / (2 * PI)) * waveSpeedsJitter;
  240. //  float4  waveSpeeds      = sqrt(G * waterHeight);
  241.     float4  dirAngles0      = (angRange.xxxx + angJitter0) * ANGULAR_SEGMENT_SIZE;
  242.     float4  dirAngles1      = dirAngles0 + ANGULAR_SEGMENT_SIZE;
  243.     float4  waveSteepness   = 1;
  244.     float2  waveInputPos    = worldPos.xz - GPU_PARAM_ID_WRLD_CAM_OFFS.xz;
  245.  
  246.     float4  waveDirX0;
  247.     float4  waveDirY0;
  248.     float4  waveDirX1;
  249.     float4  waveDirY1;
  250.  
  251.     sincos(dirAngles0,waveDirY0,waveDirX0);
  252.     sincos(dirAngles1,waveDirY1,waveDirX1);
  253.  
  254.     NX_HINT_LOOP
  255.     for (int i = 0; i < 1; i++)
  256.     {
  257.         float4  waveAmpsFadeout = 1;// saturate(waveLengths0 * minWaveLengthInv);
  258.  
  259.         waveAmpsFadeout *= waveAmpsFadeout;
  260.         waveAmpsFadeout *= waveAmpsFadeout;
  261.         waveAmpsFadeout *= waveAmpsFadeout;
  262.  
  263.         EvalOceanWaves(waveInputPos,time,waveSteepness,waveDirX0,waveDirY0,phaseOffs0,waveLengths0,waveSpeeds,waveAmplitudes0 * waveAmpsFadeout,ctx);
  264.         EvalOceanWaves(waveInputPos,time,waveSteepness,waveDirX1,waveDirY1,phaseOffs0,waveLengths0,waveSpeeds,waveAmplitudes1 * waveAmpsFadeout,ctx);
  265.  
  266.         float scale = 1.35424f;
  267.  
  268.         waveLengths0 *= scale;
  269.         waveSpeeds *= SQRT2;
  270.         waveAmplitudes0 *= scale;
  271.         waveAmplitudes1 *= scale;
  272.         phaseOffs0 *= PI / 2;
  273.     }
  274. #endif
  275. }
  276. //*********************************************************************************************
  277.  
  278.  
  279. //
  280. // WaterSampleScreenSpaceRefl()
  281. //
  282. //
  283. //*******************************************************************************************
  284. half4 WaterSampleScreenSpaceRefl(float3 wpos,float3 dir,const S_SSRParams params)
  285. {
  286.     float zf            = params.m_CamNearFar.w;
  287.     float maxSearchDist = 10000;
  288.  
  289. //  return SampleScreenSpaceRefl2(wpos,dir * maxSearchDist,GPU_PARAM_ID_VIEW_PROJ_TM,GPU_PARAM_ID_VIEW_TM,GPU_SAMPLER_ID_AUX_SCREENSPACE_COLOR,GPU_SAMPLER_ID_SCENE_DEPTH,GPU_PARAM_ID_RTARGET_SIZE,GPU_PARAM_ID_CAM_NEAR_FAR.w);
  290.     return SampleScreenSpaceRefl2(wpos,dir * maxSearchDist,params.m_ViewProjTM,params.m_ViewTM,GPU_SAMPLER_ID_SSR_COLOR,GPU_SAMPLER_ID_SSR_DEPTH,params.m_RTSize,zf);
  291. }
  292. //*******************************************************************************************
  293.  
  294. //
  295. // EvalWaterShading()
  296. //
  297. //
  298. //*********************************************************************************************
  299. half3 EvalWaterShading(in S_WaterShadingParams params)
  300. {
  301.     half3   normViewerDir   = normalize(params.ToViewer.xyz);
  302.     float   sceneDepth      = DecodeTexDepth(NXTex2DLod(GPU_SAMPLER_ID_SCENE_DEPTH,params.UVScreen.xyyy)) * GPU_PARAM_ID_CAM_NEAR_FAR.w;
  303. //  half3   normal          = params.Normal;
  304.     half3   normalBump      = params.NormalBump;
  305.     float   waterDepth      = params.WaterDepth;
  306.     float   accWaterDepth   = max(sceneDepth - params.WorldPosAndDepth.w * GPU_PARAM_ID_CAM_NEAR_FAR.w,0);
  307.     float   horizAttScale   = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams2.y;
  308.     float   vertAttScale    = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams2.z;
  309.     half3   extinction      = exp(-GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ColorAtt.xyz * (accWaterDepth * horizAttScale + waterDepth * vertAttScale));
  310.     half    invInScatter    = exp(-GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ColorAtt.w * accWaterDepth);
  311.     half    edgeSoftFactor  = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams2.x;
  312.     float   edgeSoftening   = Sqr(saturate(waterDepth * edgeSoftFactor));
  313.     float   time            = GPU_PARAM_ID_TIME;   
  314.     half3   R               = ReflectLeaving(normViewerDir,normalBump);
  315.     half4   refr            = params.RefrColorBump;
  316.     half4   refrFlat        = params.RefrColorFlat;
  317.  
  318.     half4   reflSS          = WaterSampleScreenSpaceRefl(params.WorldPosAndDepth.xyz,R,GPU_PARAM_ID_SSR_PARAMS);
  319.     half3   reflSky         = EvalSkyColor(R);
  320.     half3   refl            = lerp(reflSky,reflSS,reflSS.a);
  321.  
  322.     half    specPower       = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams.z;
  323.     half    facing          = saturate(dot(normViewerDir,normalBump));
  324.     half    fresnelPower    = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams.x;
  325.     half    fresnelBias     = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams.y;
  326.     half    fresnel         = Fresnel(facing,fresnelBias,fresnelPower);
  327.     half    sunShadowMask   = 1;
  328.  
  329.     S_LightAccumCtx     lightAccCtx;
  330.     S_ShadingParams     shadingParams = (S_ShadingParams)0;
  331.     S_MaterialParams    materialParams;
  332.    
  333.     shadingParams.m_Normal          = normalBump;
  334.     shadingParams.m_ToViewer        = normViewerDir;
  335.     shadingParams.m_Refl            = R;
  336.     shadingParams.m_WorldPos        = params.WorldPosAndDepth.xyz;
  337.     shadingParams.m_WorldDist       = length(params.ToViewer);
  338.     shadingParams.m_BloomEmissivity = 0;
  339.  
  340.     materialParams.m_MatDiff        = 1;
  341.     materialParams.m_MatParams      = half4(specPower,1,1,0);
  342.  
  343.     BeginLightingAccumulation(lightAccCtx,shadingParams,materialParams,GPU_PARAM_ID_GLOBAL_LIGHTING);
  344.  
  345.     lightAccCtx.m_ShadowMask = sunShadowMask;
  346.  
  347.     AccumulateGlobalLighting(lightAccCtx,GPU_PARAM_ID_GLOBAL_LIGHTING,shadingParams,materialParams);
  348.  
  349.     EndLightingAccumulation(lightAccCtx,shadingParams,materialParams,GPU_PARAM_ID_GLOBAL_LIGHTING);
  350.  
  351.  
  352. //  return saturate(dot(normViewerDir,normalBump));
  353.  
  354.  
  355.     half3   litColor    = lightAccCtx.m_Diff;
  356.     half3   finalRefr   = lerp(GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ScatterColor.xyz,refr * extinction,invInScatter);
  357. //  half3   finalRefr   = lerp(GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ScatterColor.xyz * sunShadowMask,refr * extinction,invInScatter);
  358.  
  359.     litColor = lerp(finalRefr,refl,fresnel);// + lightAccCtx.m_Spec;
  360.  
  361.     half3 result = FinalizeColorOutput(litColor,0,shadingParams,lightAccCtx,GPU_PARAM_ID_GLOBAL_LIGHTING);
  362.  
  363.     return lerp(refrFlat,result,edgeSoftening * params.Opacity);
  364. }
  365. //*********************************************************************************************
  366.  
  367. //
  368. // VS_WaterProjGrid()
  369. //
  370. //
  371. //*******************************************************************************************
  372. S_VSOutputWater2 VS_WaterProjGrid(float2 pos: POSITION)
  373. {
  374.     S_VSOutputWater2    res = (S_VSOutputWater2)0;
  375.  
  376.     float   zn          = GPU_PARAM_ID_CAM_NEAR_FAR.z;
  377.     float4  waterPlane  = GPU_PARAM_ID_WATER_PARAMS.m_ProjectorSpaceWaterPlane;
  378.     float3  bckOffs     = float3(0,0,-GPU_PARAM_ID_WATER_PARAMS.m_MiscParams.z);
  379.     float   depth       = zn - bckOffs.z;
  380.     float3  vpos        = GetViewSpacePosFromDepth(pos.xy,depth,GPU_PARAM_ID_WATER_PARAMS.m_ProjGridProjInfo);
  381.     float   isecT       = PlaneRayIntersection(bckOffs,vpos,waterPlane);
  382.    
  383.     [branch]
  384.     if (isecT >= 0)
  385.     {
  386.         vpos = bckOffs + vpos * isecT;
  387.  
  388.         //
  389.         // calc frequency fadeouts to avoid aliasing
  390.         //
  391.  
  392.         float3 vposC    = GetViewSpacePosFromDepth(pos.xy,zn,GPU_PARAM_ID_WATER_PARAMS.m_ProjGridProjInfo);
  393.         float3 vposHN   = GetViewSpacePosFromDepth(pos.xy + float2(GPU_PARAM_ID_WATER_PARAMS.m_ProjGridParams.z,0),zn,GPU_PARAM_ID_WATER_PARAMS.m_ProjGridProjInfo);
  394.         float3 vposVN   = GetViewSpacePosFromDepth(pos.xy + float2(0,GPU_PARAM_ID_WATER_PARAMS.m_ProjGridParams.w),zn,GPU_PARAM_ID_WATER_PARAMS.m_ProjGridProjInfo);
  395.  
  396.         vposC   = vposC  * PlaneRayIntersectionUnchecked(0,vposC,waterPlane);
  397.         vposHN  = vposHN * PlaneRayIntersectionUnchecked(0,vposHN,waterPlane);
  398.         vposVN  = vposVN * PlaneRayIntersectionUnchecked(0,vposVN,waterPlane);
  399.  
  400.         float2  stepXY          = float2(distance(vposC,vposHN),distance(vposC,vposVN));
  401.         float   minWaveLength   = max(stepXY.x,stepXY.y);
  402.         float3  wpos            = mul(float4(vpos,1),GPU_PARAM_ID_VIEW_TM_INV);
  403.  
  404.         S_WavesEvalCtx evalCtx;
  405.  
  406.         ResetWavesEvalCtx(evalCtx);    
  407.  
  408.         NX_HINT_LOOP
  409.         for (int i = 0; i < GPU_MAX_WATER_WAVES / 4; i++)
  410.         {
  411.             float4  waveLengths     = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesLengths[i];
  412.             float4  waveAmpsFadeout = saturate(pow((waveLengths * 0.5) / minWaveLength,10));
  413.             float4  waveAmplitudes  = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesAmplitudes[i] * waveAmpsFadeout;
  414.             float4  waveSpeeds      = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesSpeeds[i];
  415.             float4  wavePhases      = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesPhases[i];
  416.             float4  waveDirX        = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesDirX[i];
  417.             float4  waveDirY        = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesDirY[i];
  418.             float4  waveSteepness   = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesSteepness[i];
  419.             float2  waveInputPos    = wpos.xz - GPU_PARAM_ID_WRLD_CAM_OFFS.xz;
  420.            
  421.             EvalOceanWaves(waveInputPos,GPU_PARAM_ID_TIME,waveSteepness,waveDirX,waveDirY,wavePhases,waveLengths,waveSpeeds,waveAmplitudes,evalCtx);
  422.         }
  423.  
  424.  
  425.         res.Foam = 0;
  426.  
  427.  
  428.         //
  429.         // UVs are calculated before actual position displacement to get nice stretching of normalmaps over waves
  430.         //
  431.  
  432.         float   time = GPU_PARAM_ID_TIME;
  433.  
  434.         res.UV0UV1.xy = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer0Params,time);
  435.         res.UV0UV1.zw = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer1Params,time);
  436.         res.UV2UV3.xy = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer2Params,time);
  437.         res.UV2UV3.zw = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer3Params,time);
  438.  
  439.         res.UV0UV1 += GPU_PARAM_ID_WATER_PARAMS.m_Layer01UVoffs;
  440.         res.UV2UV3 += GPU_PARAM_ID_WATER_PARAMS.m_Layer23UVoffs;
  441.  
  442.  
  443.  
  444.         wpos += evalCtx.PosOffs;
  445.  
  446.         res.Normal              = evalCtx.Normal;
  447.         res.NormalSmooth        = evalCtx.NormalSmooth;
  448.         res.Pos                 = mul(float4(wpos,1),GPU_PARAM_ID_VIEW_PROJ_TM);
  449.         res.WorldPosAndDepth    = float4(wpos,res.Pos.w);
  450.         res.UVScreenProj        = HPosToScreenUV(res.Pos);
  451.         res.ToViewer            = GPU_PARAM_ID_CAM_POS - wpos;
  452.     }
  453.     else
  454.     {
  455.         res.Pos = float4(pos.xy * float2(2,-2) + float2(-1,1),2,1);
  456.     }
  457.  
  458.  
  459.     return res;
  460. }
  461. //*******************************************************************************************
  462.  
  463.  
  464.  
  465. //
  466. // VS_DynamicSimWater()
  467. //
  468. //
  469. //*******************************************************************************************
  470. S_VSOutputTerrainDynWater VS_DynamicSimWater(float3 pos : POSITION,int4 normalX16Y16: BLENDINDICES,float3 vel2DAndHeight : TEXCOORD0)
  471. {
  472.     S_VSOutputTerrainDynWater   res     = (S_VSOutputTerrainDynWater)0;
  473.  
  474. #if 1
  475.     float3  wpos            = mul(float4(pos,1),GPU_PARAM_ID_WORLD_TM);
  476.     float2  nrm2            = float2(dot(normalX16Y16.xy,float2(1,256)) / 65535,dot(normalX16Y16.zw,float2(1,256)) / 65535) * 2 - 1;
  477.     float3  normal          = float3(nrm2.x,sqrt(1 - nrm2.x * nrm2.x - nrm2.y * nrm2.y),nrm2.y);
  478.     float   time            = GPU_PARAM_ID_TIME;
  479.     float   layer0UVScale   = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer0Params.z;
  480.     float   layer1UVScale   = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer1Params.z;
  481.     float   noise           = Perlin2D((wpos.xz - GPU_PARAM_ID_WRLD_CAM_OFFS.xz) * 0.025f + time * 0.1f) * 0.5f + 0.5f;
  482.  
  483. #if 0
  484.     S_WavesEvalCtx wavesEvalCtx;
  485.  
  486.     ResetWavesEvalCtx(wavesEvalCtx);       
  487.  
  488.     EvalWavesByVelocity(wpos,-vel2DAndHeight.xy,vel2DAndHeight.z,time,0,wavesEvalCtx);
  489.  
  490.     wpos += wavesEvalCtx.PosOffs;
  491.     normal = wavesEvalCtx.Normal;
  492. #endif
  493.  
  494.     float4  hpos    = mul(float4(wpos,1),GPU_PARAM_ID_VIEW_PROJ_TM);
  495.  
  496.     res.Pos                 = VSOutputFinalPos(hpos);
  497.     res.WorldPosAndDepth    = float4(wpos,LinWorldDepthFromHPos(hpos));
  498.     res.Normal              = normal;
  499.     res.ToViewer            = GPU_PARAM_ID_CAM_POS - wpos;
  500.     res.UVScreenProj        = HPosToScreenUV(res.Pos);
  501.  
  502.     res.UV0 = (wpos.xz * layer0UVScale + GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer0Params.xy).xyxy * float2(1,-1).xyxy;
  503.     res.UV1 = (wpos.xz * layer1UVScale + GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer1Params.xy).xyxy * float2(1,-1).xyxy;
  504.  
  505.     res.UVTerrain.xy = wpos.xz * GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_WrldToTerrainTexUVScaleBias.xy + GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_WrldToTerrainTexUVScaleBias.zw;
  506.  
  507.     res.Params.z = vel2DAndHeight.z;// + wavesEvalCtx.PosOffs.y;
  508.     res.Params.w = noise;
  509.  
  510.  
  511.     //
  512.     // adjust UVs to follow flow field
  513.     //
  514.  
  515.     {
  516.         float2  nrmVel                  = normalize(vel2DAndHeight.xy);
  517.         float2  flowVel                 = nrmVel * min(length(vel2DAndHeight.xy),0.25f) * float2(1,-1);
  518.         float4  uvRndOffs               = float4(0.182764f,0.8766731f,0.564621f,0.427134f);
  519.         float4  flowFollowAmps          = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexLayersFlowFollowAmp;
  520.         float2  flowSpeedScaleLayer     = float2(   GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer0Params.w,
  521.                                                     GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_TexNormalsLayer1Params.w);
  522.  
  523.         float   flowOffs                = noise * 0.25f;
  524.         float4  toffs                   = frac(frac(time.xxxx * flowSpeedScaleLayer.xxyy + float2(0,0.5f).xyxy) + flowOffs);
  525.  
  526.         res.UV0 = res.UV0 - (flowVel.xyxy * toffs.xxyy * flowFollowAmps.x) + uvRndOffs.xyzw;
  527.         res.UV1 = res.UV1 - (flowVel.xyxy * toffs.zzww * flowFollowAmps.y) + uvRndOffs.zwyx;
  528.  
  529.         res.Params.xy = 2 * abs(toffs.xz - 0.5f);
  530.  
  531.         res.Params2.xy = vel2DAndHeight.xy;
  532.     }
  533. #endif
  534.  
  535.     return res;
  536. }
  537. //*******************************************************************************************
  538.  
  539. //
  540. // VS_Water()
  541. //
  542. //
  543. //*******************************************************************************************
  544. S_VSOutputWater2 VS_Water(int4  input: BLENDINDICES)
  545. {
  546.     S_VSOutputWater2    res         = (S_VSOutputWater2)0;
  547.     float               span        = GPU_PARAM_ID_WATER_TILE_PARAMS.x;
  548.     float               tileSize    = GPU_PARAM_ID_WATER_TILE_PARAMS.z;
  549.     float               waterHeight = GPU_PARAM_ID_WATER_PARAMS.m_Params.w;
  550.     float2              gridPos     = input.xy;
  551.     float3              wrldPos;
  552.  
  553.     gridPos.y = tileSize - 1 - gridPos.y;
  554.  
  555.     wrldPos.xz  = gridPos.xy * span - (tileSize - 1) * 0.5 * span;
  556.     wrldPos.y   = waterHeight + GPU_PARAM_ID_WRLD_CAM_OFFS.y;
  557.  
  558.  
  559.     S_WavesEvalCtx  evalCtx;
  560.     float3          wpos = wrldPos;
  561.  
  562.     evalCtx.PosOffs     = 0;
  563.     evalCtx.Binormal    = float3(0,0,1);
  564.     evalCtx.Tangent     = float3(1,0,0);
  565.     evalCtx.Normal      = float3(0,1,0);
  566.     evalCtx.NormalSmooth= float3(0,1,0);
  567.     evalCtx.FoamAmount  = 0;
  568.  
  569.     NX_HINT_LOOP
  570.     for (int i = 0; i < GPU_MAX_WATER_WAVES / 4; i++)
  571.     {
  572.         float4  waveLengths     = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesLengths[i];
  573.         float4  waveAmplitudes  = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesAmplitudes[i];
  574.         float4  waveSpeeds      = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesSpeeds[i];
  575.         float4  wavePhases      = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesPhases[i];
  576.         float4  waveDirX        = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesDirX[i];
  577.         float4  waveDirY        = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesDirY[i];
  578.         float4  waveSteepness   = GPU_PARAM_ID_WATER_GERSTNER_WAVES.m_GeomWavesSteepness[i];
  579.  
  580.         EvalOceanWaves(wpos.xz - GPU_PARAM_ID_WRLD_CAM_OFFS.xz,GPU_PARAM_ID_TIME,waveSteepness,waveDirX,waveDirY,wavePhases,waveLengths,waveSpeeds,waveAmplitudes,evalCtx);
  581.     }
  582.  
  583.  
  584.     //
  585.     // UVs are calculated before actual position displacement to get nice stretching of normalmaps over waves
  586.     //
  587.  
  588.     float   time = GPU_PARAM_ID_TIME;
  589.  
  590.     res.UV0UV1.xy = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer0Params,time);
  591.     res.UV0UV1.zw = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer1Params,time);
  592.     res.UV2UV3.xy = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer2Params,time);
  593.     res.UV2UV3.zw = CalcLayerUV(wpos,GPU_PARAM_ID_WATER_PARAMS.m_Layer3Params,time);
  594.  
  595.     res.UV0UV1 += GPU_PARAM_ID_WATER_PARAMS.m_Layer01UVoffs;
  596.     res.UV2UV3 += GPU_PARAM_ID_WATER_PARAMS.m_Layer23UVoffs;
  597.  
  598.     wpos += evalCtx.PosOffs;
  599.  
  600.     float4 hpos = mul(float4(wpos,1),GPU_PARAM_ID_VIEW_PROJ_TM);
  601.  
  602.     res.Normal              = evalCtx.Normal;
  603.     res.NormalSmooth        = evalCtx.NormalSmooth;
  604.     res.Pos                 = VSOutputFinalPos(hpos);
  605.     res.WorldPosAndDepth    = float4(wpos,LinWorldDepthFromHPos(hpos));
  606.     res.UVScreenProj        = HPosToScreenUV(res.Pos);
  607.     res.ToViewer            = GPU_PARAM_ID_CAM_POS - wpos;
  608.     res.Foam                = evalCtx.FoamAmount;
  609.  
  610. #if 0
  611.     sincos(GPU_PARAM_ID_WATER_PARAMS.m_Layer0Params.x,res.RotL0L1.y,res.RotL0L1.x);
  612.     sincos(GPU_PARAM_ID_WATER_PARAMS.m_Layer1Params.x,res.RotL0L1.w,res.RotL0L1.z);
  613.     sincos(GPU_PARAM_ID_WATER_PARAMS.m_Layer2Params.x,res.RotL2L3.y,res.RotL2L3.x);
  614.     sincos(GPU_PARAM_ID_WATER_PARAMS.m_Layer3Params.x,res.RotL2L3.w,res.RotL2L3.z);
  615. #endif
  616.  
  617.     return res;
  618. }
  619. //*******************************************************************************************
  620.  
  621.  
  622. //
  623. // PS_Water()
  624. //
  625. //
  626. //*******************************************************************************************
  627. half4 PS_Water(S_VSOutputWater2 input) : COLOR0
  628. {
  629.     half3   normViewerDir   = normalize(input.ToViewer.xyz);
  630.     float   sceneDepth      = DecodeTexDepth(NXTex2Dproj(GPU_SAMPLER_ID_SCENE_DEPTH,input.UVScreenProj)) * GPU_PARAM_ID_CAM_NEAR_FAR.w;
  631.     float3  sceneViewPos    = GetViewSpacePosFromDepth(input.UVScreenProj.xy / input.UVScreenProj.w,sceneDepth);
  632.     float3  sceneWrldPos    = mul(float4(sceneViewPos,1),GPU_PARAM_ID_VIEW_TM_INV);
  633.     half    sunShadowMask   = 1;
  634.     half    edgeSoftening   = saturate((sceneDepth - input.UVScreenProj.w) * GPU_PARAM_ID_WATER_PARAMS.m_MiscParams.w);
  635.     half3   normalSmooth    = normalize(input.NormalSmooth);
  636.     half3   normal          = normalize(input.Normal);
  637.     float   waterDepth      = max(input.WorldPosAndDepth.y - sceneWrldPos.y,0);
  638.     float   accWaterDepth   = max(sceneDepth - input.WorldPosAndDepth.w,0);
  639.     float   viewDist        = length(input.ToViewer.xyz);
  640.     float   L               = viewDist * waterDepth / (GPU_PARAM_ID_CAM_POS.y - sceneWrldPos.y);
  641.     half3   extinction      = exp(-GPU_PARAM_ID_WATER_PARAMS.m_ColorAtt.xyz * 2 * L);
  642. //  half3   extinction      = exp(-GPU_PARAM_ID_WATER_PARAMS.m_ColorAtt.xyz * (accWaterDepth + waterDepth));
  643.     half    invInScatter    = exp(-GPU_PARAM_ID_WATER_PARAMS.m_ColorAtt.w * accWaterDepth);
  644.     half3   fnormal         = normalize(cross(ddx(input.WorldPosAndDepth.xyz),ddy(input.WorldPosAndDepth.xyz)));
  645.  
  646.  
  647.     //
  648.     // calc bumpmapped normal
  649.     //
  650.  
  651. #if 1
  652.     float3x3 TNB0 = CotangentFrame(normal,-normViewerDir,input.UV0UV1.xy);
  653.     float3x3 TNB1 = CotangentFrame(normal,-normViewerDir,input.UV0UV1.zw);
  654.     float3x3 TNB2 = CotangentFrame(normal,-normViewerDir,input.UV2UV3.xy);
  655.     float3x3 TNB3 = CotangentFrame(normal,-normViewerDir,input.UV2UV3.zw);
  656.  
  657.     half3   texNrm0 = mul(UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER0,input.UV0UV1.xy)),TNB0);
  658.     half3   texNrm1 = mul(UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER1,input.UV0UV1.zw)),TNB1);
  659.     half3   texNrm2 = mul(UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER2,input.UV2UV3.xy)),TNB2);
  660.     half3   texNrm3 = mul(UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER3,input.UV2UV3.zw)),TNB3);
  661.    
  662.     half3   texNrm;
  663.    
  664.     texNrm.xz   = texNrm0.xz + texNrm1.xz + texNrm2.xz + texNrm3.xz;
  665.     texNrm.y    = texNrm0.y * texNrm1.y * texNrm2.y * texNrm3.y;
  666.  
  667.     normal = normalize(texNrm);
  668.  
  669. #else
  670.  
  671.     // This is incorrect because of gerstner-waves introduced non-uniform UV stretching
  672.  
  673.     half3   texNrm0 = UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER0,input.UV0UV1.xy));
  674.     half3   texNrm1 = UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER1,input.UV0UV1.zw));
  675.     half3   texNrm2 = UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER2,input.UV2UV3.xy));
  676.     half3   texNrm3 = UnpackTexNormal(NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER3,input.UV2UV3.zw));
  677.     half3   texNrm;
  678.  
  679.     texNrm.x = dot(texNrm0.xy,input.RotL0L1.xy);
  680.     texNrm.y = dot(texNrm0.xy,input.RotL0L1.yx * float2(1,-1));
  681.  
  682.     texNrm.x += dot(texNrm1.xy,input.RotL0L1.zw);
  683.     texNrm.y += dot(texNrm1.xy,input.RotL0L1.wz * float2(1,-1));
  684.  
  685.     texNrm.x += dot(texNrm2.xy,input.RotL2L3.xy);
  686.     texNrm.y += dot(texNrm2.xy,input.RotL2L3.yx * float2(1,-1));
  687.  
  688.     texNrm.x += dot(texNrm3.xy,input.RotL2L3.zw);
  689.     texNrm.y += dot(texNrm3.xy,input.RotL2L3.wz * float2(1,-1));
  690.  
  691.     texNrm.z    = texNrm0.z * texNrm1.z * texNrm2.z * texNrm3.z;
  692.     texNrm      = normalize(texNrm);
  693.  
  694.     normal = normalize( texNrm.x * tangent +
  695.                         texNrm.y * binormal +
  696.                         texNrm.z * normal);
  697.  
  698. #endif
  699.  
  700.  
  701. //  return saturate(dot(normViewerDir,normalSmooth));
  702. //  return saturate(dot(normViewerDir,normal));
  703.  
  704.     //
  705.     // reflection vector
  706.     //
  707.    
  708.     half3       R = ReflectLeaving(normViewerDir,normal);
  709.  
  710.  
  711.     //
  712.     // sample refraction
  713.     //
  714.  
  715.  
  716.     half2   bumpScale       = half2(GPU_PARAM_ID_WATER_PARAMS.m_Params.xy);// * input.UVScreenProj.w;
  717.     half4   bumpUVOffs      = half4(normal.xzxz) * bumpScale.xxyy;
  718.  
  719.     float4  uvRefr          = input.UVScreenProj;
  720.     float4  uvRefl          = input.UVScreenProj;
  721.  
  722.     uvRefl.xy += bumpUVOffs.xy;
  723.     uvRefr.xy += bumpUVOffs.zw;
  724.  
  725.     half4   refrBump        = NXTex2Dproj(GPU_SAMPLER_ID_AUX_SCREENSPACE_COLOR,uvRefr);
  726.     half4   refrFlat        = NXTex2Dproj(GPU_SAMPLER_ID_AUX_SCREENSPACE_COLOR,input.UVScreenProj);
  727.     half4   refr            = lerp(refrFlat,refrBump,edgeSoftening);
  728.  
  729.     half3   Rsmooth     = ReflectLeaving(normViewerDir,normalize(normalSmooth));
  730.     float4  projR       = mul(float4(Rsmooth,0),GPU_PARAM_ID_WATER_PARAMS.m_ReflViewProjTM);
  731.     float2  reflUV      = (projR.xy / projR.z) * float2(0.5,-0.5) + float2(0.5,0.5);
  732.     half4   refl        = NXTex2D(GPU_SAMPLER_ID_REFLECTION,reflUV);
  733.  
  734.  
  735.  
  736.     //
  737.     // Fresnel term approximation
  738.     //
  739.  
  740. #if 0
  741.     half    facing      = saturate(dot(normViewerDir,normal));
  742. #else
  743.     half    facing      = saturate(dot(normViewerDir,normalSmooth));
  744. #endif
  745.     half    fresnel     = Fresnel(facing,GPU_PARAM_ID_WATER_PARAMS.m_MiscParams.x,GPU_PARAM_ID_WATER_PARAMS.m_MiscParams.y);   
  746.  
  747.  
  748.     S_LightAccumCtx     lightAccCtx;
  749.     S_ShadingParams     shadingParams = (S_ShadingParams)0;
  750.     S_MaterialParams    materialParams;
  751.  
  752.  
  753.     shadingParams.m_Normal          = normal;//Smooth;
  754.     shadingParams.m_ToViewer        = normViewerDir;
  755.     shadingParams.m_Refl            = R;
  756.     shadingParams.m_WorldPos        = input.WorldPosAndDepth.xyz;
  757.     shadingParams.m_WorldDist       = length(input.ToViewer);
  758.     shadingParams.m_BloomEmissivity = 0;
  759.  
  760.     materialParams.m_MatDiff        = 1;
  761.     materialParams.m_MatParams      = half4(45,1,1,0);
  762.  
  763.     // spec power
  764.     materialParams.m_MatParams.x    = GPU_PARAM_ID_WATER_PARAMS.m_Params.z;
  765.  
  766.  
  767.     BeginLightingAccumulation(lightAccCtx,shadingParams,materialParams,GPU_PARAM_ID_GLOBAL_LIGHTING);
  768.  
  769.     lightAccCtx.m_ShadowMask = sunShadowMask;
  770.  
  771.     AccumulateGlobalLighting(lightAccCtx,GPU_PARAM_ID_GLOBAL_LIGHTING,shadingParams,materialParams);
  772.  
  773.     EndLightingAccumulation(lightAccCtx,shadingParams,materialParams,GPU_PARAM_ID_GLOBAL_LIGHTING);
  774.  
  775.  
  776.     half3   litColor    = lightAccCtx.m_Diff;
  777.     half3   finalRefr   = lerp(GPU_PARAM_ID_WATER_PARAMS.m_ScatterColor.xyz,refr * extinction,invInScatter);
  778.     half    fakeLight   = 0.5 + 0.5 * saturate(dot(normalSmooth,GPU_PARAM_ID_GLOBAL_LIGHTING.m_LightDir));
  779.     half4   foamTex     = NXTex2D(GPU_SAMPLER_ID_DIFFUSE,input.UV0UV1.xy * 20);
  780.     half3   foamLit     = foamTex.xyz * (lightAccCtx.m_Diff + lightAccCtx.m_Amb);
  781.  
  782.     litColor = lerp(finalRefr,refl,fresnel) + lightAccCtx.m_Spec;
  783.     litColor = lerp(litColor,foamLit,input.Foam);
  784.  
  785.     half3 result = FinalizeColorOutput(litColor,0,shadingParams,lightAccCtx,GPU_PARAM_ID_GLOBAL_LIGHTING);
  786.  
  787.     result = lerp(refrFlat,result,edgeSoftening);
  788.  
  789.     return half4(result,0);
  790. }
  791. //*******************************************************************************************
  792.  
  793.  
  794. //
  795. // PS_TerrainDynWater()
  796. //
  797. //
  798. //*******************************************************************************************
  799. half4 PS_TerrainDynWater(S_VSOutputTerrainDynWater input NX_IMPORT_VPOS) : COLOR0
  800. {
  801.     S_WaterShadingParams params;
  802.  
  803.     float3  normal  = normalize(input.Normal);
  804.  
  805.     #if 0
  806.     {
  807.         S_WavesEvalCtx  wavesEvalCtx;
  808.         float3          waveSamplePos   = input.WorldPosAndDepth.xyz;
  809.         float           time            = GPU_PARAM_ID_TIME;
  810.  
  811.  
  812.         ResetWavesEvalCtx(wavesEvalCtx);       
  813.  
  814.         wavesEvalCtx.Normal = normal;
  815.  
  816. //      waveSamplePos.xz += -input.Params2.xy * fmod(time,20) * 10;
  817.  
  818. //      EvalWavesByVelocity(input.WorldPosAndDepth.xyz,-input.Params2.xy,input.Params.z,time,input.Params.w,5,wavesEvalCtx);
  819.         EvalWavesByVelocity(waveSamplePos,-input.Params2.xy,input.Params.z,time,input.Params.w,15,wavesEvalCtx);
  820.  
  821.  
  822.         half3 wnormal   = normalize(wavesEvalCtx.Normal);
  823.         half3 toViewer  = normalize(input.ToViewer);
  824.  
  825.         normal = wnormal;
  826.  
  827.  
  828. //      return wnormal.xyzz;
  829. //      return saturate(dot(wnormal,toViewer));
  830.     }
  831. #endif
  832.  
  833.  
  834.  
  835.     float2  UVScreen        = input.UVScreenProj.xy / input.UVScreenProj.w;
  836.     float3  binormal        = normalize(cross(float3(1,0,0),normal));
  837.     float3  tangent         = normalize(cross(normal,binormal));
  838.     float   distance        = length(input.ToViewer.xyz);
  839.     half    nrmMapStrength  = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_MiscParams.w;
  840.  
  841.     half3   layer0nrmA      = NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER0,input.UV0.xy);
  842.     half3   layer0nrmB      = NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER0,input.UV0.zw);
  843.     half3   layer0nrm       = UnpackTexNormal(lerp(layer0nrmA,layer0nrmB,input.Params.x).xyz);
  844.  
  845.     half3   layer1nrmA      = NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER1,input.UV1.xy);
  846.     half3   layer1nrmB      = NXTex2D(GPU_SAMPLER_ID_NORMALS_LAYER1,input.UV1.zw);
  847.     half3   layer1nrm       = UnpackTexNormal(lerp(layer1nrmA,layer1nrmB,input.Params.y).xyz);
  848.  
  849.     half3   finalNrm        = MixSignedNormals(layer0nrm,layer1nrm);
  850.     half3   normalBump      = normalize(finalNrm.x * tangent + finalNrm.y * binormal + finalNrm.z * normal * nrmMapStrength);
  851.  
  852.     float   refrBumpScale   = GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_ShadingParams.w * (1 - saturate(distance / 200));
  853.     half2   refrBumpUVOffs  = normalBump.xz * refrBumpScale;
  854.  
  855.    
  856.     params.WorldPosAndDepth = input.WorldPosAndDepth;
  857.     params.Normal           = normal;
  858.     params.NormalBump       = normalBump;
  859.     params.ToViewer         = input.ToViewer.xyz;
  860.     params.WaterDepth       = input.Params.z;
  861.     params.UVScreen         = UVScreen;
  862.     params.RefrColorFlat    = NXTex2DLod(GPU_SAMPLER_ID_AUX_SCREENSPACE_COLOR,UVScreen.xyyy);
  863.     params.RefrColorBump    = NXTex2DLod(GPU_SAMPLER_ID_AUX_SCREENSPACE_COLOR,(UVScreen + refrBumpUVOffs).xyyy);
  864.    
  865.  
  866.     //
  867.     // calc opacity for LOD cross-fading
  868.     //
  869. #if 1
  870.     half    LODDistFade = saturate(max(length(input.ToViewer.xyz) - GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_MiscParams.x,0) * GPU_PARAM_ID_TERRAIN_WATER_PARAMS.m_MiscParams.z);
  871. #else
  872.     half    LODDistFade = params.RefrColorFlat.a;
  873. #endif
  874.     params.Opacity = step(LODDistFade,NXTex2D(GPU_SAMPLER_ID_DITHER_MASK,NX_GET_VPOS(input) * (1.0f / DITHER_TEX_SIZE)).a * (255.0 / 64));
  875. //  params.Opacity = 1;
  876.  
  877.  
  878.     return half4(EvalWaterShading(params),0);
  879. }
  880. //*******************************************************************************************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement