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
|
// 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.
//
#ifndef _NVWAVEWORKS_SPECTRUM_UTIL_H
#define _NVWAVEWORKS_SPECTRUM_UTIL_H
#ifndef GRAV_ACCEL
#define GRAV_ACCEL 9.810f // The acceleration of gravity, m/s^2
#endif
#ifndef PI
#define PI 3.1415926536f
#endif
// Phillips Spectrum
// K: normalized wave vector, W: wind direction, v: wind velocity, a: constant affecting factor
FN_QUALIFIER float FN_NAME(Phillips)(float2 K, float2 W, float v, float a, float dir_depend, float small_wave_fraction)
{
// largest possible wave from constant wind of velocity v
float l = v * v / GRAV_ACCEL;
// damp out waves with very small length w << l
float w = small_wave_fraction * l;
float Ksqr = K.x * K.x + K.y * K.y;
float Kcos = K.x * W.x + K.y * W.y;
float phillips = a * expf(-1 / (l * l * Ksqr)) / (Ksqr * Ksqr * Ksqr) * (Kcos * Kcos);
// filter out waves moving opposite to wind
if (Kcos < 0)
phillips *= (1.0f-dir_depend);
// damp out waves with very small length w << l
return phillips * expf(-Ksqr * w * w);
}
// Upper-bound estimate of integral of Phillips Spectrum power over disc-shaped 2D wave vector space of radius k centred on K = {0,0}
// There is no wind velocity parameter, since the integral is rotationally invariant
//
FN_QUALIFIER float FN_NAME(UpperBoundPhillipsIntegral)(float k, float v, float a, float dir_depend, float /*small_wave_fraction*/)
{
if(k <= 0.f) return 0.f;
// largest possible wave from constant wind of velocity v
float l = v * v / GRAV_ACCEL;
// integral has analytic form, yay!
float phillips_integ = 0.5f * PI * a * l * l * expf(-1.f/(k*k*l*l));
// dir_depend affects half the domain
phillips_integ *= (1.0f-0.5f*dir_depend);
// we may safely ignore 'small_wave_fraction' for an upper-bound estimate
return phillips_integ;
}
// Rectangular window, parameterised by in (i) and out (o) thresholds
FN_QUALIFIER float FN_NAME(RectWindow)(float r, float i, float o)
{
if(r < i)
{
return 0.f;
}
else if(r < o)
{
return 1.f;
}
else
{
return 0.f;
}
}
FN_QUALIFIER float FN_NAME(CalcH0)( int nx, int ny,
float2 K,
float window_in, float window_out,
float2 wind_dir, float v, float dir_depend,
float a,
float norm,
float small_wave_fraction
)
{
// distance from DC, in wave-numbers
float nr = sqrtf(float(nx*nx)+float(ny*ny));
float window = sqrtf(FN_NAME(RectWindow)(nr, window_in, window_out));
float amplitude = (K.x == 0 && K.y == 0) ? 0 : sqrtf(FN_NAME(Phillips)(K, wind_dir, v, a, dir_depend, small_wave_fraction));
amplitude *= norm;
amplitude *= window;
amplitude *= 0.7071068f;
return amplitude;
}
#endif //_NVWAVEWORKS_SPECTRUM_UTIL_H
|