Skip to content

Commit

Permalink
WIP Ghost Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Froggy618157725 committed Jul 11, 2024
1 parent 125b97d commit d9fb7fb
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 27 deletions.
34 changes: 25 additions & 9 deletions crates/alkahest-renderer/assets/shaders/gui/outline.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

cbuffer cb_outline : register(b0) {
float time_since_selection;
bool ghost;
};

#define OUTLINE_COLOR float3(1.0, 0.6, 0.2) * 0.6
#define OUTLINE_COLOR_BACK (OUTLINE_COLOR * 0.6)
#define OUTLINE_COLOR float3(1.0, 0.6, 0.2)
#define GHOST_COLOR float3(0.2, 0.6, 1.0)
#define OUTLINE_WIDTH 2

Texture2D DepthTargetOutline : register(t0);
Expand All @@ -24,6 +25,13 @@ float2 QueryTexelSize(Texture2D t) {
// Pixel Shader
float4 PSMain(VSOutput input) : SV_Target {
float depth = DepthTargetOutline.Sample(SampleType, input.uv).r;
float3 outline_color;
if (ghost) {
outline_color = GHOST_COLOR;
} else {
outline_color = OUTLINE_COLOR;
}
float3 outline_color_back = outline_color * 0.6;

// if the pixel isn't 0 (we are on the depth silhouette)
if (depth != 0)
Expand All @@ -47,23 +55,31 @@ float4 PSMain(VSOutput input) : SV_Target {
{
float depthScene = DepthTargetScene.Sample(SampleType, input.uv).r;
if(depthScene > depth) // Behind scene
return float4(OUTLINE_COLOR, 0.65);
return float4(outline_color, 0.65);
else // In front of scene
return float4(OUTLINE_COLOR, 1);
return float4(outline_color, 1);
}
}
}

// if we are on the silhouette but not on the border
float depthScene = DepthTargetScene.Sample(SampleType, input.uv).r;
float fillFlash = (1.0 - timeNormMul) * 0.20;
if(depthScene > depth) { // Behind scene
dither_discard(input.screen_pos, 0.15);
// return float4(OUTLINE_COLOR, 0.16 + fillFlash);
return float4(lerp(OUTLINE_COLOR, OUTLINE_COLOR_BACK, timeNormMul), 0.75 + fillFlash);
if (!ghost) {
if(depthScene > depth) { // Behind scene
dither_discard(input.screen_pos, 0.15);
// return float4(outline_color, 0.16 + fillFlash);
return float4(lerp(outline_color, outline_color_back, timeNormMul), 0.75 + fillFlash);
}
} else {
if(depthScene <= depth) {
dither_discard(input.screen_pos, 0.50);
return float4(outline_color, 0.75 + fillFlash);
}
}

// else // In front of scene
// return float4(OUTLINE_COLOR, 0.015 + fillFlash);
// return float4(outline_color, 0.015 + fillFlash);
}

discard;
Expand Down
1 change: 1 addition & 0 deletions crates/alkahest-renderer/src/ecs/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl AsRef<str> for Label {

pub struct Hidden;
pub struct Global;
pub struct Ghost;

/// Marker component to indicate that the entity is allowed to be modified in
/// potentially destructive ways (e.g. deleting it, changing it's name, etc.)
Expand Down
2 changes: 2 additions & 0 deletions crates/alkahest-renderer/src/ecs/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub enum EntityTag {
Activity,
Ambient,
Global,
Ghost,
Havok,
Utility,
User,
Expand Down Expand Up @@ -116,6 +117,7 @@ impl Display for EntityTag {
EntityTag::Activity => write!(f, "Activity"),
EntityTag::Ambient => write!(f, "Ambient"),
EntityTag::Global => write!(f, "Global"),
EntityTag::Ghost => write!(f, "Ghost"),
EntityTag::Havok => write!(f, "Havok"),
EntityTag::Utility => write!(f, "Utility"),
EntityTag::User => write!(f, "User"),
Expand Down
20 changes: 18 additions & 2 deletions crates/alkahest-renderer/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ use alkahest_data::{
};
use anyhow::Context;
use bitflags::bitflags;
use glam::Vec3;
use hecs::Entity;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use strum::{EnumCount, EnumIter};
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;

use crate::{
ecs::{
common::Hidden,
common::{Ghost, Hidden},
render::{
dynamic_geometry::update_dynamic_model_system,
static_geometry::update_static_instances_system,
Expand Down Expand Up @@ -161,15 +163,29 @@ impl Renderer {
if !scene.entity(selected).map_or(true, |v| v.has::<Hidden>()) {
self.draw_outline(
scene,
selected,
Vec::from([selected]),
resources
.get::<SelectedEntity>()
.time_selected
.elapsed()
.as_secs_f32(),
false
);
}
}
let ghosts : Vec<Entity> = scene.query::<&Ghost>().iter().map(|(e, _ )| e).collect();
if ghosts.len() > 0 {
self.draw_outline(
scene,
ghosts,
resources
.get::<SelectedEntity>()
.time_selected
.elapsed()
.as_secs_f32(),
true
);
}
}

unsafe {
Expand Down
40 changes: 27 additions & 13 deletions crates/alkahest-renderer/src/renderer/pickbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ use crate::{
util::Hocus,
};

pub struct OutlineParams {
time_since_select: f32,
ghost: bool,
}

impl Renderer {
pub(super) fn draw_pickbuffer(&self, scene: &Scene, selected: Option<Entity>) {
gpu_event!(self.gpu, "pickbuffer");
Expand All @@ -50,7 +55,7 @@ impl Renderer {
}

// TODO(cohae): move rendering logic to Pickbuffer (where possible)
pub(super) fn draw_outline(&self, scene: &Scene, selected: Entity, time_since_select: f32) {
pub(super) fn draw_outline(&self, scene: &Scene, selected: Vec<Entity>, time_since_select: f32, ghost: bool) {
gpu_event!(self.gpu, "selection_outline");

self.pickbuffer.outline_depth.clear(0.0, 0);
Expand All @@ -69,13 +74,15 @@ impl Renderer {
self.gpu
.context()
.OMSetDepthStencilState(Some(&self.pickbuffer.outline_depth.state), 0);
draw_entity(
scene,
selected,
self,
Some(&self.pickbuffer.static_instance_cb),
TfxRenderStage::GenerateGbuffer,
);
for e in selected {
draw_entity(
scene,
e,
self,
Some(&self.pickbuffer.static_instance_cb),
TfxRenderStage::GenerateGbuffer,
);
}

// Draw the outline itself
self.gpu
Expand All @@ -90,19 +97,24 @@ impl Renderer {
self.gpu.set_input_topology(EPrimitiveType::Triangles);
self.gpu
.context()
.VSSetShader(&self.pickbuffer.outline_vs, None);
.VSSetShader(&self.pickbuffer.outline_vs.clone(), None);
self.gpu
.context()
.PSSetShader(&self.pickbuffer.outline_ps, None);
.PSSetShader(&self.pickbuffer.outline_ps.clone(), None);
self.gpu.context().PSSetShaderResources(
0,
Some(&[
Some(self.pickbuffer.outline_depth.texture_view.clone()),
Some(self.data.lock().gbuffers.depth.texture_view.clone()),
]),
);
self.pickbuffer.outline_cb.write(&time_since_select).ok();
self.pickbuffer.outline_cb.bind(0, TfxShaderStage::Pixel);
if ghost {
self.pickbuffer.ghost_cb.write(&OutlineParams {time_since_select, ghost}).ok();
self.pickbuffer.ghost_cb.bind(0, TfxShaderStage::Pixel);
} else {
self.pickbuffer.outline_cb.write(&OutlineParams {time_since_select, ghost}).ok();
self.pickbuffer.outline_cb.bind(0, TfxShaderStage::Pixel);
}

self.gpu.context().Draw(3, 0);
}
Expand All @@ -121,7 +133,8 @@ pub struct Pickbuffer {

pub(super) outline_vs: ID3D11VertexShader,
pub(super) outline_ps: ID3D11PixelShader,
pub(super) outline_cb: ConstantBuffer<f32>,
pub(super) outline_cb: ConstantBuffer<OutlineParams>,
pub(super) ghost_cb: ConstantBuffer<OutlineParams>,

clear_vs: ID3D11VertexShader,
clear_ps: ID3D11PixelShader,
Expand Down Expand Up @@ -176,6 +189,7 @@ impl Pickbuffer {
outline_vs,
outline_ps,
outline_cb: ConstantBuffer::create(gctx.clone(), None)?,
ghost_cb: ConstantBuffer::create(gctx.clone(), None)?,
clear_vs,
clear_ps,
pick_ps,
Expand Down
29 changes: 26 additions & 3 deletions crates/alkahest/src/gui/inspector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use alkahest_data::map::{SLightCollection, SRespawnPoint};
use alkahest_renderer::{
camera::Camera,
ecs::{
common::{EntityWorldId, Global, Hidden, Label, Mutable},
common::{EntityWorldId, Ghost, Global, Hidden, Label, Mutable},
map::{CubemapVolume, NodeMetadata},
render::{
decorators::DecoratorRenderer, dynamic_geometry::DynamicModelComponent,
Expand Down Expand Up @@ -183,13 +183,30 @@ pub fn show_inspector_panel(

let mut global = e.has::<Global>();
let mut global_changed = false;
if e.has::<Mutable>() && !e.has::<Route>() {
if ui.checkbox(&mut global, "Show in all Maps").changed() {
let mut mutable = e.has::<Mutable>();
if !e.has::<Route>() {
if ui
.checkbox(
&mut global,
if mutable {
"Show in all Maps"
} else {
"Show ghost in all Maps"
},
)
.changed()
{
global_changed = true;
if global {
cmd.insert_one(ent, Global);
if (!mutable) {
cmd.insert_one(ent, Ghost);
}
} else {
cmd.remove_one::<Global>(ent);
if (!mutable) {
cmd.remove_one::<Ghost>(ent);
}
}
};
ui.separator();
Expand All @@ -199,8 +216,14 @@ pub fn show_inspector_panel(
if global_changed {
if global {
insert_tag(scene, ent, EntityTag::Global);
if (!mutable) {
insert_tag(scene, ent, EntityTag::Ghost);
}
} else {
remove_tag(scene, ent, EntityTag::Global);
if (!mutable) {
insert_tag(scene, ent, EntityTag::Ghost);
}
}
}
}
Expand Down

0 comments on commit d9fb7fb

Please sign in to comment.