summaryrefslogtreecommitdiff
path: root/sample/d3d11/ocean_surface.fx
diff options
context:
space:
mode:
authorJason Maskell <[email protected]>2016-05-12 10:58:15 +0200
committerJason Maskell <[email protected]>2016-05-12 10:58:15 +0200
commit72b21c69e32c73abf3a18b0e962746e64faebba4 (patch)
treecd22b1b298bc865c3ae6037e8eb89a64a94203ea /sample/d3d11/ocean_surface.fx
parentMerge branch 'master' of https://github.com/NVIDIAGameWorks/WaveWorks (diff)
downloadwaveworks_archive-72b21c69e32c73abf3a18b0e962746e64faebba4.tar.xz
waveworks_archive-72b21c69e32c73abf3a18b0e962746e64faebba4.zip
Restructuring starts. Got some initial CMake problems sorted. Need to extend.
Diffstat (limited to 'sample/d3d11/ocean_surface.fx')
-rw-r--r--sample/d3d11/ocean_surface.fx791
1 files changed, 0 insertions, 791 deletions
diff --git a/sample/d3d11/ocean_surface.fx b/sample/d3d11/ocean_surface.fx
deleted file mode 100644
index c34c65e..0000000
--- a/sample/d3d11/ocean_surface.fx
+++ /dev/null
@@ -1,791 +0,0 @@
-// This code contains NVIDIA Confidential Information and is disclosed
-// under the Mutual Non-Disclosure Agreement.
-//
-// Notice
-// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
-// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
-// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
-// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// NVIDIA Corporation assumes no responsibility for the consequences of use of such
-// information or for any infringement of patents or other rights of third parties that may
-// result from its use. No license is granted by implication or otherwise under any patent
-// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
-// expressly authorized by NVIDIA. Details are subject to change without notice.
-// This code supersedes and replaces all information previously supplied.
-// NVIDIA Corporation products are not authorized for use as critical
-// components in life support devices or systems without express written approval of
-// NVIDIA Corporation.
-//
-// Copyright � 2008- 2013 NVIDIA Corporation. All rights reserved.
-//
-// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
-// rights in and to this software and related documentation and any modifications thereto.
-// Any use, reproduction, disclosure or distribution of this software and related
-// documentation without an express license agreement from NVIDIA Corporation is
-// strictly prohibited.
-//
-
-#define GFSDK_WAVEWORKS_SM5
-#define GFSDK_WAVEWORKS_USE_TESSELLATION
-
-#define GFSDK_WAVEWORKS_DECLARE_GEOM_VS_CONSTANT(Type,Label,Regoff) Type Label;
-#define GFSDK_WAVEWORKS_BEGIN_GEOM_VS_CBUFFER(Label) cbuffer Label {
-#define GFSDK_WAVEWORKS_END_GEOM_VS_CBUFFER };
-
-#define GFSDK_WAVEWORKS_DECLARE_GEOM_HS_CONSTANT(Type,Label,Regoff) Type Label;
-#define GFSDK_WAVEWORKS_BEGIN_GEOM_HS_CBUFFER(Label) cbuffer Label {
-#define GFSDK_WAVEWORKS_END_GEOM_HS_CBUFFER };
-
-#include "GFSDK_WaveWorks_Quadtree.fxh"
-
-#define GFSDK_WAVEWORKS_DECLARE_ATTR_DS_CONSTANT(Type,Label,Regoff) Type Label;
-#define GFSDK_WAVEWORKS_BEGIN_ATTR_DS_CBUFFER(Label) cbuffer Label {
-#define GFSDK_WAVEWORKS_END_ATTR_DS_CBUFFER };
-#define GFSDK_WAVEWORKS_DECLARE_ATTR_DS_SAMPLER(Label,TextureLabel,Regoff) sampler Label; texture2D TextureLabel;
-
-#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_CONSTANT(Type,Label,Regoff) Type Label;
-#define GFSDK_WAVEWORKS_BEGIN_ATTR_PS_CBUFFER(Label) cbuffer Label {
-#define GFSDK_WAVEWORKS_END_ATTR_PS_CBUFFER };
-#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER(Label,TextureLabel,Regoff) sampler Label; texture2D TextureLabel;
-
-#include "GFSDK_WaveWorks_Attributes.fxh"
-#include "common.fx"
-
-//------------------------------------------------------------------------------------
-// Global variables
-//------------------------------------------------------------------------------------
-
-// Constant
-
-float3 g_LightPosition;
-float3 g_CameraPosition;
-float4x4 g_ModelViewMatrix;
-float4x4 g_ModelViewProjectionMatrix;
-float4x4 g_LightModelViewProjectionMatrix;
-float4x4 g_WorldToTopDownTextureMatrix;
-
-float3 g_WaterTransmittance = {0.065,0.028,0.035}; // light absorption per meter for coastal water, taken from here: http://www.seafriends.org.nz/phgraph/water.htm http://www.seafriends.org.nz/phgraph/phdwg34.gif
-float3 g_WaterScatterColor = {0.0,0.7,0.3};
-float3 g_WaterSpecularColor = {1.1,0.8,0.5};
-float g_WaterScatterIntensity = 0.1;
-float g_WaterSpecularIntensity = 10.0f;
-
-float3 g_FoamColor = {0.90f, 0.95f, 1.0f};
-float3 g_FoamUnderwaterColor = {0.0,0.7,0.6};
-
-float g_WaterSpecularPower = 200.0;
-float3 g_AtmosphereBrightColor = {1.1,0.9,0.6};
-float3 g_AtmosphereDarkColor = {0.4,0.4,0.5};
-float g_FogDensity = 1.0f/1500.0f;
-
-float4 g_WireframeColor = {1.0,1.0,1.0,1.0};
-
-float2 g_WindDirection;
-
-float2 g_ScreenSizeInv;
-float g_ZNear;
-float g_ZFar;
-float g_Time;
-
-float g_GerstnerSteepness;
-float g_BaseGerstnerAmplitude;
-float g_BaseGerstnerWavelength;
-float g_BaseGerstnerSpeed;
-float g_BaseGerstnerParallelness;
-float g_enableShoreEffects;
-
-float g_Wireframe;
-float2 g_WinSize = {1920.0,1080.0};
-
-//-----------------------------------------------------------------------------------
-// Texture & Samplers
-//-----------------------------------------------------------------------------------
-texture2D g_LogoTexture;
-Texture2D g_ReflectionTexture;
-Texture2D g_RefractionTexture;
-Texture2D g_RefractionDepthTextureResolved;
-Texture2D g_WaterNormalMapTexture;
-Texture2D g_ShadowmapTexture;
-Texture2D g_FoamIntensityTexture;
-Texture2D g_FoamDiffuseTexture;
-Texture2D g_DataTexture;
-
-// Custom trilinear sampler clamping to custom border color
-sampler SamplerTrilinearBorder =
-sampler_state
-{
- Filter = MIN_MAG_MIP_LINEAR;
- AddressU = Border;
- AddressV = Border;
- BorderColor = float4(20.0,-50.0,0.0,0.0);
-};
-
-struct VS_OUTPUT
-{
- float4 worldspace_position : VSO ;
-};
-
-struct DS_OUTPUT
-{
- float4 positionClip : SV_Position;
- GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp;
- float3 displacementWS: TEXCOORD5;
- float3 positionWS: TEXCOORD6;
- float3 world_pos_undisplaced : TEXCOORD7;
- float3 gerstner_displacement : TEXCOORD8;
- float2 gerstner_sdfUV : TEXCOORD9;
- float gerstner_multiplier : TEXCOORD10;
-};
-
-struct PS_INPUT
-{
- float4 positionClip : SV_Position;
- GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp;
- float3 displacementWS: TEXCOORD5;
- float3 positionWS: TEXCOORD6;
- float3 world_pos_undisplaced : TEXCOORD7;
- float3 gerstner_displacement : TEXCOORD8;
- float2 gerstner_sdfUV : TEXCOORD9;
- float gerstner_multiplier : TEXCOORD10;
- noperspective float3 v_dist : TEXCOORD11;
-};
-
-struct HS_ConstantOutput
-{
- float fTessFactor[3] : SV_TessFactor;
- float fInsideTessFactor : SV_InsideTessFactor;
-};
-
-
-
-static const float kTopDownDataPixelsPerMeter = 256.0f/700.0; // taken from SDF generation source code, the SDF texture size is 256x256, the viewport size is 700x700
-static const float kMaxDepthBelowSea = 50.0f;
-static const float kMaxDistance = 20.0f; // taken from SDF generation code
-static const float kNumWaves = 1.0; // Total number of Gerster waves of different amplitude, speed etc to calculate,
- // i+1-th wave has 20% smaller amplitude,
- // 20% smaller phase and group speed and 20% less parallelity
- // Note that all the waves will share the same gerstnerMultiplierOut (lerping between ocean waves and Gerstner waves) for simplicity
-
-void GetGerstnerVertexAttributes(float3 posWS, out float2 sdfUVOut, out float3 offsetOut, out float gerstnerMultiplierOut)
-{
- // getting UV for fetching SDF texture
- float4 topDownPosition = mul( float4( posWS.xyz, 1), g_WorldToTopDownTextureMatrix );
- float2 uv = mad( topDownPosition.xy/topDownPosition.w, 0.5f, 0.5f );
- uv.y = 1-uv.y;
-
- // initializing the outputs so we can exit early
- sdfUVOut = uv;
- offsetOut = float3 (0.0,0.0,0.0);
- gerstnerMultiplierOut = 0;
-
- // getting SDF
- const float4 tdData = g_DataTexture.SampleLevel(SamplerTrilinearBorder, uv, 0 );
-
- // early out without adding gerstner waves if far from shore
- if((tdData.x >= kMaxDistance - 0.1))
- {
- return;
- }
-
- // initializing variables common to all Gerstner waves
- float phaseShift = g_Time;
- float sdfPhase = tdData.x*kMaxDistance/kTopDownDataPixelsPerMeter;
- float distanceMultiplier = saturate(1.0-tdData.x); // Shore waves linearly fade in on the edges of SDF
- float depthMultiplier = saturate((g_BaseGerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length, we use 0.25 as this parameter also allows shore waves to heighten as the depth decreases
- gerstnerMultiplierOut = distanceMultiplier*depthMultiplier;
-
- // initializing variables to be changed along summing up the waves
- float gerstnerWavelength = g_BaseGerstnerWavelength;
- float gerstnerOmega = 2.0*3.141592 / g_BaseGerstnerWavelength; // angular speed of gerstner wave
- float gerstnerParallelness = g_BaseGerstnerParallelness; // "parallelness" of shore waves. 0 means the waves are parallel to shore, 1 means the waves are parallel to wind gradient
- float gerstnerSpeed = g_BaseGerstnerSpeed; // phase speed of gerstner waves
- float gerstnerAmplitude = g_BaseGerstnerAmplitude;
- float2 windDirection = g_WindDirection;
-
- // summing up the waves
- for(float i = 0.0; i < kNumWaves; i+=1.0)
- {
- float windPhase = dot(windDirection, posWS.xz);
- float gerstnerPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness)/gerstnerWavelength);
- float2 propagationDirection = normalize( lerp(-tdData.zw + windDirection * 0.000001f, g_WindDirection, gerstnerParallelness*gerstnerParallelness));
- float gerstnerGroupSpeedPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness*3.0)/gerstnerWavelength); // letting the group speed phase to be non-parallel to propagation phase, so altering parallelness modificator fot this
-
- float groupSpeedMultiplier = 0.5 + 0.5*cos((gerstnerGroupSpeedPhase + gerstnerOmega*gerstnerSpeed*phaseShift/2.0)/2.7); // Group speed for water waves is half of the phase speed, we allow 2.7 wavelengths to be in wave group, not so much as breaking shore waves lose energy quickly
- float worldSpacePosMultiplier = 0.75 + 0.25*sin(phaseShift*0.3 + 0.5*posWS.x/gerstnerWavelength)*sin(phaseShift*0.4 + 0.5*posWS.y/gerstnerWavelength); // slowly crawling worldspace aligned checkerboard pattern that damps gerstner waves further
- float depthMultiplier = saturate((gerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length
- float gerstnerMultiplier = distanceMultiplier*depthMultiplier*groupSpeedMultiplier*worldSpacePosMultiplier; // final scale factor applied to base Gerstner amplitude and used to mix between ocean waves and shore waves
-
- float steepness = g_GerstnerSteepness;
- float baseAmplitude = gerstnerMultiplier * gerstnerAmplitude; //amplitude gradually increases as wave runs over shallower seabed
- float breakerMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/
-
- // calculating Gerstner offset
- float s,c;
- sincos(gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift, s, c);
- float waveVerticalOffset = s * baseAmplitude;
- offsetOut.y += waveVerticalOffset;
- offsetOut.xz += c * propagationDirection * steepness * baseAmplitude; // trochoidal Gerstner wave
- offsetOut.xz -= propagationDirection * s * baseAmplitude * breakerMultiplier * 2.0; // adding wave forward skew due to its bottom slowing down, so the forward wave front gradually becomes vertical
- float breakerPhase = gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift + 3.141592*0.05;
- float fp = frac(breakerPhase/(3.141592*2.0));
- offsetOut.xz -= 0.5*baseAmplitude*propagationDirection*breakerMultiplier*(saturate(fp*10.0) - saturate(-1.0 + fp*10.0)); // moving breaking area of the wave further forward
-
- // updating the parameters for next wave
- gerstnerWavelength *= 0.66;
- gerstnerOmega /= 0.66;
- gerstnerSpeed *= 0.66;
- gerstnerAmplitude *= 0.66;
- gerstnerParallelness *= 0.66;
- windDirection.xy *= float2(-1.0,1.0)*windDirection.yx; // rotating wind direction
-
- offsetOut.y += baseAmplitude*1.2; // Adding vertical displacement as the wave increases while rolling on the shallow area
- }
-
-}
-
-void GetGerstnerSurfaceAttributes( float2 sdfUV, float2 posWS, out float3 normalOut, out float breakerOut, out float foamTrailOut)
-{
- // initializing the outputs
- normalOut = float3 (0.0,1.0,0.0);
- foamTrailOut = 0.0;
- breakerOut = 0.0;
-
- // getting SDF
- const float4 tdData = g_DataTexture.SampleLevel(SamplerTrilinearBorder, sdfUV, 0 );
-
- // initializing variables common to all Gerstner waves
- float phaseShift = g_Time;
- float sdfPhase = tdData.x*kMaxDistance/kTopDownDataPixelsPerMeter;
- float distanceMultiplier = saturate(1.0-tdData.x); // Shore waves linearly fade in on the edges of SDF
-
- // initializing variables to be changed along summing up the waves
- float gerstnerWavelength = g_BaseGerstnerWavelength;
- float gerstnerOmega = 2.0*3.141592 / g_BaseGerstnerWavelength; // angular speed of gerstner wave
- float gerstnerParallelness = g_BaseGerstnerParallelness; // "parallelness" of shore waves. 0 means the waves are parallel to shore, 1 means the waves are parallel to wind gradient
- float gerstnerSpeed = g_BaseGerstnerSpeed; // phase speed of gerstner waves
- float gerstnerAmplitude = g_BaseGerstnerAmplitude;
- float2 windDirection = g_WindDirection;
-
- // summing up the waves
- for(float i = 0.0; i < kNumWaves; i+=1.0)
- {
- float windPhase = dot(windDirection, posWS.xy);
- float gerstnerPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness)/gerstnerWavelength);
- float2 propagationDirection = normalize( lerp(-tdData.zw + windDirection * 0.000001f, g_WindDirection, gerstnerParallelness*gerstnerParallelness));
- float gerstnerGroupSpeedPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness*3.0)/gerstnerWavelength); // letting the group speed phase to be non-parallel to propagation phase, so altering parallelness modificator fot this
-
- float groupSpeedMultiplier = 0.5 + 0.5*cos((gerstnerGroupSpeedPhase + gerstnerOmega*gerstnerSpeed*phaseShift/2.0)/2.7); // Group speed for water waves is half of the phase speed, we allow 2.7 wavelengths to be in wave group, not so much as breaking shore waves lose energy quickly
- float worldSpacePosMultiplier = 0.75 + 0.25*sin(phaseShift*0.3 + 0.5*posWS.x/gerstnerWavelength)*sin(phaseShift*0.4 + 0.5*posWS.y/gerstnerWavelength); // slowly crawling worldspace aligned checkerboard pattern that damps gerstner waves further
- float depthMultiplier = saturate((gerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length
- float gerstnerMultiplier = distanceMultiplier*depthMultiplier*groupSpeedMultiplier*worldSpacePosMultiplier; // final scale factor applied to base Gerstner amplitude and used to mix between ocean waves and shore waves
-
- float steepness = g_GerstnerSteepness;
- float baseAmplitude = gerstnerMultiplier * gerstnerAmplitude; //amplitude gradually increases as wave runs over shallower seabed
-
- // calculating normal
- float s,c;
- sincos(gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift, s, c);
- normalOut.y -= gerstnerOmega*steepness*baseAmplitude*s;
- normalOut.xz -= gerstnerOmega*baseAmplitude*c*propagationDirection; // orienting normal according to direction of wave propagation. No need to normalize, it is unit length.
-
- // calculating foam parameters
- float breakerMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/
-
- float foamTrailPhase = gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift + 3.141592*0.05; // delaying foam trail a bit so it's following the breaker
- float fp = frac(foamTrailPhase/(3.141592*2.0));
- foamTrailOut += gerstnerMultiplier*breakerMultiplier*(saturate(fp*10.0) - saturate(fp*1.1)); // only breaking waves leave foamy trails
- breakerOut += gerstnerMultiplier*breakerMultiplier*(saturate(fp*10.0) - saturate(-1.0 + fp*10.0)); // making narrow sawtooth pattern
-
- // updating the parameters for next wave
- gerstnerWavelength *= 0.66;
- gerstnerOmega /= 0.66;
- gerstnerSpeed *= 0.66;
- gerstnerAmplitude *= 0.66;
- gerstnerParallelness *= 0.66;
- windDirection.xy *= float2(-1.0,1.0)*windDirection.yx; // rotating wind direction
- }
-}
-
-//-----------------------------------------------------------------------------
-// Name: OceanWaveVS
-// Type: Vertex shader
-// Desc:
-//-----------------------------------------------------------------------------
-VS_OUTPUT OceanWaveVS(GFSDK_WAVEWORKS_VERTEX_INPUT In)
-{
- VS_OUTPUT Output;
- Output.worldspace_position = float4(GFSDK_WaveWorks_GetUndisplacedVertexWorldPosition(In),0.0);
- return Output;
-}
-
-
-//-----------------------------------------------------------------------------
-// Name: HS_Constant
-// Type: Hull shader
-// Desc:
-//-----------------------------------------------------------------------------
-HS_ConstantOutput HS_Constant( InputPatch<VS_OUTPUT, 3> I )
-{
- HS_ConstantOutput O;
- O.fTessFactor[0] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[1].worldspace_position,I[2].worldspace_position);
- O.fTessFactor[1] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[2].worldspace_position,I[0].worldspace_position);
- O.fTessFactor[2] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[0].worldspace_position,I[1].worldspace_position);
- O.fInsideTessFactor = (O.fTessFactor[0] + O.fTessFactor[1] + O.fTessFactor[2])/3.0f;
- return O;
-}
-
-[domain("tri")]
-[partitioning("fractional_odd")]
-[outputtopology("triangle_cw")]
-[patchconstantfunc("HS_Constant")]
-[outputcontrolpoints(3)]
-VS_OUTPUT HS_FlatTriangles( InputPatch<VS_OUTPUT, 3> I, uint uCPID : SV_OutputControlPointID )
-{
- VS_OUTPUT O = (VS_OUTPUT)I[uCPID];
- return O;
-}
-
-//--------------------------------------------------------------------------------------
-// This domain shader applies contol point weighting to the barycentric coords produced by the FF tessellator
-//--------------------------------------------------------------------------------------
-[domain("tri")]
-DS_OUTPUT DS_FlatTriangles_Shore( HS_ConstantOutput HSConstantData, const OutputPatch<VS_OUTPUT, 3> I, float3 f3BarycentricCoords : SV_DomainLocation )
-{
- DS_OUTPUT Output = (DS_OUTPUT)0;
-
- GFSDK_WAVEWORKS_VERTEX_OUTPUT NV_ocean = GFSDK_WaveWorks_GetDisplacedVertexAfterTessellation(I[0].worldspace_position, I[1].worldspace_position, I[2].worldspace_position, f3BarycentricCoords);
-
- float3 gerstnerDisplacement = float3(0,0,0);
- float2 sdfUV = float2(0,0);
- float gerstnerMultiplier = 0;
-
- if(g_enableShoreEffects > 0)
- {
- GetGerstnerVertexAttributes(NV_ocean.pos_world_undisplaced.xzy, sdfUV, gerstnerDisplacement, gerstnerMultiplier);
- }
-
- NV_ocean.world_displacement *= 1.0 - 0.7*gerstnerMultiplier;
- NV_ocean.world_displacement += gerstnerDisplacement.xzy*gerstnerMultiplier;
-
- NV_ocean.pos_world = NV_ocean.pos_world_undisplaced + NV_ocean.world_displacement;
- Output.positionWS = NV_ocean.pos_world;
- Output.displacementWS = NV_ocean.world_displacement;
- Output.positionClip = mul(float4(NV_ocean.pos_world,1.0), g_ModelViewProjectionMatrix);
- Output.world_pos_undisplaced = NV_ocean.pos_world_undisplaced;
- Output.gerstner_displacement = gerstnerDisplacement.xzy;
- Output.gerstner_sdfUV = sdfUV;
- Output.gerstner_multiplier = gerstnerMultiplier;
- Output.NV_ocean_interp = NV_ocean.interp;
-
- return Output;
-}
-
-//--------------------------------------------------------------------------------------
-// This geometry shader enables solid wireframe mode
-//--------------------------------------------------------------------------------------
-[maxvertexcount(3)]
-void GSSolidWire( triangle DS_OUTPUT input[3], inout TriangleStream<PS_INPUT> outStream )
-{
- PS_INPUT output;
-
- float2 p0 = g_WinSize * input[0].positionClip.xy/input[0].positionClip.w;
- float2 p1 = g_WinSize * input[1].positionClip.xy/input[1].positionClip.w;
- float2 p2 = g_WinSize * input[2].positionClip.xy/input[2].positionClip.w;
- float2 v0 = p2 - p1;
- float2 v1 = p2 - p0;
- float2 v2 = p1 - p0;
- float area = abs(v1.x*v2.y - v1.y * v2.x);
-
-
-
- // Generate vertices
- output.positionClip = input[0].positionClip;
- output.NV_ocean_interp = input[0].NV_ocean_interp;
- output.displacementWS = input[0].displacementWS;
- output.positionWS = input[0].positionWS;
- output.world_pos_undisplaced = input[0].world_pos_undisplaced;
- output.gerstner_displacement = input[0].gerstner_displacement;
- output.gerstner_sdfUV = input[0].gerstner_sdfUV;
- output.gerstner_multiplier = input[0].gerstner_multiplier;
- output.v_dist = float3(area/length(v0),0,0);
- outStream.Append( output );
-
- output.positionClip = input[1].positionClip;
- output.NV_ocean_interp = input[1].NV_ocean_interp;
- output.displacementWS = input[1].displacementWS;
- output.positionWS = input[1].positionWS;
- output.world_pos_undisplaced = input[1].world_pos_undisplaced;
- output.gerstner_displacement = input[1].gerstner_displacement;
- output.gerstner_sdfUV = input[1].gerstner_sdfUV;
- output.gerstner_multiplier = input[1].gerstner_multiplier;
- output.v_dist = float3(0,area/length(v1),0);
- outStream.Append( output );
-
- output.positionClip = input[2].positionClip;
- output.NV_ocean_interp = input[2].NV_ocean_interp;
- output.displacementWS = input[2].displacementWS;
- output.positionWS = input[2].positionWS;
- output.world_pos_undisplaced = input[2].world_pos_undisplaced;
- output.gerstner_displacement = input[2].gerstner_displacement;
- output.gerstner_sdfUV = input[2].gerstner_sdfUV;
- output.gerstner_multiplier = input[2].gerstner_multiplier;
- output.v_dist = float3(0,0,area/length(v2));
- outStream.Append( output );
-
- outStream.RestartStrip();
-}
-
-float GetRefractionDepth(float2 position)
-{
- return g_RefractionDepthTextureResolved.SampleLevel(SamplerLinearClamp,position,0).r;
-}
-
-// primitive simulation of non-uniform atmospheric fog
-float3 CalculateFogColor(float3 pixel_to_light_vector, float3 pixel_to_eye_vector)
-{
- return lerp(g_AtmosphereDarkColor,g_AtmosphereBrightColor,0.5*dot(pixel_to_light_vector,-pixel_to_eye_vector)+0.5);
-}
-
-//-----------------------------------------------------------------------------
-// Name: OceanWaveShorePS
-// Type: Pixel shader
-// Desc:
-//-----------------------------------------------------------------------------
-float4 OceanWaveShorePS(PS_INPUT In) : SV_Target
-{
- float3 color;
- float3 normal;
- float fresnel_factor;
- float specular_factor;
- float scatter_factor;
- float3 refraction_color;
- float3 reflection_color;
- float4 disturbance_eyespace;
-
-
- float water_depth;
-
- float3 water_vertex_positionWS = In.positionWS.xzy;
-
- float3 pixel_to_light_vector = normalize(g_LightPosition-water_vertex_positionWS);
- float3 pixel_to_eye_vector = normalize(g_CameraPosition-water_vertex_positionWS);
-
- GFSDK_WAVEWORKS_SURFACE_ATTRIBUTES surface_attributes = GFSDK_WaveWorks_GetSurfaceAttributes(In.NV_ocean_interp);
-
- float3 gerstner_normal = float3(0.0,1.0,0.0);
- float gerstner_breaker = 0;
- float gerstner_foamtrail = 0;
-
- if(g_enableShoreEffects > 0)
- {
- if(In.gerstner_multiplier > 0)
- {
- GetGerstnerSurfaceAttributes( In.gerstner_sdfUV, In.world_pos_undisplaced.xy, gerstner_normal, gerstner_breaker, gerstner_foamtrail);
- }
- surface_attributes.normal = lerp(float3(0,1,0),surface_attributes.normal.xzy, 1.0-0.9*In.gerstner_multiplier*In.gerstner_multiplier); // Leaving just 10% of original open ocean normals in areas affected by shore waves
- surface_attributes.foam_turbulent_energy += gerstner_foamtrail*3.0;
- surface_attributes.foam_wave_hats += gerstner_breaker*15.0; // 15.0*breaker so the breaker foam has rough edges
-
- // using PD normal combination
- normal = normalize(float3(surface_attributes.normal.xz*gerstner_normal.y + gerstner_normal.xz*surface_attributes.normal.y, surface_attributes.normal.y*gerstner_normal.y));
- normal = normal.xzy;
- }
- else
- {
- normal = surface_attributes.normal.xzy;
- }
-
- float3 reflected_eye_to_pixel_vector=-pixel_to_eye_vector+2*dot(pixel_to_eye_vector,normal)*normal;
-
- // calculating pixel position in light space
- float4 positionLS = mul(float4(water_vertex_positionWS,1),g_LightModelViewProjectionMatrix);
- positionLS.xyz/=positionLS.w;
- positionLS.x=(positionLS.x+1)*0.5;
- positionLS.y=(1-positionLS.y)*0.5;
- positionLS.z = min(0.99,positionLS.z);
-
- // calculating shadow multiplier to be applied to diffuse/scatter/specular light components
- float shadow_factor = g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy,positionLS.z* 0.995f).r;
-
- // simulating scattering/double refraction: light hits the side of wave, travels some distance in water, and leaves wave on the other side
- // it's difficult to do it physically correct without photon mapping/ray tracing, so using simple but plausible emulation below
-
- // only the crests of water waves generate double refracted light
- scatter_factor = g_WaterScatterIntensity*
- // the waves that lie between camera and light projection on water plane generate maximal amount of double refracted light
- pow(max(0.0,dot(normalize(float3(pixel_to_light_vector.x,0.0,pixel_to_light_vector.z)),-pixel_to_eye_vector)),2.0)*
- // the slopes of waves that are oriented back to light generate maximal amount of double refracted light
- shadow_factor*pow(max(0.0,1.0-dot(pixel_to_light_vector,normal)),2.0);
-
- scatter_factor += g_WaterScatterIntensity*
- // the scattered light is best seen if observing direction is normal to slope surface
- max(0,dot(pixel_to_eye_vector,normal));//*
-
- // calculating fresnel factor
- float r=(1.0 - 1.33)*(1.0 - 1.33)/((1.0 + 1.33)*(1.0 + 1.33));
- fresnel_factor = r + (1.0-r)*pow(saturate(1.0 - dot(normal,pixel_to_eye_vector)),5.0);
-
-
- // calculating specular factor
- specular_factor=shadow_factor*pow(max(0,dot(pixel_to_light_vector,reflected_eye_to_pixel_vector)),g_WaterSpecularPower);
-
- // calculating disturbance which has to be applied to planar reflections/refractions to give plausible results
- disturbance_eyespace=mul(float4(normal.x,normal.z,0,0),g_ModelViewMatrix);
-
- float2 reflection_disturbance = float2(disturbance_eyespace.x,disturbance_eyespace.z)*0.06;
- float2 refraction_disturbance = float2(-disturbance_eyespace.x,disturbance_eyespace.y)*0.9*
- // fading out refraction disturbance at distance so refraction doesn't look noisy at distance
- (100.0/(100+length(g_CameraPosition-water_vertex_positionWS)));
-
- // picking refraction depth at non-displaced point, need it to scale the refraction texture displacement amount according to water depth
- float refraction_depth = GetRefractionDepth(In.positionClip.xy*g_ScreenSizeInv);
- refraction_depth = g_ZFar*g_ZNear / (g_ZFar-refraction_depth*(g_ZFar-g_ZNear));
- float4 vertex_in_viewspace = mul(float4(In.positionWS.xyz,1),g_ModelViewMatrix);
- water_depth = refraction_depth-vertex_in_viewspace.z;
-
- if(water_depth < 0)
- {
- refraction_disturbance = 0;
- }
- water_depth = max(0,water_depth);
- refraction_disturbance *= min(1.0f,water_depth*0.03);
-
- // getting refraction depth again, at displaced point now
- refraction_depth = GetRefractionDepth(In.positionClip.xy*g_ScreenSizeInv+refraction_disturbance);
- refraction_depth = g_ZFar*g_ZNear / (g_ZFar-refraction_depth*(g_ZFar-g_ZNear));
- vertex_in_viewspace= mul(float4(In.positionWS.xyz,1),g_ModelViewMatrix);
- water_depth = max(water_depth,refraction_depth-vertex_in_viewspace.z);
- water_depth = max(0,water_depth);
- float depth_damper = min(1,water_depth*3.0);
- float depth_damper_sss = min(1,water_depth*0.5);
-
- // getting reflection and refraction color at disturbed texture coordinates
- reflection_color = g_ReflectionTexture.SampleLevel(SamplerLinearClamp,float2(In.positionClip.x*g_ScreenSizeInv.x,1.0-In.positionClip.y*g_ScreenSizeInv.y)+reflection_disturbance,0).rgb;
- refraction_color = g_RefractionTexture.SampleLevel(SamplerLinearClamp,In.positionClip.xy*g_ScreenSizeInv+refraction_disturbance,0).rgb;
-
- // fading fresnel factor to 0 to soften water surface edges
- fresnel_factor*=depth_damper;
-
- // fading fresnel factor to 0 for rays that reflect below water surface
- fresnel_factor*= 1.0 - 1.0*saturate(-2.0*reflected_eye_to_pixel_vector.y);
-
- // applying water absorbtion according to distance that refracted ray travels in water
- // note that we multiply this by 2 since light travels through water twice: from light to seafloor then from seafloor back to eye
- refraction_color.r *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.r);
- refraction_color.g *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.g);
- refraction_color.b *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.b);
-
- // applying water scatter factor
- refraction_color += scatter_factor*shadow_factor*g_WaterScatterColor*depth_damper_sss;
-
- // adding milkiness due to mixed-in foam
- refraction_color += g_FoamUnderwaterColor*saturate(surface_attributes.foam_turbulent_energy*0.2)*depth_damper_sss;
-
- // combining final water color
- color = lerp(refraction_color, reflection_color, fresnel_factor);
- // adding specular
- color.rgb += specular_factor*g_WaterSpecularIntensity*g_WaterSpecularColor*shadow_factor*depth_damper;
-
- // applying surface foam provided by turbulent energy
-
- // low frequency foam map
- float foam_intensity_map_lf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.04*float2(1,1)).x - 1.0;
-
- // high frequency foam map
- float foam_intensity_map_hf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.15*float2(1,1)).x - 1.0;
-
- // ultra high frequency foam map
- float foam_intensity_map_uhf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.3*float2(1,1)).x;
-
- float foam_intensity;
- foam_intensity = saturate(foam_intensity_map_hf + min(3.5,1.0*surface_attributes.foam_turbulent_energy-0.2));
- foam_intensity += (foam_intensity_map_lf + min(1.5,1.0*surface_attributes.foam_turbulent_energy));
-
-
- foam_intensity -= 0.1*saturate(-surface_attributes.foam_surface_folding);
-
- foam_intensity = max(0,foam_intensity);
-
- foam_intensity *= 1.0+0.8*saturate(surface_attributes.foam_surface_folding);
-
- float foam_bubbles = g_FoamDiffuseTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.5).r;
- foam_bubbles = saturate(5.0*(foam_bubbles-0.8));
-
- // applying foam hats
- foam_intensity += max(0,foam_intensity_map_uhf*2.0*surface_attributes.foam_wave_hats);
-
- foam_intensity = pow(foam_intensity, 0.7);
- foam_intensity = saturate(foam_intensity*foam_bubbles*1.0);
-
- foam_intensity*=depth_damper;
-
- // foam diffuse color
- float foam_diffuse_factor = max(0,0.8+max(0,0.2*dot(pixel_to_light_vector,surface_attributes.normal)));
-
- color = lerp(color, foam_diffuse_factor*float3(1.0,1.0,1.0),foam_intensity);
-
- // applying atmospheric fog to water surface
- float fog_factor = min(1,exp(-length(g_CameraPosition-water_vertex_positionWS)*g_FogDensity));
- color = lerp(color, CalculateFogColor(normalize(g_LightPosition),pixel_to_eye_vector).rgb, fresnel_factor*(1.0-fog_factor));
-
- // applying solid wireframe
- float d = min(In.v_dist.x,min(In.v_dist.y,In.v_dist.z));
- float I = exp2(-2.0*d*d);
- return float4(color + g_Wireframe*I*0.5, 1.0);
-}
-
-//-----------------------------------------------------------------------------
-// Name: OceanWaveTech
-// Type: Technique
-// Desc:
-//-----------------------------------------------------------------------------
-technique11 RenderOceanSurfTech
-{
-
- // With shoreline
- pass Pass_Solid_WithShoreline
- {
- SetVertexShader( CompileShader( vs_5_0, OceanWaveVS() ) );
- SetHullShader( CompileShader( hs_5_0, HS_FlatTriangles() ) );
- SetDomainShader( CompileShader( ds_5_0, DS_FlatTriangles_Shore() ) );
- SetGeometryShader( CompileShader( gs_5_0, GSSolidWire() ) );
- SetPixelShader( CompileShader( ps_5_0, OceanWaveShorePS() ) );
-
- SetDepthStencilState( DepthNormal, 0 );
- SetRasterizerState( CullBackMS );
- SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
- }
-}
-
-
-struct VS_LOGO_OUTPUT
-{
- float4 positionClip : SV_Position;
- float2 tex_coord : TEXCOORD1;
-};
-
-//-----------------------------------------------------------------------------
-// Name: DisplayLogoVS
-// Type: Vertex shader
-//-----------------------------------------------------------------------------
-VS_LOGO_OUTPUT DisplayLogoVS(float4 vPos : POSITION, float2 vTexCoord : TEXCOORD0)
-{
- VS_LOGO_OUTPUT Output;
- Output.positionClip = vPos;
- Output.tex_coord = vTexCoord;
- return Output;
-}
-
-//-----------------------------------------------------------------------------
-// Name: DisplayLogoPS
-// Type: Pixel shader
-//-----------------------------------------------------------------------------
-float4 DisplayLogoPS(VS_LOGO_OUTPUT In) : SV_Target
-{
- return g_LogoTexture.Sample(SamplerLinearWrap, In.tex_coord);
-}
-
-//-----------------------------------------------------------------------------
-// Name: DisplayBufferTech
-// Type: Technique
-// Desc: Logo rendering
-//-----------------------------------------------------------------------------
-technique11 DisplayLogoTech
-{
- pass P0
- {
- SetVertexShader( CompileShader( vs_5_0, DisplayLogoVS() ) );
- SetGeometryShader( NULL );
- SetPixelShader( CompileShader( ps_5_0, DisplayLogoPS() ) );
-
- SetDepthStencilState( DepthAlways, 0 );
- SetRasterizerState( NoCullMS );
- SetBlendState( Translucent, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
- }
-}
-
-float4 g_OriginPosition;
-float4 g_ContactPosition;
-float4 g_RayDirection;
-
-struct RAY_CONTACT_VS_INPUT
-{
- float4 PositionWS : POSITION;
-};
-
-struct RAY_CONTACT_VS_OUTPUT
-{
- float4 PositionClip : SV_Position;
-};
-
-//-----------------------------------------------------------------------------
-// Name: ContactVS
-// Type: Vertex shader
-// Desc:
-//-----------------------------------------------------------------------------
-RAY_CONTACT_VS_OUTPUT ContactVS(RAY_CONTACT_VS_INPUT In)
-{
- RAY_CONTACT_VS_OUTPUT Output;
- Output.PositionClip = mul(float4(In.PositionWS.xzy*0.5 + g_ContactPosition.xyz, 1.0), g_ModelViewProjectionMatrix);
- return Output;
-}
-
-//-----------------------------------------------------------------------------
-// Name: RayVS
-// Type: Vertex shader
-// Desc:
-//-----------------------------------------------------------------------------
-RAY_CONTACT_VS_OUTPUT RayVS(RAY_CONTACT_VS_INPUT In)
-{
- RAY_CONTACT_VS_OUTPUT Output;
- Output.PositionClip = mul(float4(g_OriginPosition.xzy + In.PositionWS.y*g_RayDirection.xzy,1.0), g_ModelViewProjectionMatrix);
- return Output;
-}
-
-//-----------------------------------------------------------------------------
-// Name: RayContactPS
-// Type: Pixel shader
-// Desc:
-//-----------------------------------------------------------------------------
-float4 RayContactPS(RAY_CONTACT_VS_OUTPUT In) : SV_Target
-{
- return float4(0, 1.0, 0, 1.0);
-}
-
-//-----------------------------------------------------------------------------
-// Name: RenderRayContactTech
-// Type: Technique
-// Desc:
-//-----------------------------------------------------------------------------
-technique11 RenderRayContactTech
-{
-
- // Contact
- pass Pass_Contact
- {
- SetVertexShader( CompileShader( vs_5_0, ContactVS() ) );
- SetHullShader( NULL );
- SetDomainShader( NULL );
- SetGeometryShader( NULL );
- SetPixelShader( CompileShader( ps_5_0, RayContactPS() ) );
-
- SetDepthStencilState( DepthNormal, 0 );
- SetRasterizerState( NoCullMS );
- SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
- }
-
- // Ray
- pass Pass_Ray
- {
- SetVertexShader( CompileShader( vs_5_0, RayVS() ) );
- SetHullShader( NULL );
- SetDomainShader( NULL );
- SetGeometryShader( NULL );
- SetPixelShader( CompileShader( ps_5_0, RayContactPS() ) );
-
- SetDepthStencilState( DepthNormal, 0 );
- SetRasterizerState( Wireframe );
- SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
- }
-}