mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added entity shadows
This commit is contained in:
parent
50daf185a8
commit
499344ccab
@ -30,6 +30,9 @@ out vec4 tgt_color;
|
||||
void main() {
|
||||
vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
diffuse_light *= point_shadow;
|
||||
ambient_light *= point_shadow;
|
||||
vec3 point_light = light_at(f_pos, f_norm);
|
||||
light += point_light;
|
||||
diffuse_light += point_light;
|
||||
|
@ -40,8 +40,9 @@ void main() {
|
||||
|
||||
vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
|
||||
diffuse_light *= f_light;
|
||||
ambient_light *= f_light;
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
diffuse_light *= f_light * point_shadow;
|
||||
ambient_light *= f_light, point_shadow;
|
||||
vec3 point_light = light_at(f_pos, f_norm);
|
||||
light += point_light;
|
||||
diffuse_light += point_light;
|
||||
|
@ -8,6 +8,6 @@ uniform u_globals {
|
||||
vec4 time_of_day;
|
||||
vec4 tick;
|
||||
vec4 screen_res;
|
||||
uvec4 light_count;
|
||||
uvec4 light_shadow_count;
|
||||
uvec4 medium;
|
||||
};
|
||||
|
@ -8,6 +8,15 @@ uniform u_lights {
|
||||
Light lights[32];
|
||||
};
|
||||
|
||||
struct Shadow {
|
||||
vec4 shadow_pos_radius;
|
||||
};
|
||||
|
||||
layout (std140)
|
||||
uniform u_shadows {
|
||||
Shadow shadows[24];
|
||||
};
|
||||
|
||||
#include <srgb.glsl>
|
||||
|
||||
vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) {
|
||||
@ -24,7 +33,7 @@ vec3 light_at(vec3 wpos, vec3 wnorm) {
|
||||
|
||||
vec3 light = vec3(0);
|
||||
|
||||
for (uint i = 0u; i < light_count.x; i++) {
|
||||
for (uint i = 0u; i < light_shadow_count.x; i ++) {
|
||||
|
||||
// Only access the array once
|
||||
Light L = lights[i];
|
||||
@ -39,16 +48,30 @@ vec3 light_at(vec3 wpos, vec3 wnorm) {
|
||||
// Multiply the vec3 only once
|
||||
vec3 color = srgb_to_linear(L.light_col.rgb) * (strength * L.light_col.a);
|
||||
|
||||
// This is commented out to avoid conditional branching. See here: https://community.khronos.org/t/glsl-float-multiply-by-zero/104391
|
||||
// if (max(max(color.r, color.g), color.b) < 0.002) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Old: light += color * clamp(dot(normalize(difference), wnorm), LIGHT_AMBIENCE, 1.0);
|
||||
|
||||
// The dot product cannot be greater than one, so no need to clamp max value
|
||||
// Also, rather than checking if it is smaller than LIGHT_AMBIENCE, add LIGHT_AMBIENCE instead
|
||||
light += color * (max(0, dot(normalize(difference), wnorm)) + LIGHT_AMBIENCE);
|
||||
}
|
||||
return light;
|
||||
}
|
||||
|
||||
float shadow_at(vec3 wpos, vec3 wnorm) {
|
||||
float shadow = 1.0;
|
||||
|
||||
for (uint i = 0u; i < light_shadow_count.y; i ++) {
|
||||
|
||||
// Only access the array once
|
||||
Shadow S = shadows[i];
|
||||
|
||||
vec3 shadow_pos = S.shadow_pos_radius.xyz;
|
||||
float radius = S.shadow_pos_radius.w;
|
||||
|
||||
vec3 diff = shadow_pos - wpos;
|
||||
if (diff.z >= 0.0) {
|
||||
diff.z = diff.z * 0.1;
|
||||
}
|
||||
|
||||
float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), 0.5);
|
||||
|
||||
shadow = min(shadow, shade);
|
||||
}
|
||||
return min(shadow, 1.0);
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ const float FADE_DIST = 32.0;
|
||||
void main() {
|
||||
vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
|
||||
diffuse_light *= f_light;
|
||||
ambient_light *= f_light;
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
diffuse_light *= f_light * point_shadow;
|
||||
ambient_light *= f_light, point_shadow;
|
||||
vec3 point_light = light_at(f_pos, f_norm);
|
||||
light += point_light;
|
||||
diffuse_light += point_light;
|
||||
|
@ -21,8 +21,9 @@ out vec4 tgt_color;
|
||||
void main() {
|
||||
vec3 light, diffuse_light, ambient_light;
|
||||
get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light);
|
||||
diffuse_light *= f_light;
|
||||
ambient_light *= f_light;
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
diffuse_light *= f_light * point_shadow;
|
||||
ambient_light *= f_light * point_shadow;
|
||||
vec3 point_light = light_at(f_pos, f_norm);
|
||||
light += point_light;
|
||||
diffuse_light += point_light;
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
},
|
||||
render::{
|
||||
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Light, Model,
|
||||
PostProcessLocals, PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
||||
PostProcessLocals, PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
||||
},
|
||||
scene::{
|
||||
camera::{Camera, CameraMode},
|
||||
@ -36,6 +36,7 @@ struct PostProcess {
|
||||
pub struct Scene {
|
||||
globals: Consts<Globals>,
|
||||
lights: Consts<Light>,
|
||||
shadows: Consts<Shadow>,
|
||||
camera: Camera,
|
||||
|
||||
skybox: Skybox,
|
||||
@ -57,6 +58,7 @@ impl Scene {
|
||||
Self {
|
||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||
|
||||
skybox: Skybox {
|
||||
@ -134,6 +136,7 @@ impl Scene {
|
||||
client.state().get_time(),
|
||||
renderer.get_resolution(),
|
||||
0,
|
||||
0,
|
||||
BlockKind::Air,
|
||||
)],
|
||||
) {
|
||||
@ -193,6 +196,7 @@ impl Scene {
|
||||
self.figure_state.locals(),
|
||||
self.figure_state.bone_consts(),
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
);
|
||||
|
||||
renderer.render_figure(
|
||||
@ -201,6 +205,7 @@ impl Scene {
|
||||
self.backdrop_state.locals(),
|
||||
self.backdrop_state.bone_consts(),
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
);
|
||||
|
||||
renderer.render_post_process(
|
||||
|
@ -26,7 +26,7 @@ pub use self::{
|
||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
||||
Mode as UiMode, UiPipeline,
|
||||
},
|
||||
Globals, Light,
|
||||
Globals, Light, Shadow,
|
||||
},
|
||||
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},
|
||||
texture::Texture,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
Globals, Light,
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self,
|
||||
@ -38,6 +38,7 @@ gfx_defines! {
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthFmt},
|
||||
Globals, Light,
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self,
|
||||
@ -27,6 +27,7 @@ gfx_defines! {
|
||||
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||
|
@ -28,7 +28,7 @@ gfx_defines! {
|
||||
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
||||
tick: [f32; 4] = "tick",
|
||||
screen_res: [f32; 4] = "screen_res",
|
||||
light_count: [u32; 4] = "light_count",
|
||||
light_shadow_count: [u32; 4] = "light_shadow_count",
|
||||
medium: [u32; 4] = "medium",
|
||||
}
|
||||
|
||||
@ -36,6 +36,10 @@ gfx_defines! {
|
||||
pos: [f32; 4] = "light_pos",
|
||||
col: [f32; 4] = "light_col",
|
||||
}
|
||||
|
||||
constant Shadow {
|
||||
pos_radius: [f32; 4] = "shadow_pos_radius",
|
||||
}
|
||||
}
|
||||
|
||||
impl Globals {
|
||||
@ -50,6 +54,7 @@ impl Globals {
|
||||
tick: f64,
|
||||
screen_res: Vec2<u16>,
|
||||
light_count: usize,
|
||||
shadow_count: usize,
|
||||
medium: BlockKind,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -61,7 +66,7 @@ impl Globals {
|
||||
time_of_day: [time_of_day as f32; 4],
|
||||
tick: [tick as f32; 4],
|
||||
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
|
||||
light_count: [light_count as u32; 4],
|
||||
light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0],
|
||||
medium: [if medium.is_fluid() { 1 } else { 0 }; 4],
|
||||
}
|
||||
}
|
||||
@ -79,6 +84,7 @@ impl Default for Globals {
|
||||
0.0,
|
||||
Vec2::new(800, 500),
|
||||
0,
|
||||
0,
|
||||
BlockKind::Air,
|
||||
)
|
||||
}
|
||||
@ -91,6 +97,10 @@ impl Light {
|
||||
col: Rgba::new(col.r, col.g, col.b, strength).into_array(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pos(&self) -> Vec3<f32> {
|
||||
Vec3::new(self.pos[0], self.pos[1], self.pos[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Light {
|
||||
@ -98,3 +108,21 @@ impl Default for Light {
|
||||
Self::new(Vec3::zero(), Rgb::zero(), 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Shadow {
|
||||
pub fn new(pos: Vec3<f32>, radius: f32) -> Self {
|
||||
Self {
|
||||
pos_radius: [pos.x, pos.y, pos.z, radius],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pos(&self) -> Vec3<f32> {
|
||||
Vec3::new(self.pos_radius[0], self.pos_radius[1], self.pos_radius[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Shadow {
|
||||
fn default() -> Self {
|
||||
Self::new(Vec3::zero(), 0.0)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
Globals, Light,
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self,
|
||||
@ -36,6 +36,7 @@ gfx_defines! {
|
||||
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
super::{Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
Globals, Light,
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self,
|
||||
@ -32,6 +32,7 @@ gfx_defines! {
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
|
@ -4,7 +4,7 @@ use super::{
|
||||
instances::Instances,
|
||||
mesh::Mesh,
|
||||
model::{DynamicModel, Model},
|
||||
pipelines::{figure, fluid, postprocess, skybox, sprite, terrain, ui, Globals, Light},
|
||||
pipelines::{figure, fluid, postprocess, skybox, sprite, terrain, ui, Globals, Light, Shadow},
|
||||
texture::Texture,
|
||||
Pipeline, RenderError,
|
||||
};
|
||||
@ -392,6 +392,7 @@ impl Renderer {
|
||||
locals: &Consts<figure::Locals>,
|
||||
bones: &Consts<figure::BoneData>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -408,6 +409,7 @@ impl Renderer {
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
@ -421,6 +423,7 @@ impl Renderer {
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<terrain::Locals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -436,6 +439,7 @@ impl Renderer {
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
@ -449,6 +453,7 @@ impl Renderer {
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<terrain::Locals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -464,6 +469,7 @@ impl Renderer {
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
@ -477,6 +483,7 @@ impl Renderer {
|
||||
globals: &Consts<Globals>,
|
||||
instances: &Instances<sprite::Instance>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
@ -492,6 +499,7 @@ impl Renderer {
|
||||
ibuf: instances.ibuf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
},
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
self, character::CharacterSkeleton, object::ObjectSkeleton, quadruped::QuadrupedSkeleton,
|
||||
quadrupedmedium::QuadrupedMediumSkeleton, Animation, Skeleton,
|
||||
},
|
||||
render::{Consts, FigureBoneData, FigureLocals, Globals, Light, Renderer},
|
||||
render::{Consts, FigureBoneData, FigureLocals, Globals, Light, Renderer, Shadow},
|
||||
scene::camera::{Camera, CameraMode},
|
||||
};
|
||||
use client::Client;
|
||||
@ -408,6 +408,7 @@ impl FigureMgr {
|
||||
client: &mut Client,
|
||||
globals: &Consts<Globals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
camera: &Camera,
|
||||
) {
|
||||
let tick = client.get_tick();
|
||||
@ -480,7 +481,7 @@ impl FigureMgr {
|
||||
)
|
||||
.0;
|
||||
|
||||
renderer.render_figure(model, globals, locals, bone_consts, lights);
|
||||
renderer.render_figure(model, globals, locals, bone_consts, lights, shadows);
|
||||
} else {
|
||||
debug!("Body has no saved figure");
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
audio::AudioFrontend,
|
||||
render::{
|
||||
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
||||
PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
||||
PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
||||
},
|
||||
window::Event,
|
||||
};
|
||||
@ -30,7 +30,10 @@ use vek::*;
|
||||
const CURSOR_PAN_SCALE: f32 = 0.005;
|
||||
|
||||
const MAX_LIGHT_COUNT: usize = 32;
|
||||
const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not be visible
|
||||
const MAX_SHADOW_COUNT: usize = 24;
|
||||
const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not emit light from their origin
|
||||
const SHADOW_DIST_RADIUS: f32 = 8.0;
|
||||
const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not be visible
|
||||
|
||||
struct Skybox {
|
||||
model: Model<SkyboxPipeline>,
|
||||
@ -45,6 +48,7 @@ struct PostProcess {
|
||||
pub struct Scene {
|
||||
globals: Consts<Globals>,
|
||||
lights: Consts<Light>,
|
||||
shadows: Consts<Shadow>,
|
||||
camera: Camera,
|
||||
|
||||
skybox: Skybox,
|
||||
@ -63,7 +67,12 @@ impl Scene {
|
||||
|
||||
Self {
|
||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||
lights: renderer
|
||||
.create_consts(&[Light::default(); MAX_LIGHT_COUNT])
|
||||
.unwrap(),
|
||||
shadows: renderer
|
||||
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
||||
.unwrap(),
|
||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||
|
||||
skybox: Skybox {
|
||||
@ -200,14 +209,30 @@ impl Scene {
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
lights.sort_by_key(|light| {
|
||||
Vec3::from(Vec4::from(light.pos)).distance_squared(player_pos) as i32
|
||||
});
|
||||
lights.sort_by_key(|light| light.get_pos().distance_squared(player_pos) as i32);
|
||||
lights.truncate(MAX_LIGHT_COUNT);
|
||||
renderer
|
||||
.update_consts(&mut self.lights, &lights)
|
||||
.expect("Failed to update light constants");
|
||||
|
||||
// Update shadow constants
|
||||
let mut shadows = (
|
||||
&client.state().ecs().read_storage::<comp::Pos>(),
|
||||
client.state().ecs().read_storage::<comp::Scale>().maybe(),
|
||||
)
|
||||
.join()
|
||||
.filter(|(pos, _)| {
|
||||
(pos.0.distance_squared(player_pos) as f32)
|
||||
< self.loaded_distance.powf(2.0).min(SHADOW_MAX_DIST) + SHADOW_DIST_RADIUS
|
||||
})
|
||||
.map(|(pos, scale)| Shadow::new(pos.0, scale.map(|s| s.0).unwrap_or(1.0)))
|
||||
.collect::<Vec<_>>();
|
||||
shadows.sort_by_key(|shadow| shadow.get_pos().distance_squared(player_pos) as i32);
|
||||
shadows.truncate(MAX_SHADOW_COUNT);
|
||||
renderer
|
||||
.update_consts(&mut self.shadows, &shadows)
|
||||
.expect("Failed to update light constants");
|
||||
|
||||
// Update global constants.
|
||||
renderer
|
||||
.update_consts(
|
||||
@ -222,6 +247,7 @@ impl Scene {
|
||||
client.state().get_time(),
|
||||
renderer.get_resolution(),
|
||||
lights.len(),
|
||||
shadows.len(),
|
||||
client
|
||||
.state()
|
||||
.terrain()
|
||||
@ -258,12 +284,19 @@ impl Scene {
|
||||
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
||||
|
||||
// Render terrain and figures.
|
||||
self.figure_mgr
|
||||
.render(renderer, client, &self.globals, &self.lights, &self.camera);
|
||||
self.figure_mgr.render(
|
||||
renderer,
|
||||
client,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
&self.camera,
|
||||
);
|
||||
self.terrain.render(
|
||||
renderer,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
mesh::Meshable,
|
||||
render::{
|
||||
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, SpriteInstance,
|
||||
SpritePipeline, TerrainLocals, TerrainPipeline,
|
||||
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
||||
SpriteInstance, SpritePipeline, TerrainLocals, TerrainPipeline,
|
||||
},
|
||||
};
|
||||
|
||||
@ -894,12 +894,19 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
renderer: &mut Renderer,
|
||||
globals: &Consts<Globals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
focus_pos: Vec3<f32>,
|
||||
) {
|
||||
// Opaque
|
||||
for (_, chunk) in &self.chunks {
|
||||
if chunk.visible {
|
||||
renderer.render_terrain_chunk(&chunk.opaque_model, globals, &chunk.locals, lights);
|
||||
renderer.render_terrain_chunk(
|
||||
&chunk.opaque_model,
|
||||
globals,
|
||||
&chunk.locals,
|
||||
lights,
|
||||
shadows,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -919,6 +926,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
globals,
|
||||
&instances,
|
||||
lights,
|
||||
shadows,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -928,7 +936,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// Translucent
|
||||
for (_, chunk) in &self.chunks {
|
||||
if chunk.visible {
|
||||
renderer.render_fluid_chunk(&chunk.fluid_model, globals, &chunk.locals, lights);
|
||||
renderer.render_fluid_chunk(
|
||||
&chunk.fluid_model,
|
||||
globals,
|
||||
&chunk.locals,
|
||||
lights,
|
||||
shadows,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,11 @@ impl<'a> BlockGen<'a> {
|
||||
cache,
|
||||
Vec2::from(*cliff_pos),
|
||||
) {
|
||||
Some(cliff_sample) if cliff_sample.is_cliffs && cliff_sample.spawn_rate > 0.5 => {
|
||||
Some(cliff_sample)
|
||||
if cliff_sample.is_cliffs
|
||||
&& cliff_sample.spawn_rate > 0.5
|
||||
&& cliff_sample.spawn_rules.cliffs =>
|
||||
{
|
||||
let cliff_pos3d = Vec3::from(*cliff_pos);
|
||||
|
||||
let height = (RandomField::new(seed + 1).get(cliff_pos3d) % 64) as f32
|
||||
|
@ -10,11 +10,15 @@ use vek::*;
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct SpawnRules {
|
||||
pub trees: bool,
|
||||
pub cliffs: bool,
|
||||
}
|
||||
|
||||
impl Default for SpawnRules {
|
||||
fn default() -> Self {
|
||||
Self { trees: true }
|
||||
Self {
|
||||
trees: true,
|
||||
cliffs: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +26,7 @@ impl SpawnRules {
|
||||
pub fn and(self, other: Self) -> Self {
|
||||
Self {
|
||||
trees: self.trees && other.trees,
|
||||
cliffs: self.cliffs && other.cliffs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ impl<'a> Generator<'a, TownState> for TownGen {
|
||||
fn spawn_rules(&self, town: &'a TownState, wpos: Vec2<i32>) -> SpawnRules {
|
||||
SpawnRules {
|
||||
trees: wpos.distance_squared(town.center.into()) > (town.radius + 32).pow(2),
|
||||
cliffs: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user