Add colorization for vulkan
This commit is contained in:
parent
d3ddcd884d
commit
76c39afd8b
@ -1,15 +1,27 @@
|
||||
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 = 4) in float f_hue_change;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.h"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 mixed_color = sampleMeshTexture0(f_material_id, f_uv)* f_vertex_color;
|
||||
if (mixed_color.a < 0.5)
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
if (tex_color.a * f_vertex_color.a < 0.5)
|
||||
discard;
|
||||
o_color = vec4(mixed_color.xyz, 1.0);
|
||||
tex_color.xyz *= f_vertex_color.xyz;
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
vec2 new_xy = vec2(f_hue_change, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, tex_color.a);
|
||||
}
|
||||
|
||||
o_color = vec4(tex_color.xyz, 1.0);
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
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 = 4) in float f_hue_change;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.h"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 mixed_color = sampleMeshTexture0(f_material_id, f_uv).xyz * f_vertex_color.xyz;
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
float mask = tex_color.a;
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#ifndef PBR_ENABLED
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(f_hue_change,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, 1.0);
|
||||
}
|
||||
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
o_color = vec4(mixed_color * 0.5, 0.5);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ void main()
|
||||
offset += vec3(cos(u_push_constants.m_wind_direction) * 0.7);
|
||||
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz + offset *
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation + offset *
|
||||
v_color.r,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale.xyz, v_position);
|
||||
@ -21,4 +21,5 @@ void main()
|
||||
f_uv = v_uv;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
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 = 4) in float f_hue_change;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.h"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 mixed_color = sampleMeshTexture0(f_material_id, f_uv).xyz * f_vertex_color.xyz;
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
float mask = tex_color.a;
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#ifndef PBR_ENABLED
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(f_hue_change,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, 1.0);
|
||||
}
|
||||
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
o_color = vec4(mixed_color, 1.0);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
void main()
|
||||
{
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale.xyz, v_position);
|
||||
gl_Position = u_camera.m_projection_view_matrix * v_world_position;
|
||||
@ -12,4 +12,5 @@ void main()
|
||||
f_uv = v_uv + u_object_buffer.m_objects[gl_InstanceIndex].m_texture_trans;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ void main()
|
||||
v_weight[1] * u_skinning_matrices.m_mat[max(v_joint[1] + offset, 0)] +
|
||||
v_weight[2] * u_skinning_matrices.m_mat[max(v_joint[2] + offset, 0)] +
|
||||
v_weight[3] * u_skinning_matrices.m_mat[max(v_joint[3] + offset, 0)];
|
||||
vec4 v_skinning_position = joint_matrix * vec4(v_position.xyz, 1.0);
|
||||
vec4 v_skinning_position = joint_matrix * vec4(v_position, 1.0);
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale.xyz,
|
||||
v_skinning_position.xyz);
|
||||
@ -20,4 +20,5 @@ void main()
|
||||
f_uv = v_uv + u_object_buffer.m_objects[gl_InstanceIndex].m_texture_trans;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ layout(std140, set = 1, binding = 0) uniform CameraBuffer
|
||||
|
||||
struct ObjectData
|
||||
{
|
||||
vec4 m_position;
|
||||
vec3 m_translation;
|
||||
float m_hue_change;
|
||||
vec4 m_rotation;
|
||||
vec4 m_scale;
|
||||
int m_skinning_offest;
|
||||
@ -41,3 +42,4 @@ layout(location = 0) out vec4 f_vertex_color;
|
||||
layout(location = 1) out vec2 f_uv;
|
||||
layout(location = 2) out vec2 f_uv_two;
|
||||
layout(location = 3) flat out int f_material_id;
|
||||
layout(location = 4) out float f_hue_change;
|
||||
|
@ -30,7 +30,7 @@ ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id,
|
||||
{
|
||||
using namespace MiniGLM;
|
||||
const irr::core::matrix4& model_mat = node->getAbsoluteTransformation();
|
||||
float position[3] = { model_mat[12], model_mat[13], model_mat[14] };
|
||||
float translation[3] = { model_mat[12], model_mat[13], model_mat[14] };
|
||||
irr::core::quaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
irr::core::vector3df scale = model_mat.getScale();
|
||||
if (scale.X != 0.0f && scale.Y != 0.0f && scale.Z != 0.0f)
|
||||
@ -49,7 +49,7 @@ ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id,
|
||||
// Conjugated quaternion in glsl
|
||||
rotation.W = -rotation.W;
|
||||
}
|
||||
memcpy(m_position, position, sizeof(position));
|
||||
memcpy(&m_translation_x, translation, sizeof(translation));
|
||||
memcpy(m_rotation, &rotation, sizeof(irr::core::quaternion));
|
||||
memcpy(m_scale, &scale, sizeof(irr::core::vector3df));
|
||||
m_skinning_offset = skinning_offset;
|
||||
@ -58,6 +58,11 @@ ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id,
|
||||
node->getMaterial(irrlicht_material_id).getTextureMatrix(0);
|
||||
m_texture_trans[0] = texture_matrix[8];
|
||||
m_texture_trans[1] = texture_matrix[9];
|
||||
auto& ri = node->getMaterial(irrlicht_material_id).getRenderInfo();
|
||||
if (ri && ri->getHue() > 0.0f)
|
||||
m_hue_change = ri->getHue();
|
||||
else
|
||||
m_hue_change = 0.0f;
|
||||
} // ObjectData
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -28,7 +28,10 @@ class GEVulkanTextureDescriptor;
|
||||
|
||||
struct ObjectData
|
||||
{
|
||||
float m_position[4];
|
||||
float m_translation_x;
|
||||
float m_translation_y;
|
||||
float m_translation_z;
|
||||
float m_hue_change;
|
||||
float m_rotation[4];
|
||||
float m_scale[4];
|
||||
int m_skinning_offset;
|
||||
|
@ -500,4 +500,9 @@ bool CentralVideoSettings::isARBTextureBufferObjectUsable() const
|
||||
return hasTextureBufferObject;
|
||||
}
|
||||
|
||||
bool CentralVideoSettings::supportsColorization() const
|
||||
{
|
||||
return isGLSL() || GE::getDriver()->getDriverType() == video::EDT_VULKAN;
|
||||
}
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -93,6 +93,7 @@ public:
|
||||
bool isShadowEnabled() const;
|
||||
bool isTextureCompressionEnabled() const;
|
||||
bool isDeferredEnabled() const;
|
||||
bool supportsColorization() const;
|
||||
};
|
||||
|
||||
extern CentralVideoSettings* CVS;
|
||||
|
@ -259,11 +259,6 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
m_nodes_set.insert(node);
|
||||
node->setParent(this);
|
||||
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
((scene::IAnimatedMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
if (node->getType() == scene::ESNT_MESH)
|
||||
((scene::IMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
|
||||
node->drop();
|
||||
|
||||
node->updateAbsolutePosition();
|
||||
|
@ -593,22 +593,25 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
Vec3 kart_max = m_mesh->getMax();
|
||||
#ifndef SERVER_ONLY
|
||||
// Test if kart model support colorization
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
for (u32 i = 0; i < m_mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb =
|
||||
static_cast<SP::SPMeshBuffer*>(m_mesh->getMeshBuffer(i));
|
||||
SP::SPMeshBuffer* spmb =
|
||||
dynamic_cast<SP::SPMeshBuffer*>(m_mesh->getMeshBuffer(i));
|
||||
if (!spmb)
|
||||
{
|
||||
m_support_colorization = m_support_colorization ||
|
||||
m_mesh->getMeshBuffer(i)->getMaterial().isColorizable();
|
||||
continue;
|
||||
}
|
||||
// Pre-upload gl meshes and textures for kart screen
|
||||
mb->uploadGLMesh();
|
||||
std::vector<Material*> mbs = mb->getAllSTKMaterials();
|
||||
spmb->uploadGLMesh();
|
||||
std::vector<Material*> mbs = spmb->getAllSTKMaterials();
|
||||
for (Material* m : mbs)
|
||||
{
|
||||
m_support_colorization =
|
||||
m_support_colorization || m->isColorizable();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef MOVE_KART_MESHES
|
||||
|
@ -322,7 +322,7 @@ void World::initTeamArrows(AbstractKart* k)
|
||||
|
||||
KartModel* km = k->getKartModel();
|
||||
// Color of karts can be changed using shaders if the model supports
|
||||
if (km->supportColorization() && CVS->isGLSL())
|
||||
if (km->supportColorization() && CVS->supportsColorization())
|
||||
return;
|
||||
|
||||
float arrow_pos_height = km->getHeight() + 0.5f;
|
||||
|
@ -113,7 +113,7 @@ void BaseUserScreen::init()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
getWidget<IconButtonWidget>("default_kart_color")
|
||||
->setVisible(CVS->isGLSL());
|
||||
->setVisible(CVS->supportsColorization());
|
||||
#endif
|
||||
|
||||
m_password_tb->setPasswordBox(true, L'*');
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include <ge_render_info.hpp>
|
||||
#include "graphics/sp/sp_mesh_buffer.hpp"
|
||||
#include "graphics/sp/sp_mesh_node.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
@ -41,6 +40,7 @@
|
||||
|
||||
#include <IAnimatedMeshSceneNode.h>
|
||||
#include <ISceneManager.h>
|
||||
#include <ge_render_info.hpp>
|
||||
|
||||
/** A track object: any additional object on the track. This object implements
|
||||
* a graphics-only representation, i.e. there is no physical representation.
|
||||
@ -196,35 +196,10 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
std::string model_name;
|
||||
xml_node.get("model", &model_name);
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
scene::IMesh* mesh = NULL;
|
||||
// Use the first material in mesh to determine hue
|
||||
Material* colorized = NULL;
|
||||
if (model_name.size() > 0)
|
||||
{
|
||||
mesh = irr_driver->getMesh(model_name);
|
||||
if (mesh != NULL)
|
||||
{
|
||||
for (u32 j = 0; j < mesh->getMeshBufferCount(); j++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
|
||||
(mesh->getMeshBuffer(j));
|
||||
std::vector<Material*> mbs = mb->getAllSTKMaterials();
|
||||
for (Material* m : mbs)
|
||||
{
|
||||
if (m->isColorizable() && m->hasRandomHue())
|
||||
{
|
||||
colorized = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (colorized != NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -232,12 +207,27 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
xml_node.get("lod_group", &group_name);
|
||||
// Try to get the first mesh from lod groups
|
||||
mesh = model_def_loader.getFirstMeshFor(group_name);
|
||||
}
|
||||
|
||||
// Use the first material in mesh to determine hue
|
||||
Material* colorized = NULL;
|
||||
if (mesh != NULL)
|
||||
{
|
||||
for (u32 j = 0; j < mesh->getMeshBufferCount(); j++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
|
||||
(mesh->getMeshBuffer(j));
|
||||
scene::IMeshBuffer* buf = mesh->getMeshBuffer(j);
|
||||
SP::SPMeshBuffer* mb = dynamic_cast<SP::SPMeshBuffer*>(buf);
|
||||
if (!mb)
|
||||
{
|
||||
Material* m = material_manager->getMaterialFor(buf
|
||||
->getMaterial().getTexture(0), buf);
|
||||
if (m->isColorizable() && m->hasRandomHue())
|
||||
{
|
||||
colorized = m;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
std::vector<Material*> mbs = mb->getAllSTKMaterials();
|
||||
for (Material* m : mbs)
|
||||
{
|
||||
@ -253,7 +243,6 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If at least one material is colorizable, add RenderInfo for it
|
||||
if (colorized != NULL)
|
||||
@ -264,7 +253,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
m_render_info = std::make_shared<GE::GERenderInfo>(hue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
scene::ISceneNode *glownode = NULL;
|
||||
bool is_movable = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user