+Color Sky::get_transmittance(const Vector3 &look_dir)
+{
+ Vector3 pos(0.0f, 0.0f, view_height);
+ Vector3 planet_center(0.0f, 0.0f, -planet.planet_radius);
+
+ Geometry::Ray<float, 3> ray(pos-planet_center, look_dir);
+ Geometry::HyperSphere<float, 3> surface(planet.planet_radius);
+ Geometry::SurfacePoint<float, 3> intersection;
+ if(surface.get_intersections(ray, &intersection, 1))
+ return Color(0.0f);
+
+ Geometry::HyperSphere<float, 3> space(planet.planet_radius+planet.atmosphere_thickness);
+ if(!space.get_intersections(ray, &intersection, 1))
+ return Color(1.0f);
+
+ float step_size = intersection.distance/50;
+
+ Color path_extinction(0.0f);
+ for(unsigned i=0; i<50; ++i)
+ {
+ Vector3 from_center = pos-planet_center;
+ float height = from_center.norm()-planet.planet_radius;
+
+ Color rayleigh_scatter = planet.rayleigh_scatter*exp(height/planet.rayleigh_density_decay);
+ Color mie_scatter = planet.mie_scatter*exp(height/planet.mie_density_decay);
+ Color mie_absorb = planet.mie_absorb*exp(height/planet.mie_density_decay);
+ Color ozone_absorb = planet.ozone_absorb*max(1.0f-abs(height-planet.ozone_band_center)/planet.ozone_band_extent, 0.0f);
+
+ path_extinction = path_extinction+(rayleigh_scatter+mie_scatter+mie_absorb+ozone_absorb)*step_size;
+ pos += look_dir*step_size;
+ }
+
+ return Color(exp(-path_extinction.r), exp(-path_extinction.g), exp(-path_extinction.b));
+}
+