Add shader to render ghost kart

This commit is contained in:
Benau 2022-07-30 09:03:56 +08:00
parent 1a953b8a6c
commit 2696ef2567
5 changed files with 71 additions and 2 deletions

View File

@ -0,0 +1,13 @@
layout(location = 0) in vec4 f_vertex_color;
layout(location = 1) in vec2 f_uv;
layout(location = 3) flat in int f_material_id;
layout(location = 0) out vec4 o_color;
#include "utils/sample_mesh_texture.h"
void main()
{
vec3 mixed_color = sampleMeshTexture0(f_material_id, f_uv).xyz * f_vertex_color.xyz;
o_color = vec4(mixed_color * 0.5, 0.5);
}

View File

@ -257,6 +257,7 @@ std::string GEVulkanDrawCall::getShader(irr::scene::ISceneNode* node,
case irr::video::EMT_ONETEXTURE_BLEND: return "alphablend";
case irr::video::EMT_SOLID_2_LAYER: return "decal";
case irr::video::EMT_STK_GRASS: return "grass";
case irr::video::EMT_STK_GHOST: return "ghost";
default: return "solid";
}
} // getShader
@ -308,9 +309,17 @@ void GEVulkanDrawCall::createAllPipelines(GEVulkanDriver* vk)
settings.m_vertex_shader = "spm.vert";
settings.m_skinning_vertex_shader = "spm_skinning.vert";
settings.m_push_constants_func = nullptr;
settings.m_depth_write = true;
settings.m_backface_culling = true;
settings.m_alphablend = true;
settings.m_drawing_priority = (char)9;
settings.m_fragment_shader = "ghost.frag";
settings.m_shader_name = "ghost";
createPipeline(vk, settings);
settings.m_depth_write = false;
settings.m_backface_culling = false;
settings.m_alphablend = true;
settings.m_drawing_priority = (char)10;
settings.m_fragment_shader = "transparent.frag";

View File

@ -195,6 +195,9 @@ namespace video
//! Alphatest material for grass without using vertex color in stk. */
EMT_STK_GRASS,
//! Render objects like ghost in stk (used by ghost karts for now). */
EMT_STK_GHOST,
//! This value is not used. It only forces this enumeration to compile to 32 bit.
EMT_FORCE_32BIT = 0x7fffffff
};

View File

@ -22,6 +22,7 @@
#include "karts/controller/ghost_controller.hpp"
#include "karts/kart_gfx.hpp"
#include "karts/kart_model.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "modes/easter_egg_hunt.hpp"
#include "modes/linear_world.hpp"
@ -45,6 +46,8 @@ GhostKart::GhostKart(const std::string& ident, unsigned int world_kart_id,
// ----------------------------------------------------------------------------
void GhostKart::reset()
{
m_current_attachment = -1;
m_graphical_y_offset = 0;
m_node->setVisible(true);
Kart::reset();
// This will set the correct start position
@ -80,6 +83,44 @@ void GhostKart::addReplayEvent(float time,
} // addReplayEvent
// ----------------------------------------------------------------------------
void GhostKart::setGhostKartMaterial()
{
if (irr_driver->getVideoDriver()->getDriverType() != video::EDT_VULKAN ||
m_current_attachment == (int)m_attachment->getType())
return;
m_current_attachment = (int)m_attachment->getType();
std::function<void(core::array<scene::ISceneNode*>&)> set_ghost =
[&](core::array<scene::ISceneNode*>& child)
{
for (unsigned i = 0; i < child.size(); i++)
{
scene::ISceneNode* node = child[i];
if (node->getType() != irr::scene::ESNT_ANIMATED_MESH &&
node->getType() != irr::scene::ESNT_MESH)
continue;
if (node->getType() == scene::ESNT_ANIMATED_MESH)
{
scene::IAnimatedMeshSceneNode* anode = static_cast<
scene::IAnimatedMeshSceneNode*>(node);
anode->setReadOnlyMaterials(false);
for (unsigned j = 0; j < anode->getJointCount(); j++)
set_ghost(anode->getJointNode(j)->getChildren());
}
else if (node->getType() == scene::ESNT_MESH)
{
static_cast<scene::IMeshSceneNode*>(node)
->setReadOnlyMaterials(false);
}
for (unsigned j = 0; j < node->getMaterialCount(); j++)
node->getMaterial(j).MaterialType = video::EMT_STK_GHOST;
set_ghost(node->getChildren());
}
};
set_ghost(m_node->getChildren());
} // setGhostKartMaterial
// ----------------------------------------------------------------------------
/** Called once per rendered frame. It is used to only update any graphical
* effects.
@ -96,6 +137,7 @@ void GhostKart::updateGraphics(float dt)
Moveable::updateGraphics(center_shift, btQuaternion(0, 0, 0, 1));
// Also update attachment's graphics
m_attachment->updateGraphics(dt);
setGhostKartMaterial();
} // updateGraphics
// ----------------------------------------------------------------------------

View File

@ -50,10 +50,12 @@ private:
unsigned int m_last_egg_idx = 0;
int m_current_attachment;
// ----------------------------------------------------------------------------
/** Compute the time at which the ghost finished the race */
void computeFinishTime();
// ----------------------------------------------------------------------------
void setGhostKartMaterial();
public:
GhostKart(const std::string& ident, unsigned int world_kart_id,
int position, float color_hue,