vertex_shader " varying vec3 eye_look_dir; void main() { vec4 eye_pos = vec4(mat3(gl_ModelViewMatrix)*gl_Vertex.xyz, 1); gl_Position = gl_ProjectionMatrix*eye_pos; eye_look_dir = eye_pos.xyz; }"; fragment_shader " uniform vec3 eye_sky_dir; uniform vec3 wavelengths; uniform float scatter_constant; uniform float sun_intensity; uniform float sun_size; uniform bool srgb_output; varying vec3 eye_look_dir; float thickness(float c, float r) { float rc = r*c; return sqrt(2.0*r+1.0+rc*rc)-rc; } float srgb(float c) { if(c<0.0031308) return 12.92*c; else return (1.055)*pow(c, 1.0/2.4)-0.055; } void main() { vec3 n_eye_look_dir = normalize(eye_look_dir); vec3 n_eye_sun_dir = normalize(gl_LightSource[0].position.xyz); if(dot(n_eye_look_dir, eye_sky_dir)>0) { float look_scale = thickness(dot(n_eye_look_dir, eye_sky_dir), 635.0); float sun_scale = thickness(dot(n_eye_sun_dir, eye_sky_dir), 635.0); float c = dot(n_eye_look_dir, n_eye_sun_dir); float scatter_strength = (1.0+c*c)/2.0; vec3 scatter_factor = scatter_constant/pow(wavelengths, vec3(4.0)); vec3 color; float scale_ratio = look_scale/sun_scale; if(scale_ratio>0.999 && scale_ratio<1.001) color = sun_intensity*scatter_strength*scatter_factor*sun_scale*exp(-scatter_factor*sun_scale); else color = sun_intensity*scatter_strength*(exp(-scatter_factor*sun_scale)-exp(-scatter_factor*look_scale))/(1.0-sun_scale/look_scale); if(dot(n_eye_look_dir, n_eye_sun_dir)>cos(sun_size)) color += exp(-scatter_factor*look_scale)*sun_intensity; if(srgb_output) gl_FragColor = vec4(srgb(color.r), srgb(color.g), srgb(color.b), 1.0); else gl_FragColor = vec4(color, 1.0); } else gl_FragColor = vec4(vec3(0.0), 1.0); }";