1// -*-C++-*-
2#version 120
3
4uniform float fg_Fcoef;
5
6uniform sampler2D texture;
7
8uniform float light_color_base_r;
9uniform float light_color_base_g;
10uniform float light_color_base_b;
11
12uniform float light_color_center_r;
13uniform float light_color_center_g;
14uniform float light_color_center_b;
15
16uniform float intensity_scale;
17
18uniform float pointing_x;
19uniform float pointing_y;
20uniform float pointing_z;
21
22uniform float outer_angle;
23uniform float inner_angle;
24uniform float zero_angle;
25uniform float outer_gain;
26
27uniform float visibility;
28uniform float avisibility;
29uniform float hazeLayerAltitude;
30uniform float eye_alt;
31uniform float terminator;
32
33uniform float osg_SimulationTime;
34
35uniform bool is_directional;
36uniform bool is_strobe;
37
38varying vec3 vertex;
39varying vec3 relPos;
40varying vec3 normal;
41
42varying float flogz;
43
44float Noise2D(in vec2 coord, in float wavelength);
45float fog_func (in float targ, in float alt);
46
47float shape (in vec3 coord, in float noise, in float fade, in float transmission, in float glare, in float lightArg)
48{
49   float r = length (coord) / max(fade, 0.2);
50
51   float angle = noise * 6.2832;
52
53   float sinphi = dot(vec2 (sin(angle),cos(angle)), normalize(coord.yz));
54   float sinterm = sin(mod((sinphi-3.0) * (sinphi-3.0),6.2832));
55   float ray = 0.0;
56   if (sinterm == 0.0)
57   	{ray = 0.0;}
58   else
59	//{ray = clamp(pow(sinterm,10.0),0.0,1.0);
60	{ray = sinterm * sinterm * sinterm * sinterm * sinterm * sinterm * sinterm * sinterm * sinterm * sinterm;
61   	ray *= exp(-40.0 * r * r) * smoothstep(0.8, 1.0,fade) * smoothstep(0.7, 1.0, glare);
62	}
63
64
65
66   float base = exp(-80.0*r*r );
67   float halo = 0.2 * exp(-10.0 * r * r) * (1.0 - smoothstep(-5.0, 0.0, lightArg));
68   float fogEffect =  (1.0-smoothstep(0.4,0.8,transmission));
69   //fogEffect = 1.0;
70
71   //float offset = 0.0;
72   //offset *=0.3;
73   //vec2 offset_vec = vec2 (1.0, 0.0);
74   //offset_vec *= offset;
75
76  // vec2 coord_reduced1 = vec2(coord.y- 1.2* offset_vec.x, coord.z -  1.2 * offset_vec.y);
77   //vec2 coord_reduced2 = vec2(coord.y- 2.0 * offset_vec.x, coord.z - 2.0 * offset_vec.y);
78   //vec3 coord_reduced = coord;
79   //r = min(length (coord_reduced1), 0.8* length(coord_reduced2));
80   //r /= 1.0 - 0.3 * smoothstep(0.0, 0.3, offset);
81
82   float intensity = clamp(base + halo + ray,0.0,1.0) + 0.2 * fogEffect * (1.0-smoothstep(0.3, 0.6,r));
83
84   intensity *=fade;
85
86return intensity;
87}
88
89
90float directional_fade (in float direction)
91{
92
93float arg = clamp(direction, 0.0, 1.0);
94float ia = (1.0 - inner_angle);
95float oa = (1.0 - outer_angle);
96float za = (1.0 - zero_angle);
97
98if (direction > ia) {return 1.0;}
99else if (direction > oa)
100	{return outer_gain + (1.0-outer_gain) * (direction - oa) / (ia - oa);}
101else if (direction > za)
102	{return outer_gain * (direction - za) / (oa - za);}
103else {return 0.0;}
104
105}
106
107float strobe_fade (in float fade)
108{
109
110float time_arg1 = sin(4.0 * osg_SimulationTime);
111float time_arg2 = sin(4.0 * osg_SimulationTime - 0.4);
112
113return fade * 0.825 * (pow(time_arg1, 40.0) + pow(time_arg2, 8.0));
114
115}
116
117
118void main()
119{
120
121float noise = 0.0;
122
123vec3 light_color_base = vec3 (light_color_base_r, light_color_base_g, light_color_base_b);
124vec3 light_color_center = vec3 (light_color_center_r, light_color_center_g, light_color_center_b);
125
126vec3 pointing_vec = vec3 (pointing_x, pointing_y, pointing_z);
127vec3 viewDir = normalize(relPos);
128
129// fogging
130
131float dist = length(relPos);
132float delta_z = hazeLayerAltitude - eye_alt;
133float transmission;
134float vAltitude;
135float delta_zv;
136float H;
137float distance_in_layer;
138float transmission_arg;
139
140 // angle with horizon
141    float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist;
142
143
144    if (delta_z > 0.0) // we're inside the layer
145	{
146	if (ct < 0.0) // we look down
147		{
148		distance_in_layer = dist;
149		vAltitude = min(distance_in_layer,min(visibility, avisibility)) * ct;
150  		delta_zv = delta_z - vAltitude;
151		}
152	else 	// we may look through upper layer edge
153		{
154		H = dist * ct;
155		if (H > delta_z) {distance_in_layer = dist/H * delta_z;}
156		else {distance_in_layer = dist;}
157		vAltitude = min(distance_in_layer,visibility) * ct;
158  		delta_zv = delta_z - vAltitude;
159		}
160	}
161   else // we see the layer from above, delta_z < 0.0
162	{
163	H = dist * -ct;
164	if (H  < (-delta_z))
165		{
166		distance_in_layer = 0.0;
167		delta_zv = 0.0;
168		}
169	else
170		{
171		vAltitude = H + delta_z;
172		distance_in_layer = vAltitude/H * dist;
173		vAltitude = min(distance_in_layer,visibility) * (-ct);
174		delta_zv = vAltitude;
175		}
176	}
177
178
179
180    transmission_arg = (dist-distance_in_layer)/avisibility;
181    if (visibility < avisibility)
182	{
183	transmission_arg = transmission_arg + (distance_in_layer/visibility);
184	}
185   else
186	{
187	transmission_arg = transmission_arg + (distance_in_layer/avisibility);
188	}
189
190
191
192    transmission =  fog_func(transmission_arg, 0.0);
193    float lightArg = terminator/100000.0;
194
195
196float r = length(vertex);
197float mix_factor = 0.3 + 0.7 * smoothstep(0.0, 0.5, r);
198
199// directionality
200
201vec3 nViewDir = normalize(viewDir);
202vec3 nPointingVec = normalize(pointing_vec);
203float direction = dot (nViewDir, nPointingVec );
204
205float fade;
206vec2 offset = vec2 (0.0, 0.0);
207
208if (is_directional)
209	{
210	fade = directional_fade(direction);
211	}
212else
213	{fade = 1.0;}
214
215
216
217// time evolution
218
219if (is_strobe) {fade = strobe_fade (fade);}
220
221fade *= intensity_scale;
222
223// disc size correction for daylight
224
225// shape of the light disc
226float glare = length(light_color_center)/1.7321 * (1.0 - smoothstep(-5.0, 10.0, lightArg));
227float intensity = shape(vertex, noise, fade, transmission, glare, lightArg);
228
229// coloring of the light disc
230vec3 light_color = mix(light_color_base, light_color_center, intensity*intensity);
231
232
233gl_FragColor =   vec4 (light_color.rgb, intensity * transmission );
234// logarithmic depth
235gl_FragDepth = log2(flogz) * fg_Fcoef * 0.5;
236
237}
238