summaryrefslogtreecommitdiff
path: root/test/gl2_mac/water.glsl
blob: 337803c2804997c54ffcbed78789c4825a05d82a (plain) (blame)
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
<<<VSTEXT>>>
// VSTEXT
#version 330 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;

in vec4 nv_waveworks_quad7;
out GFSDK_WAVEWORKS_VERTEX_OUTPUT VSOutput;

void main()
{
    GFSDK_WAVEWORKS_VERTEX_INPUT i;
    i.nv_waveworks_quad7 = nv_waveworks_quad7;
	VSOutput = GFSDK_WaveWorks_GetDisplacedVertex(i);
	vec3 dwpos = VSOutput.pos_world;
	gl_Position = u_ViewProjMatrix*vec4(dwpos,1.f);

    //gl_Position = nv_waveworks_quad7;
}


<<<FSTEXT>>>
// FSTEXT
#version 330 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 = vec3(0.38, 0.45, 0.56);
vec3		g_BendParam = vec3(0.1, -0.4, 0.2);

vec3		g_SunDir = vec3(0.936016, -0.343206, 0.0780013);
vec3      	g_WaterDeepColor=vec3(0.0,0.4,0.6);
vec3      	g_WaterScatterColor=vec3(0.0,0.7,0.6);
vec2      	g_WaterColorIntensity=vec2(0.2,0.1);

vec3		g_FoamColor = vec3(0.90, 0.95, 1.0);
vec3		g_FoamUnderwaterColor = vec3(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);
}