1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
|
// 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"
//------------------------------------------------------------------------------------
// 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 worldspace_position : VSO ;
};
struct DS_OUTPUT
{
float4 positionClip : SV_Position;
GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp;
float3 world_displacement: TEXCOORD4;
float3 world_pos_undisplaced: TEXCOORD5;
};
struct HS_ConstantOutput
{
// Tess factor for the FF HW block
float fTessFactor[3] : SV_TessFactor;
float fInsideTessFactor : SV_InsideTessFactor;
};
//-----------------------------------------------------------------------------
// 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( 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);
Output.NV_ocean_interp = NV_ocean.interp;
Output.world_displacement = NV_ocean.world_displacement;
Output.positionClip = mul(float4(NV_ocean.pos_world,1.0), g_matViewProj);
Output.world_pos_undisplaced = NV_ocean.pos_world_undisplaced;
return Output;
}
//-----------------------------------------------------------------------------
// Name: OceanWavePS
// Type: Pixel shader
// Desc:
//-----------------------------------------------------------------------------
float4 OceanWavePS(DS_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));
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(DS_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:
//-----------------------------------------------------------------------------
technique11 RenderOceanSurfTech
{
pass Pass_Shaded
{
SetVertexShader( CompileShader( vs_5_0, OceanWaveVS() ) );
SetHullShader( CompileShader( hs_5_0, HS_FlatTriangles() ) );
SetDomainShader( CompileShader( ds_5_0, DS_FlatTriangles() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_5_0, OceanWavePS() ) );
SetDepthStencilState( EnableDepth, 0 );
SetRasterizerState( CullFront );
SetBlendState( Opaque, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
}
pass Pass_Wireframe
{
SetVertexShader( CompileShader( vs_5_0, OceanWaveVS() ) );
SetHullShader( CompileShader( hs_5_0, HS_FlatTriangles() ) );
SetDomainShader( CompileShader( ds_5_0, DS_FlatTriangles() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_5_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 );
}
}
|