mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added point lights
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <sky.glsl>
|
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
in vec3 f_norm;
|
in vec3 f_norm;
|
||||||
@ -23,6 +22,19 @@ uniform u_bones {
|
|||||||
BoneData bones[16];
|
BoneData bones[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec4 light_pos;
|
||||||
|
vec4 light_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_lights {
|
||||||
|
Light lights[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <sky.glsl>
|
||||||
|
#include <light.glsl>
|
||||||
|
|
||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -32,7 +44,7 @@ void main() {
|
|||||||
vec4(f_norm, 0.0)
|
vec4(f_norm, 0.0)
|
||||||
).xyz;
|
).xyz;
|
||||||
|
|
||||||
vec3 light = get_sun_diffuse(world_norm, time_of_day.x);
|
vec3 light = get_sun_diffuse(world_norm, time_of_day.x) + light_at(f_pos, f_norm);
|
||||||
vec3 surf_color = model_col.rgb * f_col * 2.0 * light;
|
vec3 surf_color = model_col.rgb * f_col * 2.0 * light;
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xy, focus_pos.xy);
|
float fog_level = fog(f_pos.xy, focus_pos.xy);
|
||||||
|
@ -22,6 +22,16 @@ uniform u_bones {
|
|||||||
BoneData bones[16];
|
BoneData bones[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec4 light_pos;
|
||||||
|
vec4 light_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_lights {
|
||||||
|
Light lights[32];
|
||||||
|
};
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
out vec3 f_norm;
|
out vec3 f_norm;
|
||||||
out vec3 f_col;
|
out vec3 f_col;
|
||||||
|
@ -8,4 +8,5 @@ uniform u_globals {
|
|||||||
vec4 time_of_day;
|
vec4 time_of_day;
|
||||||
vec4 tick;
|
vec4 tick;
|
||||||
vec4 screen_res;
|
vec4 screen_res;
|
||||||
|
uvec4 light_count;
|
||||||
};
|
};
|
||||||
|
22
voxygen/shaders/include/light.glsl
Normal file
22
voxygen/shaders/include/light.glsl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
float attenuation_strength(vec3 rpos) {
|
||||||
|
return 1.0 / (rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 light_at(vec3 wpos, vec3 wnorm) {
|
||||||
|
const float LIGHT_AMBIENCE = 0.1;
|
||||||
|
|
||||||
|
vec3 light = vec3(0);
|
||||||
|
for (uint i = 0u; i < light_count.x; i ++) {
|
||||||
|
vec3 light_pos = lights[i].light_pos.xyz;
|
||||||
|
float strength = attenuation_strength(wpos - light_pos);
|
||||||
|
|
||||||
|
if (strength < 0.001) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
light += strength
|
||||||
|
* lights[i].light_col.rgb
|
||||||
|
* clamp(dot(normalize(light_pos - wpos), wnorm), LIGHT_AMBIENCE, 1.0);
|
||||||
|
}
|
||||||
|
return light;
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <sky.glsl>
|
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
flat in uint f_pos_norm;
|
flat in uint f_pos_norm;
|
||||||
@ -13,8 +12,21 @@ uniform u_locals {
|
|||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec4 light_pos;
|
||||||
|
vec4 light_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_lights {
|
||||||
|
Light lights[32];
|
||||||
|
};
|
||||||
|
|
||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
|
#include <sky.glsl>
|
||||||
|
#include <light.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Calculate normal from packed data
|
// Calculate normal from packed data
|
||||||
vec3 f_norm;
|
vec3 f_norm;
|
||||||
@ -28,7 +40,7 @@ void main() {
|
|||||||
f_norm = vec3(0.0, 0.0, 1.0) * norm_dir;
|
f_norm = vec3(0.0, 0.0, 1.0) * norm_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 light = get_sun_diffuse(f_norm, time_of_day.x) * f_light;
|
vec3 light = get_sun_diffuse(f_norm, time_of_day.x) * f_light + light_at(f_pos, f_norm);
|
||||||
vec3 surf_color = f_col * light;
|
vec3 surf_color = f_col * light;
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xy, focus_pos.xy);
|
float fog_level = fog(f_pos.xy, focus_pos.xy);
|
||||||
|
@ -10,6 +10,16 @@ uniform u_locals {
|
|||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec4 light_pos;
|
||||||
|
vec4 light_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_lights {
|
||||||
|
Light lights[32];
|
||||||
|
};
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
flat out uint f_pos_norm;
|
flat out uint f_pos_norm;
|
||||||
out vec3 f_col;
|
out vec3 f_col;
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
Animation, Skeleton, SkeletonAttr,
|
Animation, Skeleton, SkeletonAttr,
|
||||||
},
|
},
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Model,
|
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Light, Model,
|
||||||
PostProcessLocals, PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
PostProcessLocals, PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
@ -33,6 +33,7 @@ struct PostProcess {
|
|||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
globals: Consts<Globals>,
|
globals: Consts<Globals>,
|
||||||
|
lights: Consts<Light>,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
|
||||||
skybox: Skybox,
|
skybox: Skybox,
|
||||||
@ -50,6 +51,7 @@ impl Scene {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||||
|
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||||
camera: Camera::new(resolution.x / resolution.y),
|
camera: Camera::new(resolution.x / resolution.y),
|
||||||
|
|
||||||
skybox: Skybox {
|
skybox: Skybox {
|
||||||
@ -99,6 +101,7 @@ impl Scene {
|
|||||||
55800.0,
|
55800.0,
|
||||||
client.state().get_time(),
|
client.state().get_time(),
|
||||||
renderer.get_resolution(),
|
renderer.get_resolution(),
|
||||||
|
0,
|
||||||
)],
|
)],
|
||||||
) {
|
) {
|
||||||
error!("Renderer failed to update: {:?}", err);
|
error!("Renderer failed to update: {:?}", err);
|
||||||
@ -139,6 +142,7 @@ impl Scene {
|
|||||||
&self.globals,
|
&self.globals,
|
||||||
self.figure_state.locals(),
|
self.figure_state.locals(),
|
||||||
self.figure_state.bone_consts(),
|
self.figure_state.bone_consts(),
|
||||||
|
&self.lights,
|
||||||
);
|
);
|
||||||
|
|
||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
@ -146,6 +150,7 @@ impl Scene {
|
|||||||
&self.globals,
|
&self.globals,
|
||||||
self.backdrop_state.locals(),
|
self.backdrop_state.locals(),
|
||||||
self.backdrop_state.bone_consts(),
|
self.backdrop_state.bone_consts(),
|
||||||
|
&self.lights,
|
||||||
);
|
);
|
||||||
|
|
||||||
renderer.render_post_process(
|
renderer.render_post_process(
|
||||||
|
@ -22,7 +22,7 @@ pub use self::{
|
|||||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
||||||
Mode as UiMode, UiPipeline,
|
Mode as UiMode, UiPipeline,
|
||||||
},
|
},
|
||||||
Globals,
|
Globals, Light,
|
||||||
},
|
},
|
||||||
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},
|
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||||
Globals,
|
Globals, Light,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self,
|
self,
|
||||||
@ -37,6 +37,7 @@ gfx_defines! {
|
|||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
||||||
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
@ -25,24 +25,16 @@ gfx_defines! {
|
|||||||
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
||||||
tick: [f32; 4] = "tick",
|
tick: [f32; 4] = "tick",
|
||||||
screen_res: [f32; 4] = "screen_res",
|
screen_res: [f32; 4] = "screen_res",
|
||||||
|
light_count: [u32; 4] = "light_count",
|
||||||
|
}
|
||||||
|
|
||||||
|
constant Light {
|
||||||
|
pos: [f32; 4] = "light_pos",
|
||||||
|
col: [f32; 4] = "light_col",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Globals {
|
impl Globals {
|
||||||
/// Create global consts with default values.
|
|
||||||
pub fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
view_mat: arr_to_mat(Mat4::identity().into_col_array()),
|
|
||||||
proj_mat: arr_to_mat(Mat4::identity().into_col_array()),
|
|
||||||
cam_pos: [0.0; 4],
|
|
||||||
focus_pos: [0.0; 4],
|
|
||||||
view_distance: [0.0; 4],
|
|
||||||
time_of_day: [0.0; 4],
|
|
||||||
tick: [0.0; 4],
|
|
||||||
screen_res: [800.0, 500.0, 0.0, 0.0],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create global consts from the provided parameters.
|
/// Create global consts from the provided parameters.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
view_mat: Mat4<f32>,
|
view_mat: Mat4<f32>,
|
||||||
@ -53,6 +45,7 @@ impl Globals {
|
|||||||
time_of_day: f64,
|
time_of_day: f64,
|
||||||
tick: f64,
|
tick: f64,
|
||||||
screen_res: Vec2<u16>,
|
screen_res: Vec2<u16>,
|
||||||
|
light_count: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
view_mat: arr_to_mat(view_mat.into_col_array()),
|
view_mat: arr_to_mat(view_mat.into_col_array()),
|
||||||
@ -63,6 +56,38 @@ impl Globals {
|
|||||||
time_of_day: [time_of_day as f32; 4],
|
time_of_day: [time_of_day as f32; 4],
|
||||||
tick: [tick as f32; 4],
|
tick: [tick as f32; 4],
|
||||||
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
|
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
|
||||||
|
light_count: [light_count as u32; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Globals {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(
|
||||||
|
Mat4::identity(),
|
||||||
|
Mat4::identity(),
|
||||||
|
Vec3::zero(),
|
||||||
|
Vec3::zero(),
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
Vec2::new(800, 500),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Light {
|
||||||
|
pub fn new(pos: Vec3<f32>, col: Rgb<f32>, strength: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
pos: Vec4::from(pos).into_array(),
|
||||||
|
col: Rgba::new(col.r, col.g, col.b, strength).into_array(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Light {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(Vec3::zero(), Rgb::zero(), 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{Pipeline, TgtColorFmt, TgtDepthFmt},
|
super::{Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||||
Globals,
|
Globals, Light,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self,
|
self,
|
||||||
@ -30,6 +30,7 @@ gfx_defines! {
|
|||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
@ -3,7 +3,7 @@ use super::{
|
|||||||
gfx_backend,
|
gfx_backend,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::{DynamicModel, Model},
|
model::{DynamicModel, Model},
|
||||||
pipelines::{figure, postprocess, skybox, terrain, ui, Globals},
|
pipelines::{figure, postprocess, skybox, terrain, ui, Globals, Light},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
Pipeline, RenderError,
|
Pipeline, RenderError,
|
||||||
};
|
};
|
||||||
@ -82,10 +82,15 @@ impl Renderer {
|
|||||||
env!("CARGO_MANIFEST_DIR"),
|
env!("CARGO_MANIFEST_DIR"),
|
||||||
"/shaders/include/sky.glsl"
|
"/shaders/include/sky.glsl"
|
||||||
));
|
));
|
||||||
|
let light = include_str!(concat!(
|
||||||
|
env!("CARGO_MANIFEST_DIR"),
|
||||||
|
"/shaders/include/light.glsl"
|
||||||
|
));
|
||||||
|
|
||||||
let mut include_ctx = IncludeContext::new();
|
let mut include_ctx = IncludeContext::new();
|
||||||
include_ctx.include("globals.glsl", globals);
|
include_ctx.include("globals.glsl", globals);
|
||||||
include_ctx.include("sky.glsl", sky);
|
include_ctx.include("sky.glsl", sky);
|
||||||
|
include_ctx.include("light.glsl", light);
|
||||||
|
|
||||||
// Construct a pipeline for rendering skyboxes
|
// Construct a pipeline for rendering skyboxes
|
||||||
let skybox_pipeline = create_pipeline(
|
let skybox_pipeline = create_pipeline(
|
||||||
@ -389,6 +394,7 @@ impl Renderer {
|
|||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
locals: &Consts<figure::Locals>,
|
locals: &Consts<figure::Locals>,
|
||||||
bones: &Consts<figure::BoneData>,
|
bones: &Consts<figure::BoneData>,
|
||||||
|
lights: &Consts<Light>,
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&model.slice,
|
&model.slice,
|
||||||
@ -398,6 +404,7 @@ impl Renderer {
|
|||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
|
lights: lights.buf.clone(),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
@ -410,6 +417,7 @@ impl Renderer {
|
|||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
locals: &Consts<terrain::Locals>,
|
locals: &Consts<terrain::Locals>,
|
||||||
|
lights: &Consts<Light>,
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&model.slice,
|
&model.slice,
|
||||||
@ -418,6 +426,7 @@ impl Renderer {
|
|||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
|
lights: lights.buf.clone(),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
mesh::Meshable,
|
mesh::Meshable,
|
||||||
render::{
|
render::{
|
||||||
Consts, FigureBoneData, FigureLocals, FigurePipeline, Globals, Mesh, Model, Renderer,
|
Consts, FigureBoneData, FigureLocals, FigurePipeline, Globals, Light, Mesh, Model, Renderer,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
@ -800,6 +800,7 @@ impl FigureMgr {
|
|||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
client: &mut Client,
|
client: &mut Client,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
|
lights: &Consts<Light>,
|
||||||
) {
|
) {
|
||||||
let tick = client.get_tick();
|
let tick = client.get_tick();
|
||||||
let ecs = client.state().ecs();
|
let ecs = client.state().ecs();
|
||||||
@ -855,7 +856,7 @@ impl FigureMgr {
|
|||||||
.get_or_create_model(renderer, *body, tick)
|
.get_or_create_model(renderer, *body, tick)
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
renderer.render_figure(model, globals, locals, bone_consts);
|
renderer.render_figure(model, globals, locals, bone_consts, lights);
|
||||||
} else {
|
} else {
|
||||||
warn!("Body has no saved figure");
|
warn!("Body has no saved figure");
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,21 @@ pub mod terrain;
|
|||||||
use self::{camera::Camera, figure::FigureMgr, terrain::Terrain};
|
use self::{camera::Camera, figure::FigureMgr, terrain::Terrain};
|
||||||
use crate::{
|
use crate::{
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, Consts, Globals, Model, PostProcessLocals,
|
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
||||||
PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline,
|
||||||
},
|
},
|
||||||
window::Event,
|
window::Event,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::comp;
|
use common::comp;
|
||||||
|
use specs::Join;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
// TODO: Don't hard-code this.
|
// TODO: Don't hard-code this.
|
||||||
const CURSOR_PAN_SCALE: f32 = 0.005;
|
const CURSOR_PAN_SCALE: f32 = 0.005;
|
||||||
|
|
||||||
|
const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not be visible
|
||||||
|
|
||||||
struct Skybox {
|
struct Skybox {
|
||||||
model: Model<SkyboxPipeline>,
|
model: Model<SkyboxPipeline>,
|
||||||
locals: Consts<SkyboxLocals>,
|
locals: Consts<SkyboxLocals>,
|
||||||
@ -29,6 +32,7 @@ struct PostProcess {
|
|||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
globals: Consts<Globals>,
|
globals: Consts<Globals>,
|
||||||
|
lights: Consts<Light>,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
|
||||||
skybox: Skybox,
|
skybox: Skybox,
|
||||||
@ -46,6 +50,7 @@ impl Scene {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||||
|
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||||
camera: Camera::new(resolution.x / resolution.y),
|
camera: Camera::new(resolution.x / resolution.y),
|
||||||
|
|
||||||
skybox: Skybox {
|
skybox: Skybox {
|
||||||
@ -128,9 +133,27 @@ impl Scene {
|
|||||||
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
|
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
|
||||||
|
|
||||||
// Update chunk loaded distance smoothly for nice shader fog
|
// Update chunk loaded distance smoothly for nice shader fog
|
||||||
let loaded_distance = client.loaded_distance().unwrap_or(0) as f32 * 32.0;
|
let loaded_distance = client.loaded_distance().unwrap_or(0) as f32 * 32.0; // TODO: No magic!
|
||||||
self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01);
|
self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01);
|
||||||
|
|
||||||
|
// Update light constants
|
||||||
|
let mut lights = (&client.state().ecs().read_storage::<comp::Pos>(),)
|
||||||
|
.join()
|
||||||
|
.filter(|(pos,)| {
|
||||||
|
(pos.0.distance_squared(player_pos) as f32)
|
||||||
|
< self.loaded_distance.powf(2.0) + LIGHT_DIST_RADIUS
|
||||||
|
})
|
||||||
|
.map(|(pos,)| pos.0)
|
||||||
|
.map(|pos| Light::new(pos + Vec3::unit_z(), Rgb::broadcast(1.0), 100.0)) // TODO: Don't add 1 to z!
|
||||||
|
.take(32)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
lights.sort_by_key(|light| {
|
||||||
|
Vec3::from(Vec4::from(light.pos)).distance_squared(player_pos) as i32
|
||||||
|
});
|
||||||
|
renderer
|
||||||
|
.update_consts(&mut self.lights, &lights)
|
||||||
|
.expect("Failed to update light constants");
|
||||||
|
|
||||||
// Update global constants.
|
// Update global constants.
|
||||||
renderer
|
renderer
|
||||||
.update_consts(
|
.update_consts(
|
||||||
@ -144,6 +167,7 @@ impl Scene {
|
|||||||
client.state().get_time_of_day(),
|
client.state().get_time_of_day(),
|
||||||
client.state().get_time(),
|
client.state().get_time(),
|
||||||
renderer.get_resolution(),
|
renderer.get_resolution(),
|
||||||
|
lights.len(),
|
||||||
)],
|
)],
|
||||||
)
|
)
|
||||||
.expect("Failed to update global constants");
|
.expect("Failed to update global constants");
|
||||||
@ -171,8 +195,9 @@ impl Scene {
|
|||||||
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
||||||
|
|
||||||
// Render terrain and figures.
|
// Render terrain and figures.
|
||||||
self.terrain.render(renderer, &self.globals);
|
self.terrain.render(renderer, &self.globals, &self.lights);
|
||||||
self.figure_mgr.render(renderer, client, &self.globals);
|
self.figure_mgr
|
||||||
|
.render(renderer, client, &self.globals, &self.lights);
|
||||||
|
|
||||||
renderer.render_post_process(
|
renderer.render_post_process(
|
||||||
&self.postprocess.model,
|
&self.postprocess.model,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::Meshable,
|
mesh::Meshable,
|
||||||
render::{Consts, Globals, Mesh, Model, Renderer, TerrainLocals, TerrainPipeline},
|
render::{Consts, Globals, Light, Mesh, Model, Renderer, TerrainLocals, TerrainPipeline},
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
@ -327,10 +327,15 @@ impl Terrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
pub fn render(
|
||||||
|
&self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
globals: &Consts<Globals>,
|
||||||
|
lights: &Consts<Light>,
|
||||||
|
) {
|
||||||
for (_pos, chunk) in &self.chunks {
|
for (_pos, chunk) in &self.chunks {
|
||||||
if chunk.visible {
|
if chunk.visible {
|
||||||
renderer.render_terrain_chunk(&chunk.model, globals, &chunk.locals);
|
renderer.render_terrain_chunk(&chunk.model, globals, &chunk.locals, lights);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user