alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH 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
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)
}