Use location, rotation and scale instead of model matrix in vulkan

This commit is contained in:
Benau 2022-08-26 09:36:30 +08:00
parent 514e3a50ad
commit 97e5064535
6 changed files with 53 additions and 17 deletions

View File

@ -1,4 +1,5 @@
#include "utils/spm_layout.h" #include "utils/spm_layout.h"
#include "../utils/get_world_location.vert"
layout(push_constant) uniform Constants layout(push_constant) uniform Constants
{ {
@ -9,11 +10,13 @@ void main()
{ {
vec3 offset = sin(u_push_constants.m_wind_direction * (v_position.y * 0.1)); vec3 offset = sin(u_push_constants.m_wind_direction * (v_position.y * 0.1));
offset += vec3(cos(u_push_constants.m_wind_direction) * 0.7); offset += vec3(cos(u_push_constants.m_wind_direction) * 0.7);
vec3 position = v_position + offset * v_color.r;
mat4 model_matrix = u_object_buffer.m_objects[gl_InstanceIndex].m_model; vec4 v_world_position = getWorldPosition(
gl_Position = u_camera.m_projection_view_matrix * model_matrix * u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz + offset *
vec4(position, 1.0); v_color.r,
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;
f_vertex_color = vec4(1.0); f_vertex_color = vec4(1.0);
f_uv = v_uv; f_uv = v_uv;
f_uv_two = v_uv_two; f_uv_two = v_uv_two;

View File

@ -1,10 +1,13 @@
#include "utils/spm_layout.h" #include "utils/spm_layout.h"
#include "../utils/get_world_location.vert"
void main() void main()
{ {
mat4 model_matrix = u_object_buffer.m_objects[gl_InstanceIndex].m_model; vec4 v_world_position = getWorldPosition(
gl_Position = u_camera.m_projection_view_matrix * model_matrix * u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz,
vec4(v_position, 1.0); 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;
f_vertex_color = v_color.zyxw; f_vertex_color = v_color.zyxw;
f_uv = v_uv; f_uv = v_uv;
f_uv_two = v_uv_two; f_uv_two = v_uv_two;

View File

@ -1,4 +1,5 @@
#include "utils/spm_layout.h" #include "utils/spm_layout.h"
#include "../utils/get_world_location.vert"
void main() void main()
{ {
@ -8,9 +9,13 @@ void main()
v_weight[1] * u_skinning_matrices.m_mat[max(v_joint[1] + offset, 0)] + 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[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)]; v_weight[3] * u_skinning_matrices.m_mat[max(v_joint[3] + offset, 0)];
mat4 model_matrix = u_object_buffer.m_objects[gl_InstanceIndex].m_model; vec4 v_skinning_position = joint_matrix * vec4(v_position.xyz, 1.0);
gl_Position = u_camera.m_projection_view_matrix * model_matrix * vec4 v_world_position = getWorldPosition(
joint_matrix * vec4(v_position, 1.0); u_object_buffer.m_objects[gl_InstanceIndex].m_position.xyz,
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
u_object_buffer.m_objects[gl_InstanceIndex].m_scale.xyz,
v_skinning_position.xyz);
gl_Position = u_camera.m_projection_view_matrix * v_world_position;
f_vertex_color = v_color.zyxw; f_vertex_color = v_color.zyxw;
f_uv = v_uv; f_uv = v_uv;
f_uv_two = v_uv_two; f_uv_two = v_uv_two;

View File

@ -10,7 +10,9 @@ layout(std140, set = 1, binding = 0) uniform CameraBuffer
struct ObjectData struct ObjectData
{ {
mat4 m_model; vec4 m_position;
vec4 m_rotation;
vec4 m_scale;
int m_skinning_offest; int m_skinning_offest;
int m_material_id; int m_material_id;
vec2 m_texture_trans; vec2 m_texture_trans;

View File

@ -16,6 +16,8 @@
#include "ge_vulkan_skybox_renderer.hpp" #include "ge_vulkan_skybox_renderer.hpp"
#include "ge_vulkan_texture_descriptor.hpp" #include "ge_vulkan_texture_descriptor.hpp"
#include "mini_glm.hpp"
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@ -25,8 +27,30 @@ namespace GE
ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id, ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id,
int skinning_offset) int skinning_offset)
{ {
memcpy(m_mat_1, node->getAbsoluteTransformation().pointer(), using namespace MiniGLM;
sizeof(irr::core::matrix4)); const irr::core::matrix4& model_mat = node->getAbsoluteTransformation();
float position[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)
{
irr::core::matrix4 local_mat = model_mat;
local_mat[0] = local_mat[0] / scale.X / local_mat[15];
local_mat[1] = local_mat[1] / scale.X / local_mat[15];
local_mat[2] = local_mat[2] / scale.X / local_mat[15];
local_mat[4] = local_mat[4] / scale.Y / local_mat[15];
local_mat[5] = local_mat[5] / scale.Y / local_mat[15];
local_mat[6] = local_mat[6] / scale.Y / local_mat[15];
local_mat[8] = local_mat[8] / scale.Z / local_mat[15];
local_mat[9] = local_mat[9] / scale.Z / local_mat[15];
local_mat[10] = local_mat[10] / scale.Z / local_mat[15];
rotation = getQuaternion(local_mat);
// Conjugated quaternion in glsl
rotation.W = -rotation.W;
}
memcpy(m_position, position, sizeof(position));
memcpy(m_rotation, &rotation, sizeof(irr::core::quaternion));
memcpy(m_scale, &scale, sizeof(irr::core::vector3df));
m_skinning_offset = skinning_offset; m_skinning_offset = skinning_offset;
m_material_id = material_id; m_material_id = material_id;
m_texture_trans[0] = 0.0f; m_texture_trans[0] = 0.0f;

View File

@ -28,10 +28,9 @@ class GEVulkanTextureDescriptor;
struct ObjectData struct ObjectData
{ {
float m_mat_1[4]; float m_position[4];
float m_mat_2[4]; float m_rotation[4];
float m_mat_3[4]; float m_scale[4];
float m_mat_4[4];
int m_skinning_offset; int m_skinning_offset;
int m_material_id; int m_material_id;
float m_texture_trans[2]; float m_texture_trans[2];