mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add player transparency and silhouette
This commit is contained in:
parent
e0e86de21d
commit
a21ae27a77
@ -41,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fleshed out range attack into charging and shooting anims for staff/bow
|
||||
- Customized attack animation for hammers and axes
|
||||
- German translation
|
||||
- Added a silhouette for players when they are occluded
|
||||
- Added transparency to the player when zooming in
|
||||
|
||||
### Changed
|
||||
|
||||
@ -56,7 +58,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Asset cleanup to lower client-size
|
||||
- Rewrote the humanoid skeleton to be more ideal for attack animations
|
||||
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.5.0] - 2019-01-31
|
||||
|
@ -10,6 +10,9 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 model_col;
|
||||
// bit 0 - is player
|
||||
// bit 1-31 - unused
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct BoneData {
|
||||
@ -43,5 +46,13 @@ void main() {
|
||||
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds);
|
||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||
|
||||
tgt_color = vec4(color, 1.0);
|
||||
float opacity = 1.0;
|
||||
|
||||
if ((flags & 1) == 1 && int(cam_mode) == 1) {
|
||||
float distance = distance(vec3(cam_pos), f_pos) - 1;
|
||||
|
||||
opacity = clamp(distance / 3, 0, 1);
|
||||
}
|
||||
|
||||
tgt_color = vec4(color, opacity);
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 model_col;
|
||||
// bit 0 - is player
|
||||
// bit 1-31 - unused
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct BoneData {
|
||||
|
@ -13,4 +13,5 @@ uniform u_globals {
|
||||
uvec4 medium;
|
||||
ivec4 select_pos;
|
||||
vec4 gamma;
|
||||
uint cam_mode;
|
||||
};
|
||||
|
33
assets/voxygen/shaders/player-shadow-frag.glsl
Normal file
33
assets/voxygen/shaders/player-shadow-frag.glsl
Normal file
@ -0,0 +1,33 @@
|
||||
#version 330 core
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
in vec3 f_pos;
|
||||
in vec3 f_col;
|
||||
flat in vec3 f_norm;
|
||||
|
||||
layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 model_mat;
|
||||
vec4 model_col;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct BoneData {
|
||||
mat4 bone_mat;
|
||||
};
|
||||
|
||||
layout (std140)
|
||||
uniform u_bones {
|
||||
BoneData bones[16];
|
||||
};
|
||||
|
||||
#include <sky.glsl>
|
||||
#include <light.glsl>
|
||||
#include <srgb.glsl>
|
||||
|
||||
out vec4 tgt_color;
|
||||
|
||||
void main() {
|
||||
tgt_color = vec4(0.0,0.0,0.0, 1.0);
|
||||
}
|
@ -30,7 +30,7 @@ pub use self::{
|
||||
},
|
||||
Globals, Light, Shadow,
|
||||
},
|
||||
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},
|
||||
renderer::{Renderer, TgtColorFmt, TgtDepthStencilFmt, WinColorFmt, WinDepthFmt},
|
||||
texture::Texture,
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
use super::{
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
@ -19,6 +20,7 @@ gfx_defines! {
|
||||
constant Locals {
|
||||
model_mat: [[f32; 4]; 4] = "model_mat",
|
||||
model_col: [f32; 4] = "model_col",
|
||||
flags: u32 = "flags",
|
||||
}
|
||||
|
||||
constant BoneData {
|
||||
@ -36,8 +38,8 @@ gfx_defines! {
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,16 +60,20 @@ impl Vertex {
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
pub fn new(model_mat: Mat4<f32>, col: Rgba<f32>) -> Self {
|
||||
pub fn new(model_mat: Mat4<f32>, col: Rgba<f32>, is_player: bool) -> Self {
|
||||
let mut flags = 0;
|
||||
flags |= is_player as u32;
|
||||
|
||||
Self {
|
||||
model_mat: arr_to_mat(model_mat.into_col_array()),
|
||||
model_col: col.into_array(),
|
||||
flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Locals {
|
||||
fn default() -> Self { Self::new(Mat4::identity(), Rgba::broadcast(1.0)) }
|
||||
fn default() -> Self { Self::new(Mat4::identity(), Rgba::broadcast(1.0), false) }
|
||||
}
|
||||
|
||||
impl BoneData {
|
||||
|
@ -1,10 +1,11 @@
|
||||
use super::{
|
||||
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthFmt},
|
||||
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthStencilFmt},
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
|
||||
gfx_vertex_struct_meta, state::ColorMask,
|
||||
gfx_vertex_struct_meta,
|
||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
||||
};
|
||||
use std::ops::Mul;
|
||||
use vek::*;
|
||||
@ -27,7 +28,7 @@ gfx_defines! {
|
||||
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
||||
|
||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ pub mod terrain;
|
||||
pub mod ui;
|
||||
|
||||
use super::util::arr_to_mat;
|
||||
use crate::scene::camera::CameraMode;
|
||||
use common::terrain::BlockKind;
|
||||
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
||||
use vek::*;
|
||||
@ -27,6 +28,7 @@ gfx_defines! {
|
||||
medium: [u32; 4] = "medium",
|
||||
select_pos: [i32; 4] = "select_pos",
|
||||
gamma: [f32; 4] = "gamma",
|
||||
cam_mode: u32 = "cam_mode",
|
||||
}
|
||||
|
||||
constant Light {
|
||||
@ -55,6 +57,7 @@ impl Globals {
|
||||
medium: BlockKind,
|
||||
select_pos: Option<Vec3<i32>>,
|
||||
gamma: f32,
|
||||
cam_mode: CameraMode,
|
||||
) -> Self {
|
||||
Self {
|
||||
view_mat: arr_to_mat(view_mat.into_col_array()),
|
||||
@ -73,6 +76,7 @@ impl Globals {
|
||||
.unwrap_or(Vec4::zero())
|
||||
.into_array(),
|
||||
gamma: [gamma; 4],
|
||||
cam_mode: cam_mode as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,6 +97,7 @@ impl Default for Globals {
|
||||
BlockKind::Air,
|
||||
None,
|
||||
1.0,
|
||||
CameraMode::ThirdPerson,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use super::{
|
||||
super::{Mesh, Pipeline, Quad, TgtColorFmt, TgtDepthFmt},
|
||||
super::{Mesh, Pipeline, Quad, TgtColorFmt, TgtDepthStencilFmt},
|
||||
Globals,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
state::{Comparison, Stencil, StencilOp},
|
||||
};
|
||||
|
||||
gfx_defines! {
|
||||
@ -25,7 +26,7 @@ gfx_defines! {
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
use super::{
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
|
||||
gfx_vertex_struct_meta, state::ColorMask,
|
||||
gfx_vertex_struct_meta,
|
||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
@ -35,7 +36,7 @@ gfx_defines! {
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
use super::{
|
||||
super::{Pipeline, TgtColorFmt, TgtDepthFmt},
|
||||
super::{Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
state::{Comparison, Stencil, StencilOp},
|
||||
};
|
||||
use std::ops::Mul;
|
||||
use vek::*;
|
||||
@ -31,7 +32,7 @@ gfx_defines! {
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ use common::assets::{self, watch::ReloadIndicator};
|
||||
use gfx::{
|
||||
self,
|
||||
handle::Sampler,
|
||||
state::{Comparison, Stencil, StencilOp},
|
||||
traits::{Device, Factory, FactoryExt},
|
||||
};
|
||||
use glsl_include::Context as IncludeContext;
|
||||
@ -20,8 +21,8 @@ use vek::*;
|
||||
|
||||
/// Represents the format of the pre-processed color target.
|
||||
pub type TgtColorFmt = gfx::format::Srgba8;
|
||||
/// Represents the format of the pre-processed depth target.
|
||||
pub type TgtDepthFmt = gfx::format::Depth;
|
||||
/// Represents the format of the pre-processed depth and stencil target.
|
||||
pub type TgtDepthStencilFmt = gfx::format::DepthStencil;
|
||||
|
||||
/// Represents the format of the window's color target.
|
||||
pub type WinColorFmt = gfx::format::Srgba8;
|
||||
@ -31,7 +32,8 @@ pub type WinDepthFmt = gfx::format::Depth;
|
||||
/// A handle to a pre-processed color target.
|
||||
pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, TgtColorFmt>;
|
||||
/// A handle to a pre-processed depth target.
|
||||
pub type TgtDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, TgtDepthFmt>;
|
||||
pub type TgtDepthStencilView =
|
||||
gfx::handle::DepthStencilView<gfx_backend::Resources, TgtDepthStencilFmt>;
|
||||
|
||||
/// A handle to a window color target.
|
||||
pub type WinColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, WinColorFmt>;
|
||||
@ -57,7 +59,7 @@ pub struct Renderer {
|
||||
win_depth_view: WinDepthView,
|
||||
|
||||
tgt_color_view: TgtColorView,
|
||||
tgt_depth_view: TgtDepthView,
|
||||
tgt_depth_stencil_view: TgtDepthStencilView,
|
||||
|
||||
tgt_color_res: TgtColorRes,
|
||||
|
||||
@ -70,6 +72,7 @@ pub struct Renderer {
|
||||
sprite_pipeline: GfxPipeline<sprite::pipe::Init<'static>>,
|
||||
ui_pipeline: GfxPipeline<ui::pipe::Init<'static>>,
|
||||
postprocess_pipeline: GfxPipeline<postprocess::pipe::Init<'static>>,
|
||||
player_shadow_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
|
||||
|
||||
shader_reload_indicator: ReloadIndicator,
|
||||
|
||||
@ -102,6 +105,7 @@ impl Renderer {
|
||||
sprite_pipeline,
|
||||
ui_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
) = create_pipelines(
|
||||
&mut factory,
|
||||
aa_mode,
|
||||
@ -111,7 +115,7 @@ impl Renderer {
|
||||
)?;
|
||||
|
||||
let dims = win_color_view.get_dimensions();
|
||||
let (tgt_color_view, tgt_depth_view, tgt_color_res) =
|
||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res) =
|
||||
Self::create_rt_views(&mut factory, (dims.0, dims.1), aa_mode)?;
|
||||
|
||||
let sampler = factory.create_sampler_linear();
|
||||
@ -132,7 +136,7 @@ impl Renderer {
|
||||
win_depth_view,
|
||||
|
||||
tgt_color_view,
|
||||
tgt_depth_view,
|
||||
tgt_depth_stencil_view,
|
||||
|
||||
tgt_color_res,
|
||||
sampler,
|
||||
@ -144,6 +148,7 @@ impl Renderer {
|
||||
sprite_pipeline,
|
||||
ui_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
|
||||
shader_reload_indicator,
|
||||
|
||||
@ -158,8 +163,8 @@ impl Renderer {
|
||||
/// Get references to the internal render target views that get rendered to
|
||||
/// before post-processing.
|
||||
#[allow(dead_code)]
|
||||
pub fn tgt_views(&self) -> (&TgtColorView, &TgtDepthView) {
|
||||
(&self.tgt_color_view, &self.tgt_depth_view)
|
||||
pub fn tgt_views(&self) -> (&TgtColorView, &TgtDepthStencilView) {
|
||||
(&self.tgt_color_view, &self.tgt_depth_stencil_view)
|
||||
}
|
||||
|
||||
/// Get references to the internal render target views that get displayed
|
||||
@ -172,8 +177,8 @@ impl Renderer {
|
||||
/// Get mutable references to the internal render target views that get
|
||||
/// rendered to before post-processing.
|
||||
#[allow(dead_code)]
|
||||
pub fn tgt_views_mut(&mut self) -> (&mut TgtColorView, &mut TgtDepthView) {
|
||||
(&mut self.tgt_color_view, &mut self.tgt_depth_view)
|
||||
pub fn tgt_views_mut(&mut self) -> (&mut TgtColorView, &mut TgtDepthStencilView) {
|
||||
(&mut self.tgt_color_view, &mut self.tgt_depth_stencil_view)
|
||||
}
|
||||
|
||||
/// Get mutable references to the internal render target views that get
|
||||
@ -228,11 +233,11 @@ impl Renderer {
|
||||
|
||||
// Avoid panics when creating texture with w,h of 0,0.
|
||||
if dims.0 != 0 && dims.1 != 0 {
|
||||
let (tgt_color_view, tgt_depth_view, tgt_color_res) =
|
||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res) =
|
||||
Self::create_rt_views(&mut self.factory, (dims.0, dims.1), self.aa_mode)?;
|
||||
self.tgt_color_res = tgt_color_res;
|
||||
self.tgt_color_view = tgt_color_view;
|
||||
self.tgt_depth_view = tgt_depth_view;
|
||||
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -242,7 +247,7 @@ impl Renderer {
|
||||
factory: &mut gfx_device_gl::Factory,
|
||||
size: (u16, u16),
|
||||
aa_mode: AaMode,
|
||||
) -> Result<(TgtColorView, TgtDepthView, TgtColorRes), RenderError> {
|
||||
) -> Result<(TgtColorView, TgtDepthStencilView, TgtColorRes), RenderError> {
|
||||
let kind = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => {
|
||||
gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Single)
|
||||
@ -279,17 +284,18 @@ impl Renderer {
|
||||
)?;
|
||||
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
|
||||
|
||||
let depth_cty = <<TgtDepthFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||
let tgt_depth_tex = factory.create_texture(
|
||||
let depth_stencil_cty = <<TgtDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||
let tgt_depth_stencil_tex = factory.create_texture(
|
||||
kind,
|
||||
levels,
|
||||
gfx::memory::Bind::DEPTH_STENCIL,
|
||||
gfx::memory::Usage::Data,
|
||||
Some(depth_cty),
|
||||
Some(depth_stencil_cty),
|
||||
)?;
|
||||
let tgt_depth_view = factory.view_texture_as_depth_stencil_trivial(&tgt_depth_tex)?;
|
||||
let tgt_depth_stencil_view =
|
||||
factory.view_texture_as_depth_stencil_trivial(&tgt_depth_stencil_tex)?;
|
||||
|
||||
Ok((tgt_color_view, tgt_depth_view, tgt_color_res))
|
||||
Ok((tgt_color_view, tgt_depth_stencil_view, tgt_color_res))
|
||||
}
|
||||
|
||||
/// Get the resolution of the render target.
|
||||
@ -303,7 +309,8 @@ impl Renderer {
|
||||
/// Queue the clearing of the depth target ready for a new frame to be
|
||||
/// rendered.
|
||||
pub fn clear(&mut self) {
|
||||
self.encoder.clear_depth(&self.tgt_depth_view, 1.0);
|
||||
self.encoder.clear_depth(&self.tgt_depth_stencil_view, 1.0);
|
||||
self.encoder.clear_stencil(&self.tgt_depth_stencil_view, 0);
|
||||
self.encoder.clear_depth(&self.win_depth_view, 1.0);
|
||||
}
|
||||
|
||||
@ -336,6 +343,7 @@ impl Renderer {
|
||||
sprite_pipeline,
|
||||
ui_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
)) => {
|
||||
self.skybox_pipeline = skybox_pipeline;
|
||||
self.figure_pipeline = figure_pipeline;
|
||||
@ -344,6 +352,7 @@ impl Renderer {
|
||||
self.sprite_pipeline = sprite_pipeline;
|
||||
self.ui_pipeline = ui_pipeline;
|
||||
self.postprocess_pipeline = postprocess_pipeline;
|
||||
self.player_shadow_pipeline = player_shadow_pipeline;
|
||||
},
|
||||
Err(e) => error!(
|
||||
"Could not recreate shaders from assets due to an error: {:#?}",
|
||||
@ -502,7 +511,7 @@ impl Renderer {
|
||||
globals: globals.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -535,7 +544,73 @@ impl Renderer {
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Queue the rendering of the player silhouette in the upcoming frame.
|
||||
pub fn render_player_shadow(
|
||||
&mut self,
|
||||
model: &Model<figure::FigurePipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<figure::Locals>,
|
||||
bones: &Consts<figure::BoneData>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
start: model.vertex_range().start,
|
||||
end: model.vertex_range().end,
|
||||
base_vertex: 0,
|
||||
instances: None,
|
||||
buffer: gfx::IndexBuffer::Auto,
|
||||
},
|
||||
&self.player_shadow_pipeline.pso,
|
||||
&figure::pipe::Data {
|
||||
vbuf: model.vbuf.clone(),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (0, 0)),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Queue the rendering of the player model in the upcoming frame.
|
||||
pub fn render_player(
|
||||
&mut self,
|
||||
model: &Model<figure::FigurePipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<figure::Locals>,
|
||||
bones: &Consts<figure::BoneData>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
start: model.vertex_range().start,
|
||||
end: model.vertex_range().end,
|
||||
base_vertex: 0,
|
||||
instances: None,
|
||||
buffer: gfx::IndexBuffer::Auto,
|
||||
},
|
||||
&self.figure_pipeline.pso,
|
||||
&figure::pipe::Data {
|
||||
vbuf: model.vbuf.clone(),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
bones: bones.buf.clone(),
|
||||
lights: lights.buf.clone(),
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -567,7 +642,7 @@ impl Renderer {
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -601,7 +676,7 @@ impl Renderer {
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
waves: (waves.srv.clone(), waves.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -633,7 +708,7 @@ impl Renderer {
|
||||
shadows: shadows.buf.clone(),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view.clone(),
|
||||
tgt_depth: self.tgt_depth_view.clone(),
|
||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -721,6 +796,7 @@ fn create_pipelines(
|
||||
GfxPipeline<sprite::pipe::Init<'static>>,
|
||||
GfxPipeline<ui::pipe::Init<'static>>,
|
||||
GfxPipeline<postprocess::pipe::Init<'static>>,
|
||||
GfxPipeline<figure::pipe::Init<'static>>,
|
||||
),
|
||||
RenderError,
|
||||
> {
|
||||
@ -869,6 +945,31 @@ fn create_pipelines(
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
|
||||
// Construct a pipeline for rendering the player silhouette
|
||||
let player_shadow_pipeline = create_pipeline(
|
||||
factory,
|
||||
figure::pipe::Init {
|
||||
tgt_depth_stencil: (
|
||||
gfx::preset::depth::PASS_TEST,
|
||||
Stencil::new(
|
||||
Comparison::Equal,
|
||||
0xff,
|
||||
(StencilOp::Keep, StencilOp::Keep, StencilOp::Keep),
|
||||
),
|
||||
),
|
||||
..figure::pipe::new()
|
||||
},
|
||||
&assets::load_watched::<String>("voxygen.shaders.figure-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>(
|
||||
"voxygen.shaders.player-shadow-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
|
||||
Ok((
|
||||
skybox_pipeline,
|
||||
figure_pipeline,
|
||||
@ -877,6 +978,7 @@ fn create_pipelines(
|
||||
sprite_pipeline,
|
||||
ui_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ pub const MIN_ZOOM: f32 = 0.1;
|
||||
// Possible TODO: Add more modes
|
||||
#[derive(PartialEq, Clone, Copy, Eq, Hash)]
|
||||
pub enum CameraMode {
|
||||
FirstPerson,
|
||||
ThirdPerson,
|
||||
FirstPerson = 0,
|
||||
ThirdPerson = 1,
|
||||
}
|
||||
|
||||
impl Default for CameraMode {
|
||||
|
@ -144,6 +144,8 @@ impl FigureMgr {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let is_player = scene_data.player_entity == entity;
|
||||
|
||||
let (pos, ori) = interpolated
|
||||
.map(|i| (Pos(i.pos), *i.ori))
|
||||
.unwrap_or((*pos, Vec3::unit_y()));
|
||||
@ -380,7 +382,7 @@ impl FigureMgr {
|
||||
let col = stats
|
||||
.map(|s| {
|
||||
Rgba::broadcast(1.0)
|
||||
+ Rgba::new(2.0, 2.0, 2.0, 0.0).map(|c| {
|
||||
+ Rgba::new(2.0, 2.0, 2., 0.00).map(|c| {
|
||||
(c / (1.0 + DAMAGE_FADE_COEFFICIENT * s.health.last_change.0)) as f32
|
||||
})
|
||||
})
|
||||
@ -627,6 +629,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedSmall(_) => {
|
||||
@ -707,6 +710,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedMedium(_) => {
|
||||
@ -789,6 +793,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::BirdMedium(_) => {
|
||||
@ -863,6 +868,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::FishMedium(_) => {
|
||||
@ -937,6 +943,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::Dragon(_) => {
|
||||
@ -1011,6 +1018,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::Critter(_) => {
|
||||
@ -1085,6 +1093,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::BirdSmall(_) => {
|
||||
@ -1159,6 +1168,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::FishSmall(_) => {
|
||||
@ -1233,6 +1243,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::BipedLarge(_) => {
|
||||
@ -1307,6 +1318,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
Body::Object(_) => {
|
||||
@ -1326,6 +1338,7 @@ impl FigureMgr {
|
||||
state_animation_rate,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
);
|
||||
},
|
||||
}
|
||||
@ -1386,6 +1399,75 @@ impl FigureMgr {
|
||||
.filter(|(_, _, _, _, stats, _, _)| stats.map_or(true, |s| !s.is_dead))
|
||||
{
|
||||
let is_player = entity == player_entity;
|
||||
|
||||
if !is_player {
|
||||
self.render_figure(
|
||||
renderer,
|
||||
tick,
|
||||
globals,
|
||||
lights,
|
||||
shadows,
|
||||
camera,
|
||||
character_state,
|
||||
entity,
|
||||
body,
|
||||
loadout,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_player(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
state: &State,
|
||||
player_entity: EcsEntity,
|
||||
tick: u64,
|
||||
globals: &Consts<Globals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
camera: &Camera,
|
||||
) {
|
||||
let ecs = state.ecs();
|
||||
|
||||
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
|
||||
let character_state = character_state_storage.get(player_entity);
|
||||
|
||||
if let Some(body) = ecs.read_storage::<Body>().get(player_entity) {
|
||||
let loadout_storage = ecs.read_storage::<Loadout>();
|
||||
let loadout = loadout_storage.get(player_entity);
|
||||
|
||||
self.render_figure(
|
||||
renderer,
|
||||
tick,
|
||||
globals,
|
||||
lights,
|
||||
shadows,
|
||||
camera,
|
||||
character_state,
|
||||
player_entity,
|
||||
body,
|
||||
loadout,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_figure(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
tick: u64,
|
||||
globals: &Consts<Globals>,
|
||||
lights: &Consts<Light>,
|
||||
shadows: &Consts<Shadow>,
|
||||
camera: &Camera,
|
||||
character_state: Option<&CharacterState>,
|
||||
entity: EcsEntity,
|
||||
body: &Body,
|
||||
loadout: Option<&Loadout>,
|
||||
is_player: bool,
|
||||
) {
|
||||
let player_camera_mode = if is_player {
|
||||
camera.get_mode()
|
||||
} else {
|
||||
@ -1597,12 +1679,16 @@ impl FigureMgr {
|
||||
)
|
||||
}),
|
||||
} {
|
||||
if is_player {
|
||||
renderer.render_player(model, globals, locals, bone_consts, lights, shadows);
|
||||
renderer.render_player_shadow(model, globals, locals, bone_consts, lights, shadows);
|
||||
} else {
|
||||
renderer.render_figure(model, globals, locals, bone_consts, lights, shadows);
|
||||
}
|
||||
} else {
|
||||
trace!("Body has no saved figure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn figure_count(&self) -> usize {
|
||||
self.character_states.len()
|
||||
@ -1705,6 +1791,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
state_animation_rate: f32,
|
||||
lpindex: u8,
|
||||
visible: bool,
|
||||
is_player: bool,
|
||||
) {
|
||||
self.visible = visible;
|
||||
self.lpindex = lpindex;
|
||||
@ -1720,7 +1807,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
* Mat4::rotation_x(ori.z.atan2(Vec2::from(ori).magnitude()))
|
||||
* Mat4::scaling_3d(Vec3::from(0.8 * scale));
|
||||
|
||||
let locals = FigureLocals::new(mat, col);
|
||||
let locals = FigureLocals::new(mat, col, is_player);
|
||||
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
||||
|
||||
renderer
|
||||
|
@ -347,6 +347,7 @@ impl Scene {
|
||||
.unwrap_or(BlockKind::Air),
|
||||
self.select_pos,
|
||||
gamma,
|
||||
self.camera.get_mode(),
|
||||
)])
|
||||
.expect("Failed to update global constants");
|
||||
|
||||
@ -381,6 +382,13 @@ impl Scene {
|
||||
tick: u64,
|
||||
) {
|
||||
// Render terrain and figures.
|
||||
self.terrain.render(
|
||||
renderer,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
self.figure_mgr.render(
|
||||
renderer,
|
||||
state,
|
||||
@ -391,13 +399,6 @@ impl Scene {
|
||||
&self.shadows,
|
||||
&self.camera,
|
||||
);
|
||||
self.terrain.render(
|
||||
renderer,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
|
||||
// Render the skybox.
|
||||
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
||||
@ -410,6 +411,17 @@ impl Scene {
|
||||
self.camera.get_focus_pos(),
|
||||
);
|
||||
|
||||
self.figure_mgr.render_player(
|
||||
renderer,
|
||||
state,
|
||||
player_entity,
|
||||
tick,
|
||||
&self.globals,
|
||||
&self.lights,
|
||||
&self.shadows,
|
||||
&self.camera,
|
||||
);
|
||||
|
||||
renderer.render_post_process(
|
||||
&self.postprocess.model,
|
||||
&self.globals,
|
||||
|
@ -170,6 +170,7 @@ impl Scene {
|
||||
BlockKind::Air,
|
||||
None,
|
||||
scene_data.gamma,
|
||||
self.camera.get_mode(),
|
||||
)]) {
|
||||
error!("Renderer failed to update: {:?}", err);
|
||||
}
|
||||
@ -199,6 +200,7 @@ impl Scene {
|
||||
1.0,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user