Theme

alex/beta-minecraft-rust

Minecraft Beta 1.7.3 Rewrite

BRANCH main
main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
Download file

root / crates / client / src / environment.rs

//! Time of day, sky and fog colors. Ports of the relevant `World` and `WorldProvider` methods.

use std::f32::consts::PI;

use common::math;
use glam::Vec3;

pub use common::world::sky::sky_darkness;

pub fn daylight(angle: f32) -> f32 {
    (math::cos(angle * PI * 2.0) * 2.0 + 0.5).clamp(0.0, 1.0)
}

/// Port of `World.getSkyColor` without weather and lightning. `temperature` is the raw sky temperature.
pub fn sky_color(angle: f32, temperature: f64) -> Vec3 {
    let rgb = sky_color_by_temperature(temperature as f32);
    let color = Vec3::new(
        (rgb >> 16 & 255) as f32 / 255.0,
        (rgb >> 8 & 255) as f32 / 255.0,
        (rgb & 255) as f32 / 255.0,
    );
    color * daylight(angle)
}

/// Port of `WorldProvider.getFogColor`.
pub fn fog_color(angle: f32) -> Vec3 {
    let light = daylight(angle);
    Vec3::new(
        192.0 / 255.0 * (light * 0.94 + 0.06),
        216.0 / 255.0 * (light * 0.94 + 0.06),
        light * 0.91 + 0.09,
    )
}

/// Port of `WorldProvider.calcSunriseSunsetColors`: RGB and fan opacity, if the sun is near the horizon.
pub fn sunrise_color(angle: f32) -> Option<[f32; 4]> {
    const SPREAD: f32 = 0.4;
    let height = math::cos(angle * PI * 2.0);
    if !(-SPREAD..=SPREAD).contains(&height) {
        return None;
    }
    let t = height / SPREAD * 0.5 + 0.5;
    let alpha = 1.0 - (1.0 - math::sin(t * PI)) * 0.99;
    Some([
        t * 0.3 + 0.7,
        t * t * 0.7 + 0.2,
        t * t * 0.0 + 0.2,
        alpha * alpha,
    ])
}

/// Port of `BiomeGenBase.getSkyColorByTemp`.
fn sky_color_by_temperature(temperature: f32) -> u32 {
    let t = (temperature / 3.0).clamp(-1.0, 1.0);
    hsb_to_rgb(224.0 / 360.0 - t * 0.05, 0.5 + t * 0.1, 1.0)
}

/// Port of `java.awt.Color.HSBtoRGB`.
fn hsb_to_rgb(hue: f32, saturation: f32, brightness: f32) -> u32 {
    let channel = |value: f32| (value * 255.0 + 0.5) as u32;
    if saturation == 0.0 {
        let v = channel(brightness);
        return v << 16 | v << 8 | v;
    }
    let h = (hue - hue.floor()) * 6.0;
    let f = h - h.floor();
    let p = brightness * (1.0 - saturation);
    let q = brightness * (1.0 - saturation * f);
    let t = brightness * (1.0 - saturation * (1.0 - f));
    let (r, g, b) = match h as i32 {
        0 => (brightness, t, p),
        1 => (q, brightness, p),
        2 => (p, brightness, t),
        3 => (p, q, brightness),
        4 => (t, p, brightness),
        _ => (brightness, p, q),
    };
    channel(r) << 16 | channel(g) << 8 | channel(b)
}