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
|
<<<VSTEXT>>>
#version 420 core
#define GFSDK_WAVEWORKS_GL
#define GFSDK_WAVEWORKS_DECLARE_GEOM_VS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#include "GFSDK_WaveWorks_Quadtree.fxh"
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_SAMPLER(Label,TextureLabel,Regoff) uniform sampler2D Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_SAMPLER_TEXTUREARRAY(Label,TextureLabel,Regoff) uniform sampler2DArray Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER(Label,TextureLabel,Regoff) uniform sampler2D Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER_TEXTUREARRAY(Label,TextureLabel,Regoff) uniform sampler2DArray Label;
#include "GFSDK_WaveWorks_Attributes.fxh"
// User uniforms
uniform mat4x4 u_ViewProjMatrix;
struct VSInputStruct
{
GFSDK_WAVEWORKS_VERTEX_INPUT WaveWorksInput;
};
in VSInputStruct VSInput;
out GFSDK_WAVEWORKS_VERTEX_OUTPUT VSOutput;
void main()
{
VSOutput = GFSDK_WaveWorks_GetDisplacedVertex(VSInput.WaveWorksInput);
vec3 dwpos = VSOutput.pos_world;
gl_Position = u_ViewProjMatrix*vec4(dwpos,1.f);
}
<<<FSTEXT>>>
#version 420 core
#define GFSDK_WAVEWORKS_GL
#define GFSDK_WAVEWORKS_DECLARE_GEOM_VS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#include "GFSDK_WaveWorks_Quadtree.fxh"
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_SAMPLER(Label,TextureLabel,Regoff) uniform sampler2D Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_VS_SAMPLER_TEXTUREARRAY(Label,TextureLabel,Regoff) uniform sampler2DArray Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_CONSTANT(Type,Label,Regoff) uniform Type Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER(Label,TextureLabel,Regoff) uniform sampler2D Label;
#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER_TEXTUREARRAY(Label,TextureLabel,Regoff) uniform sampler2DArray Label;
#include "GFSDK_WaveWorks_Attributes.fxh"
// User uniforms
uniform sampler2D g_texFoamIntensityMap;
uniform sampler2D g_texFoamDiffuseMap;
// User local variables
vec3 g_SkyColor = {0.38, 0.45, 0.56};
vec3 g_BendParam = {0.1, -0.4, 0.2};
vec3 g_SunDir = {0.936016, -0.343206, 0.0780013};
vec3 g_WaterDeepColor={0.0,0.4,0.6};
vec3 g_WaterScatterColor={0.0,0.7,0.6};
vec2 g_WaterColorIntensity={0.2,0.1};
vec3 g_FoamColor = {0.90, 0.95, 1.0};
vec3 g_FoamUnderwaterColor = {0.90, 0.95, 1.0};
// in & out variables
in GFSDK_WAVEWORKS_VERTEX_OUTPUT VSOutput;
out vec4 color;
void main()
{
GFSDK_WAVEWORKS_SURFACE_ATTRIBUTES surface_attributes = GFSDK_WaveWorks_GetSurfaceAttributes(VSOutput.interp);
float fresnel_factor;
float diffuse_factor;
float specular_factor;
float scatter_factor;
vec3 pixel_to_light_vector=g_SunDir;
vec3 pixel_to_eye_vector=surface_attributes.eye_dir;
vec3 reflected_eye_to_pixel_vector = reflect(-surface_attributes.eye_dir, surface_attributes.normal);
// 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=1.0*max(0,VSOutput.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(vec3(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,VSOutput.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.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);
// 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));
vec3 refraction_color=diffuse_factor*g_WaterDeepColor;
// adding color that provide foam bubbles spread in water
refraction_color += g_FoamUnderwaterColor*saturate(surface_attributes.foam_turbulent_energy*0.2);
// adding scatter light component
refraction_color+=g_WaterScatterColor*scatter_factor;
// reflection color
vec3 reflection_color = g_SkyColor;
// fading reflection color to half if reflected vector points below water surface
reflection_color.rgb *= 1.0 - 0.5*max(0.0,min(1.0,-reflected_eye_to_pixel_vector.z*4.0));
// applying Fresnel law
vec3 water_color = mix(refraction_color,reflection_color,fresnel_factor);
// applying surface foam provided by turbulent energy
// low frequency foam map
float foam_intensity_map_lf = 1.0*texture(g_texFoamIntensityMap, VSOutput.pos_world_undisplaced.xy*0.04*vec2(1,1)).x - 1.0;
// high frequency foam map
float foam_intensity_map_hf = 1.0*texture(g_texFoamIntensityMap, VSOutput.pos_world_undisplaced.xy*0.15*vec2(1,1)).x - 1.0;
// ultra high frequency foam map
float foam_intensity_map_uhf = 1.0*texture(g_texFoamIntensityMap, VSOutput.pos_world_undisplaced.xy*0.3*vec2(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 = texture(g_texFoamDiffuseMap, VSOutput.pos_world_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);
foam_intensity = pow(foam_intensity, 0.7);
foam_intensity = saturate(foam_intensity*foam_bubbles*1.0);
//
// 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 = mix(water_color,foam_diffuse_factor*vec3(1.0,1.0,1.0),foam_intensity);
color = vec4(water_color,0);
}
|