mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Interpolate weather in voxygen
This commit is contained in:
parent
e37f2be820
commit
4fa2644507
@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vek::Vec2;
|
||||
use vek::{Lerp, Vec2};
|
||||
|
||||
pub const CHUNKS_PER_CELL: u32 = 16;
|
||||
// Weather::default is Clear, 0 degrees C and no wind
|
||||
@ -31,6 +31,14 @@ impl Weather {
|
||||
_ => WeatherKind::Clear,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lerp(from: &Self, to: &Self, t: f32) -> Self {
|
||||
Self {
|
||||
cloud: f32::lerp(from.cloud, to.cloud, t),
|
||||
rain: f32::lerp(from.rain, to.rain, t),
|
||||
wind: Vec2::<f32>::lerp(from.wind, to.wind, t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::super::{AaMode, GlobalsLayouts, Renderer, Texture, Vertex as VertexTrait};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use std::mem;
|
||||
use common::{grid::Grid, weather::Weather};
|
||||
use std::{mem, time::Instant};
|
||||
use vek::*;
|
||||
|
||||
#[repr(C)]
|
||||
@ -31,12 +32,77 @@ impl VertexTrait for Vertex {
|
||||
const STRIDE: wgpu::BufferAddress = mem::size_of::<Self>() as wgpu::BufferAddress;
|
||||
}
|
||||
|
||||
pub struct WeatherTexture {
|
||||
a: (Grid<Weather>, Instant),
|
||||
b: (Grid<Weather>, Instant),
|
||||
pub tex: Texture,
|
||||
}
|
||||
|
||||
impl WeatherTexture {
|
||||
fn new(tex: Texture) -> Self {
|
||||
Self {
|
||||
a: (Grid::new(Vec2::zero(), Default::default()), Instant::now()),
|
||||
b: (Grid::new(Vec2::zero(), Default::default()), Instant::now()),
|
||||
tex,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_weather(&mut self, weather: Grid<Weather>) {
|
||||
self.a = mem::replace(&mut self.b, (weather, Instant::now()));
|
||||
}
|
||||
|
||||
pub fn update_texture(&self, renderer: &mut Renderer) {
|
||||
let a = &self.a.0;
|
||||
let b = &self.b.0;
|
||||
let size = self.b.0.size().as_::<u32>();
|
||||
if a.size() != b.size() {
|
||||
renderer.update_texture(
|
||||
&self.tex,
|
||||
[0, 0],
|
||||
[size.x, size.y],
|
||||
&b.iter()
|
||||
.map(|(_, w)| {
|
||||
[
|
||||
(w.cloud * 255.0) as u8,
|
||||
(w.rain * 255.0) as u8,
|
||||
(w.wind.x + 128.0).clamp(0.0, 255.0) as u8,
|
||||
(w.wind.y + 128.0).clamp(0.0, 255.0) as u8,
|
||||
]
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
} else {
|
||||
// Assume updates are regular
|
||||
let t = (self.b.1.elapsed().as_secs_f32()
|
||||
/ self.b.1.duration_since(self.a.1).as_secs_f32())
|
||||
.clamp(0.0, 1.0);
|
||||
renderer.update_texture(
|
||||
&self.tex,
|
||||
[0, 0],
|
||||
[size.x, size.y],
|
||||
&a.iter()
|
||||
.zip(b.iter())
|
||||
.map(|((_, a), (_, b))| {
|
||||
let w = Weather::lerp(a, b, t);
|
||||
[
|
||||
(w.cloud * 255.0) as u8,
|
||||
(w.rain * 255.0) as u8,
|
||||
(w.wind.x + 128.0).clamp(0.0, 255.0) as u8,
|
||||
(w.wind.y + 128.0).clamp(0.0, 255.0) as u8,
|
||||
]
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LodData {
|
||||
pub map: Texture,
|
||||
pub alt: Texture,
|
||||
pub horizon: Texture,
|
||||
pub tgt_detail: u32,
|
||||
pub clouds: Texture,
|
||||
pub weather: WeatherTexture,
|
||||
}
|
||||
|
||||
impl LodData {
|
||||
@ -135,7 +201,7 @@ impl LodData {
|
||||
);
|
||||
// SamplerInfo {
|
||||
// border: [1.0, 0.0, 1.0, 0.0].into(),
|
||||
let clouds = {
|
||||
let weather = {
|
||||
let texture_info = wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
@ -185,7 +251,7 @@ impl LodData {
|
||||
alt,
|
||||
horizon,
|
||||
tgt_detail,
|
||||
clouds,
|
||||
weather: WeatherTexture::new(weather),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,11 +578,11 @@ impl GlobalsLayouts {
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 12,
|
||||
resource: wgpu::BindingResource::TextureView(&lod_data.clouds.view),
|
||||
resource: wgpu::BindingResource::TextureView(&lod_data.weather.tex.view),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 13,
|
||||
resource: wgpu::BindingResource::Sampler(&lod_data.clouds.sampler),
|
||||
resource: wgpu::BindingResource::Sampler(&lod_data.weather.tex.sampler),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -10,9 +10,11 @@ use crate::{
|
||||
use client::Client;
|
||||
use common::{
|
||||
assets::{AssetExt, ObjAsset},
|
||||
grid::Grid,
|
||||
lod,
|
||||
spiral::Spiral2d,
|
||||
util::srgba_to_linear,
|
||||
weather::Weather,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use std::ops::Range;
|
||||
@ -77,6 +79,10 @@ impl Lod {
|
||||
|
||||
pub fn get_data(&self) -> &LodData { &self.data }
|
||||
|
||||
pub fn update_weather(&mut self, weather: Grid<Weather>) {
|
||||
self.data.weather.update_weather(weather);
|
||||
}
|
||||
|
||||
pub fn set_detail(&mut self, detail: u32) {
|
||||
// Make sure the recorded detail is even.
|
||||
self.data.tgt_detail = (detail - detail % 2).max(100).min(2500);
|
||||
@ -89,6 +95,7 @@ impl Lod {
|
||||
focus_pos: Vec3<f32>,
|
||||
camera: &Camera,
|
||||
) {
|
||||
self.data.weather.update_texture(renderer);
|
||||
// Update LoD terrain mesh according to detail
|
||||
if self
|
||||
.model
|
||||
|
@ -4,7 +4,6 @@ mod target;
|
||||
|
||||
use std::{cell::RefCell, collections::HashSet, rc::Rc, result::Result, time::Duration};
|
||||
|
||||
use itertools::Itertools;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
use mumble_link::SharedLink;
|
||||
use ordered_float::OrderedFloat;
|
||||
@ -326,29 +325,7 @@ impl SessionState {
|
||||
self.hud.show.update_map_markers(event);
|
||||
},
|
||||
client::Event::WeatherUpdate => {
|
||||
//weather
|
||||
// .iter_mut()
|
||||
// .for_each(|(p, c)| *c = if (p.x + p.y) % 2 == 0 { 1.0 } else { 0.0 });
|
||||
let size = client.get_weather().size();
|
||||
global_state.window.renderer_mut().update_texture(
|
||||
&self.scene.lod.get_data().clouds,
|
||||
[0, 0],
|
||||
[size.x as u32, size.y as u32],
|
||||
client
|
||||
.get_weather()
|
||||
.iter()
|
||||
.map(|(_, w)| {
|
||||
//println!("{}, ", w.cloud);
|
||||
[
|
||||
(w.cloud * 255.0) as u8,
|
||||
(w.rain * 255.0) as u8,
|
||||
(w.wind.x + 128.0).clamp(0.0, 255.0) as u8,
|
||||
(w.wind.y + 128.0).clamp(0.0, 255.0) as u8,
|
||||
]
|
||||
})
|
||||
.collect_vec()
|
||||
.as_slice(),
|
||||
);
|
||||
self.scene.lod.update_weather(client.get_weather().clone());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user