diff options
| author | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
| commit | 79b3462799c28af8ba586349bd671b1b56e72353 (patch) | |
| tree | 3b06e36c390254c0dc7f3733a0d32af213d87293 /test/d3d10/ocean_surface.fx | |
| download | waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.zip | |
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'test/d3d10/ocean_surface.fx')
| -rw-r--r-- | test/d3d10/ocean_surface.fx | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/test/d3d10/ocean_surface.fx b/test/d3d10/ocean_surface.fx new file mode 100644 index 0000000..4a4a8ce --- /dev/null +++ b/test/d3d10/ocean_surface.fx @@ -0,0 +1,446 @@ +// 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_SM4 + +#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 }; +#include "GFSDK_WaveWorks_Quadtree.fxh" + +#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_SAMPLER(Label,TextureLabel,Regoff) sampler Label; texture2D TextureLabel; +#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_CONSTANT(Type,Label,Regoff) Type Label; +#define GFSDK_WAVEWORKS_BEGIN_ATTR_VS_CBUFFER(Label) cbuffer Label { +#define GFSDK_WAVEWORKS_END_ATTR_VS_CBUFFER }; + +#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_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 }; +#include "GFSDK_WaveWorks_Attributes.fxh" + +//------------------------------------------------------------------------------------ +// Global variables +//------------------------------------------------------------------------------------ + +// Constant +float4x4 g_matViewProj; + +float3 g_SkyColor; +float3 g_DeepColor; +float3 g_BendParam = {0.1f, -0.4f, 0.2f}; + +float3 g_SunDir = {0.936016f, -0.343206f, 0.0780013f}; +float3 g_SunColor = {1.0f, 1.0f, 0.6f}; +float g_Shineness = 20.0f; +float3 g_WaterDeepColor={0.0,0.4,0.6}; +float3 g_WaterScatterColor={0.0,0.7,0.6}; +float3 g_WaterSpecularColor={1,0.8,0.5}; +float2 g_WaterColorIntensity={0.2,0.1}; +float g_WaterSpecularIntensity = 0.7f; + +float3 g_FoamColor = {0.90f, 0.95f, 1.0f}; +float3 foam_underwater_color = {0.90f, 0.95f, 1.0f}; + +//----------------------------------------------------------------------------------- +// Texture & Samplers +//----------------------------------------------------------------------------------- +texture1D g_texColorMap; +texture2D g_texBufferMap; +textureCUBE g_texCubeMap; +texture2D g_texFoamIntensityMap; +texture2D g_texFoamDiffuseMap; + +// Blending map for ocean color +sampler g_samplerColorMap = +sampler_state +{ + Filter = MIN_MAG_LINEAR_MIP_POINT; + AddressU = Clamp; +}; + +// Standard trilinear sampler +sampler g_samplerTrilinear = +sampler_state +{ + Filter = MIN_MAG_MIP_LINEAR;//ANISOTROPIC; + AddressU = Wrap; + AddressV = Wrap; + MaxAnisotropy = 1; +}; + +// Environment map +sampler g_samplerCubeMap = +sampler_state +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Clamp; + AddressV = Clamp; + AddressW = Clamp; +}; + +struct VS_OUTPUT +{ + float4 pos_clip : SV_Position; + GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp; + float3 world_displacement: TEXCOORD4; + float3 world_pos_undisplaced: TEXCOORD5; +}; + +//----------------------------------------------------------------------------- +// Name: OceanWaveVS +// Type: Vertex shader +// Desc: +//----------------------------------------------------------------------------- +VS_OUTPUT OceanWaveVS(GFSDK_WAVEWORKS_VERTEX_INPUT In) +{ + GFSDK_WAVEWORKS_VERTEX_OUTPUT NV_ocean = GFSDK_WaveWorks_GetDisplacedVertex(In); + VS_OUTPUT Output; + + Output.NV_ocean_interp = NV_ocean.interp; + Output.pos_clip = mul(float4(NV_ocean.pos_world,1), g_matViewProj); + Output.world_displacement = NV_ocean.world_displacement; + Output.world_pos_undisplaced = NV_ocean.pos_world - NV_ocean.world_displacement; + return Output; +} + +//----------------------------------------------------------------------------- +// Name: OceanWavePS +// Type: Pixel shader +// Desc: +//----------------------------------------------------------------------------- +float4 OceanWavePS(VS_OUTPUT In) : SV_Target +{ + GFSDK_WAVEWORKS_SURFACE_ATTRIBUTES surface_attributes = GFSDK_WaveWorks_GetSurfaceAttributes(In.NV_ocean_interp); + + float fresnel_factor; + float diffuse_factor; + float specular_factor; + float scatter_factor; + + float3 pixel_to_light_vector=g_SunDir; + float3 pixel_to_eye_vector=surface_attributes.eye_dir; + float3 reflected_eye_to_pixel_vector = reflect(-surface_attributes.eye_dir, surface_attributes.normal); + + + float cos_angle = dot(surface_attributes.normal, surface_attributes.eye_dir); + // ramp.x for fresnel term. ramp.y for atmosphere blending + float3 ramp = g_texColorMap.Sample(g_samplerColorMap, cos_angle).xyz; + // A worksaround to deal with "indirect reflection vectors" (which are rays requiring multiple + // reflections to reach the sky). + if (reflected_eye_to_pixel_vector.z < g_BendParam.x) + ramp = lerp(ramp, g_BendParam.z, (g_BendParam.x - reflected_eye_to_pixel_vector.z)/(g_BendParam.x - g_BendParam.y)); + reflected_eye_to_pixel_vector.z = max(0, reflected_eye_to_pixel_vector.z); + + + + // 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=0.01*max(0,In.world_displacement.z*0.001+0.3); + + + // the waves that lie between camera and light projection on water plane generate maximal amount of double refracted light + scatter_factor*=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 + scatter_factor*=pow(max(0.0,0.5-0.5*dot(pixel_to_light_vector,surface_attributes.normal)),3.0); + + + // water crests gather more light than lobes, so more light is scattered under the crests + scatter_factor+=2.0*g_WaterColorIntensity.y*max(0,In.world_displacement.z*0.001+0.3)* + // the scattered light is best seen if observing direction is normal to slope surface + max(0,dot(pixel_to_eye_vector,surface_attributes.normal)); + + + // calculating fresnel factor + //float r=(1.2-1.0)/(1.2+1.0); + //fresnel_factor = max(0.0,min(1.0,r+(1.0-r)*pow(1.0-dot(surface_attributes.normal,pixel_to_eye_vector),2.0))); + + //float r=(1.0 - 1.13)*(1.0 - 1.13)/(1.0 + 1.13); + //fresnel_factor = r + (1.0-r)*pow(saturate(1.0 - dot(surface_attributes.normal,pixel_to_eye_vector)),4.0); + + fresnel_factor=ramp.x; + + // calculating diffuse intensity of water surface itself + diffuse_factor=g_WaterColorIntensity.x+g_WaterColorIntensity.y*max(0,dot(pixel_to_light_vector,surface_attributes.normal)); + + float3 refraction_color=diffuse_factor*g_WaterDeepColor; + + // adding color that provide foam bubbles spread in water + refraction_color += foam_underwater_color*saturate(surface_attributes.foam_turbulent_energy*0.2); + + // adding scatter light component + refraction_color+=g_WaterScatterColor*scatter_factor; + + // reflection color + float3 reflection_color = lerp(g_SkyColor,g_texCubeMap.Sample(g_samplerCubeMap, reflected_eye_to_pixel_vector).xyz, ramp.y); + + // applying Fresnel law + float3 water_color = lerp(refraction_color,reflection_color,fresnel_factor); + + + // applying surface foam provided by turbulent energy + + // low frequency foam map + float foam_intensity_map_lf = 1.0*g_texFoamIntensityMap.Sample(g_samplerTrilinear, 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_texFoamIntensityMap.Sample(g_samplerTrilinear, 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_texFoamIntensityMap.Sample(g_samplerTrilinear, 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_texFoamDiffuseMap.Sample(g_samplerTrilinear, In.world_pos_undisplaced.xy).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);//*(1.0 + surface_attributes.foam_surface_folding*0.5); + + foam_intensity = pow(foam_intensity, 0.7); + foam_intensity = saturate(foam_intensity*foam_bubbles*1.0);// + 0.1*foam_bubbles*saturate(surface_attributes.foam_surface_folding))); + + + // foam diffuse color + float foam_diffuse_factor=max(0,0.8+max(0,0.2*dot(pixel_to_light_vector,surface_attributes.normal))); + + + water_color = lerp(water_color,foam_diffuse_factor*float3(1.0,1.0,1.0),foam_intensity); + + // calculating specular factor + reflected_eye_to_pixel_vector=-pixel_to_eye_vector+2.0*dot(pixel_to_eye_vector,surface_attributes.normal)*surface_attributes.normal; + specular_factor=pow(max(0,dot(pixel_to_light_vector,reflected_eye_to_pixel_vector)),g_Shineness); + + // adding specular component + //water_color+=g_WaterSpecularIntensity*specular_factor*g_WaterSpecularColor*/*fresnel_factor*/saturate(1.0-5.0*foam_intensity); + + return float4(water_color, 1); + + +} + +float4 g_PatchColor; + +float4 OceanWireframePS(VS_OUTPUT In) : SV_Target +{ + return g_PatchColor; +} + +//-------------------------------------------------------------------------------------- +// DepthStates +//-------------------------------------------------------------------------------------- +DepthStencilState EnableDepth +{ + DepthEnable = TRUE; + DepthWriteMask = ALL; + DepthFunc = LESS_EQUAL; + StencilEnable = FALSE; +}; + +DepthStencilState AlwaysDepth +{ + DepthEnable = TRUE; + DepthWriteMask = ALL; + DepthFunc = ALWAYS; + StencilEnable = FALSE; +}; + +//-------------------------------------------------------------------------------------- +// RasterStates +//-------------------------------------------------------------------------------------- +RasterizerState Solid +{ + FillMode = SOLID; + CullMode = NONE; + + MultisampleEnable = True; +}; + +//-------------------------------------------------------------------------------------- +// RasterStates +//-------------------------------------------------------------------------------------- +RasterizerState CullFront +{ + FillMode = SOLID; + CullMode = Front; + + MultisampleEnable = True; +}; +RasterizerState Wireframe +{ + FillMode = WIREFRAME; + CullMode = NONE; + + MultisampleEnable = True; +}; + +//-------------------------------------------------------------------------------------- +// BlendStates +//-------------------------------------------------------------------------------------- +BlendState Opaque +{ + BlendEnable[0] = FALSE; + RenderTargetWriteMask[0] = 0xF; +}; + +BlendState Translucent +{ + BlendEnable[0] = TRUE; + RenderTargetWriteMask[0] = 0xF; + + SrcBlend = SRC_ALPHA; + DestBlend = INV_SRC_ALPHA; + BlendOp = Add; +}; + +//----------------------------------------------------------------------------- +// Name: OceanWaveTech +// Type: Technique +// Desc: +//----------------------------------------------------------------------------- +technique10 RenderOceanSurfTech +{ + pass Pass_PatchVS_WavePS + { + SetVertexShader( CompileShader( vs_4_0, OceanWaveVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, OceanWavePS() ) ); + + SetDepthStencilState( EnableDepth, 0 ); + SetRasterizerState( CullFront ); + SetBlendState( Opaque, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } + + // Wireframe + pass Pass_PatchWireframe + { + SetVertexShader( CompileShader( vs_4_0, OceanWaveVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, OceanWireframePS() ) ); + + SetDepthStencilState( EnableDepth, 0 ); + SetRasterizerState( Wireframe ); + SetBlendState( Opaque, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } +} + + + +// Buffer selector +int g_BufferType; + +//----------------------------------------------------------------------------- +// Following only for debug +//----------------------------------------------------------------------------- +struct VS_DEBUG_OUTPUT +{ + float4 pos_clip : SV_Position; + float2 tex_coord : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Name: DebugTextureVS +// Type: Vertex shader +//----------------------------------------------------------------------------- +VS_DEBUG_OUTPUT DisplayBufferVS(float4 vPos : POSITION, float2 vTexCoord : TEXCOORD0) +{ + VS_DEBUG_OUTPUT Output; + + Output.pos_clip = vPos; + Output.tex_coord = vTexCoord; + + return Output; +} + +//----------------------------------------------------------------------------- +// Name: DisplayBufferPS +// Type: Pixel shader +//----------------------------------------------------------------------------- +float4 DisplayBufferPS(VS_DEBUG_OUTPUT In) : SV_Target +{ + // FXC in Mar09 DXSDK can't compile the following code correctly. + + //if (g_BufferType == 1) + // return tex2Dlod(g_samplerHeightMap, float4(In.tex_coord, 0, 0)) * 0.005f + 0.5f; + //else if (g_BufferType == 2) + //{ + // float2 grad = tex2Dlod(g_samplerGradientMap, float4(In.tex_coord, 0, 0)).xy; + // float3 normal = float3(grad, g_TexelLength_x2); + // return float4(normalize(normal) * 0.5f + 0.5f, 0); + //} + //else if (g_BufferType == 3) + //{ + // float fold = tex2D(g_samplerGradientMap, In.tex_coord).w; + // return fold * 0.5f; + //} + //else + // return 0; + + //float4 height = tex2Dlod(g_samplerHeightMap, float4(In.tex_coord, 0, 0)) * 0.005f + 0.5f; + + //float4 grad = tex2Dlod(g_samplerGradientMap, float4(In.tex_coord, 0, 0)); + //float4 normal = float4(normalize(float3(grad.xy, g_TexelLength_x2)) * 0.5f + 0.5f, 0); + + //float4 fold = grad.w * 0.5f; + + //float4 color = (g_BufferType < 2) ? height : ((g_BufferType < 3) ? normal : fold); + //return color; + return g_texBufferMap.Sample(g_samplerColorMap, In.tex_coord); +} + +//----------------------------------------------------------------------------- +// Name: DisplayBufferTech +// Type: Technique +// Desc: For debug and performance tuning purpose: outputs a floating-point +// on screen. +//----------------------------------------------------------------------------- +technique10 DisplayBufferTech +{ + pass P0 + { + SetVertexShader( CompileShader( vs_4_0, DisplayBufferVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, DisplayBufferPS() ) ); + + SetDepthStencilState( AlwaysDepth, 0 ); + SetRasterizerState( Solid ); + SetBlendState( Translucent, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } +} |