56 lines
1.8 KiB
GLSL
56 lines
1.8 KiB
GLSL
|
#version 330 core
|
||
|
|
||
|
layout(location = 0) out vec4 fragColor;
|
||
|
|
||
|
in vec2 texcoord;
|
||
|
|
||
|
const int TRANSMITTANCE_STEPS = 40;
|
||
|
|
||
|
// atmos.glsl
|
||
|
float get_earth_radius();
|
||
|
float get_atmosphere_radius();
|
||
|
float ray_sphere_intersection(vec3 ro, vec3 rd, float radius);
|
||
|
void get_atmosphere_collision_coefficients(in float h,
|
||
|
out vec4 aerosol_absorption,
|
||
|
out vec4 aerosol_scattering,
|
||
|
out vec4 molecular_absorption,
|
||
|
out vec4 molecular_scattering,
|
||
|
out vec4 extinction);
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
float sun_cos_theta = texcoord.x * 2.0 - 1.0;
|
||
|
vec3 sun_dir = vec3(-sqrt(1.0 - sun_cos_theta*sun_cos_theta), 0.0, sun_cos_theta);
|
||
|
|
||
|
float distance_to_earth_center = mix(get_earth_radius(),
|
||
|
get_atmosphere_radius(),
|
||
|
texcoord.y);
|
||
|
vec3 ray_origin = vec3(0.0, 0.0, distance_to_earth_center);
|
||
|
|
||
|
float t_d = ray_sphere_intersection(ray_origin, sun_dir, get_atmosphere_radius());
|
||
|
float dt = t_d / float(TRANSMITTANCE_STEPS);
|
||
|
|
||
|
vec4 result = vec4(0.0);
|
||
|
|
||
|
for (int i = 0; i < TRANSMITTANCE_STEPS; ++i) {
|
||
|
float t = (float(i) + 0.5) * dt;
|
||
|
vec3 x_t = ray_origin + sun_dir * t;
|
||
|
|
||
|
float altitude = length(x_t) - get_earth_radius();
|
||
|
|
||
|
vec4 aerosol_absorption, aerosol_scattering;
|
||
|
vec4 molecular_absorption, molecular_scattering;
|
||
|
vec4 extinction;
|
||
|
get_atmosphere_collision_coefficients(
|
||
|
altitude,
|
||
|
aerosol_absorption, aerosol_scattering,
|
||
|
molecular_absorption, molecular_scattering,
|
||
|
extinction);
|
||
|
|
||
|
result += extinction * dt;
|
||
|
}
|
||
|
|
||
|
vec4 transmittance = exp(-result);
|
||
|
fragColor = transmittance;
|
||
|
}
|