suns 0.0.4

Sun celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
#[derive(Debug, Clone)]
pub enum UniformValue {
    Float(f32),
    Vec3([f32; 3]),
    Vec4([f32; 4]),
    Int(i32),
}

#[derive(Debug, Clone)]
pub struct ShaderUniform {
    pub name: &'static str,
    pub value: UniformValue,
}

pub struct ShaderEndpoint {
    pub name: &'static str,
    pub uniforms: Vec<ShaderUniform>,
}

impl ShaderEndpoint {
    pub fn photosphere() -> Self {
        Self {
            name: "sun_photosphere_pbr",
            uniforms: vec![
                ShaderUniform {
                    name: "u_solar_radius",
                    value: UniformValue::Float(crate::SOLAR_RADIUS as f32),
                },
                ShaderUniform {
                    name: "u_effective_temp_k",
                    value: UniformValue::Float(crate::SOLAR_EFFECTIVE_TEMP as f32),
                },
                ShaderUniform {
                    name: "u_limb_darkening_coeff",
                    value: UniformValue::Float(0.6),
                },
                ShaderUniform {
                    name: "u_granulation_scale",
                    value: UniformValue::Float(1000.0),
                },
                ShaderUniform {
                    name: "u_magnetic_field_intensity",
                    value: UniformValue::Float(crate::SOLAR_MAGNETIC_FIELD_POLAR_T as f32),
                },
                ShaderUniform {
                    name: "u_luminosity",
                    value: UniformValue::Float(crate::SOLAR_LUMINOSITY as f32),
                },
            ],
        }
    }

    pub fn corona() -> Self {
        Self {
            name: "sun_corona",
            uniforms: vec![
                ShaderUniform {
                    name: "u_corona_temp_k",
                    value: UniformValue::Float(crate::CORONA_TEMP as f32),
                },
                ShaderUniform {
                    name: "u_corona_falloff_exponent",
                    value: UniformValue::Float(2.5),
                },
                ShaderUniform {
                    name: "u_corona_color",
                    value: UniformValue::Vec3([0.9, 0.95, 1.0]),
                },
                ShaderUniform {
                    name: "u_corona_intensity",
                    value: UniformValue::Float(0.01),
                },
            ],
        }
    }

    pub fn active_region() -> Self {
        Self {
            name: "sun_active_region",
            uniforms: vec![
                ShaderUniform {
                    name: "u_limb_darkening_coeff",
                    value: UniformValue::Float(0.6),
                },
                ShaderUniform {
                    name: "u_granulation_scale",
                    value: UniformValue::Float(500.0),
                },
                ShaderUniform {
                    name: "u_magnetic_field_intensity",
                    value: UniformValue::Float(crate::SOLAR_MAGNETIC_FIELD_SUNSPOT_T as f32),
                },
                ShaderUniform {
                    name: "u_sunspot_temp_k",
                    value: UniformValue::Float(3500.0),
                },
                ShaderUniform {
                    name: "u_sunspot_color",
                    value: UniformValue::Vec3([0.6, 0.3, 0.1]),
                },
            ],
        }
    }

    pub fn chromosphere() -> Self {
        Self {
            name: "sun_chromosphere",
            uniforms: vec![
                ShaderUniform {
                    name: "u_chromosphere_temp_k",
                    value: UniformValue::Float(crate::CHROMOSPHERE_TEMP_MAX as f32),
                },
                ShaderUniform {
                    name: "u_chromosphere_color",
                    value: UniformValue::Vec3([1.0, 0.3, 0.2]),
                },
                ShaderUniform {
                    name: "u_chromosphere_opacity",
                    value: UniformValue::Float(0.05),
                },
                ShaderUniform {
                    name: "u_thickness_m",
                    value: UniformValue::Float(crate::CHROMOSPHERE_THICKNESS as f32),
                },
            ],
        }
    }
}

pub fn limb_darkening_factor(coeff: f32, cos_theta: f32) -> f32 {
    1.0 - coeff * (1.0 - cos_theta)
}

pub fn corona_intensity_at_radius(falloff_exponent: f32, r_over_r_sun: f32) -> f32 {
    if r_over_r_sun <= 1.0 {
        return 1.0;
    }
    r_over_r_sun.powf(-falloff_exponent)
}