Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GameDevWeek
Dependencies
Cpp
mirrage
Commits
a194bb8f
Commit
a194bb8f
authored
Sep 16, 2018
by
Florian Oetke
Browse files
integrated animations and culling with shadowmap rendering (fixes #32)
parent
601584d4
Changes
19
Hide whitespace changes
Inline
Side-by-side
assets/core_assets/assets_core_shader.map
View file @
a194bb8f
...
...
@@ -7,6 +7,8 @@ vert_shader:light_directional = shader/bin/fullscreen.vert.spv
frag_shader:light_directional = shader/bin/light_directional.frag.spv
vert_shader:shadow_model = shader/bin/shadow_model.vert.spv
vert_shader:shadow_model_animated = shader/bin/shadow_model_animated.vert.spv
vert_shader:shadow_model_animated_dqs = shader/bin/shadow_model_animated_dqs.vert.spv
frag_shader:shadow_model = shader/bin/shadow_model.frag.spv
vert_shader:model = shader/bin/model.vert.spv
...
...
assets/core_assets/shader/bin/shadow_model_animated.vert.spv
0 → 100644
View file @
a194bb8f
File added
assets/core_assets/shader/bin/shadow_model_animated_dqs.vert.spv
0 → 100644
View file @
a194bb8f
File added
assets/core_assets/shader/shadow_model_animated.vert
0 → 100644
View file @
a194bb8f
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include
"global_uniforms.glsl"
layout
(
location
=
0
)
in
vec3
position
;
layout
(
location
=
1
)
in
vec3
normal
;
layout
(
location
=
2
)
in
vec2
tex_coords
;
layout
(
location
=
3
)
in
ivec4
bone_ids
;
layout
(
location
=
4
)
in
vec4
bone_weights
;
layout
(
location
=
0
)
out
Vertex_data
{
vec3
world_pos
;
vec2
tex_coords
;
}
vertex_out
;
layout
(
set
=
2
,
binding
=
0
,
std140
)
uniform
Bone_uniforms
{
mat3x4
offset
[
64
];
}
bones
;
layout
(
push_constant
)
uniform
Per_model_uniforms
{
mat4
model
;
mat4
light_view_proj
;
}
model_uniforms
;
out
gl_PerVertex
{
vec4
gl_Position
;
};
void
main
()
{
float
unused_weight
=
1
.
0
-
dot
(
bone_weights
,
vec4
(
1
.
0
));
vec3
p
=
(
vec4
(
position
,
1
.
0
)
*
bones
.
offset
[
bone_ids
[
0
]])
*
bone_weights
[
0
]
+
(
vec4
(
position
,
1
.
0
)
*
bones
.
offset
[
bone_ids
[
1
]])
*
bone_weights
[
1
]
+
(
vec4
(
position
,
1
.
0
)
*
bones
.
offset
[
bone_ids
[
2
]])
*
bone_weights
[
2
]
+
(
vec4
(
position
,
1
.
0
)
*
bones
.
offset
[
bone_ids
[
3
]])
*
bone_weights
[
3
]
+
position
*
unused_weight
;
vec4
world_pos
=
model_uniforms
.
model
*
vec4
(
p
,
1
.
0
);
vertex_out
.
world_pos
=
world_pos
.
xyz
;
gl_Position
=
model_uniforms
.
light_view_proj
*
world_pos
;
vertex_out
.
tex_coords
=
tex_coords
;
}
assets/core_assets/shader/shadow_model_animated_dqs.vert
0 → 100644
View file @
a194bb8f
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include
"global_uniforms.glsl"
layout
(
location
=
0
)
in
vec3
position
;
layout
(
location
=
1
)
in
vec3
normal
;
layout
(
location
=
2
)
in
vec2
tex_coords
;
layout
(
location
=
3
)
in
ivec4
bone_ids
;
layout
(
location
=
4
)
in
vec4
bone_weights
;
layout
(
location
=
0
)
out
Vertex_data
{
vec3
world_pos
;
vec2
tex_coords
;
}
vertex_out
;
layout
(
set
=
2
,
binding
=
0
,
std140
)
uniform
Bone_uniforms
{
mat3x4
offset
[
64
];
}
bones
;
layout
(
push_constant
)
uniform
Per_model_uniforms
{
mat4
model
;
mat4
light_view_proj
;
}
model_uniforms
;
out
gl_PerVertex
{
vec4
gl_Position
;
};
vec3
transform_position
(
vec3
p
,
mat3x4
dq
)
{
p
*=
dq
[
2
].
xyz
;
return
p
+
2
*
cross
(
dq
[
0
].
xyz
,
cross
(
dq
[
0
].
xyz
,
p
)
+
dq
[
0
].
w
*
p
)
+
2
*
(
dq
[
0
].
w
*
dq
[
1
].
xyz
-
dq
[
1
].
w
*
dq
[
0
].
xyz
+
cross
(
dq
[
0
].
xyz
,
dq
[
1
].
xyz
));
}
void
main
()
{
float
unused_weight
=
1
.
0
-
dot
(
bone_weights
,
vec4
(
1
.
0
));
mat3x4
identity_dqs
=
mat3x4
(
vec4
(
1
,
0
,
0
,
0
),
vec4
(
0
,
0
,
0
,
0
),
vec4
(
1
,
1
,
1
,
1
));
mat3x4
[]
dq
=
mat3x4
[](
bones
.
offset
[
bone_ids
[
0
]],
bones
.
offset
[
bone_ids
[
1
]],
bones
.
offset
[
bone_ids
[
2
]],
bones
.
offset
[
bone_ids
[
3
]]
);
// antipodality handling
for
(
uint
i
=
1
;
i
<=
3
;
i
++
)
{
if
(
dot
(
dq
[
0
][
0
],
dq
[
i
][
0
])
<
0
.
0
)
{
dq
[
i
][
0
]
*=
-
1
.
0
;
dq
[
i
][
1
]
*=
-
1
.
0
;
}
}
mat3x4
bone
=
dq
[
0
]
*
bone_weights
[
0
]
+
dq
[
1
]
*
bone_weights
[
1
]
+
dq
[
2
]
*
bone_weights
[
2
]
+
dq
[
3
]
*
bone_weights
[
3
]
+
identity_dqs
*
unused_weight
;
float
dq_len
=
length
(
bone
[
0
]);
bone
[
0
]
/=
dq_len
;
bone
[
1
]
/=
dq_len
;
vec3
p
=
transform_position
(
position
,
bone
);
vec4
world_pos
=
model_uniforms
.
model
*
vec4
(
p
,
1
.
0
);
vertex_out
.
world_pos
=
world_pos
.
xyz
;
gl_Position
=
model_uniforms
.
light_view_proj
*
world_pos
;
vertex_out
.
tex_coords
=
tex_coords
;
}
assets/demo_assets/blueprints/sun.json
View file @
a194bb8f
...
...
@@ -7,7 +7,8 @@
"temperature"
:
4500
,
"shadow_size"
:
24
,
"near_plane"
:
1.0
,
"far_plane"
:
80
"far_plane"
:
80
,
"update_frequency"
:
1
},
"Shadowcaster"
:
{
},
...
...
src/mirrage/renderer/include/mirrage/renderer/gbuffer.hpp
View file @
a194bb8f
...
...
@@ -27,6 +27,9 @@ namespace mirrage::renderer {
util
::
maybe
<
graphic
::
Texture_2D
&>
ambient_occlusion
;
vk
::
UniqueDescriptorSetLayout
animation_data_layout
;
vk
::
DescriptorSet
animation_data
;
//< might change each frame!
vk
::
UniqueDescriptorSetLayout
shadowmaps_layout
;
graphic
::
DescriptorSet
shadowmaps
;
...
...
src/mirrage/renderer/include/mirrage/renderer/light_comp.hpp
View file @
a194bb8f
...
...
@@ -16,6 +16,7 @@ namespace mirrage::renderer {
using
Component
::
Component
;
void
temperature
(
float
kelvin
);
auto
shadowcaster
(
bool
b
)
noexcept
{
_shadowcaster
=
b
;
}
void
source_radius
(
util
::
Distance
v
)
noexcept
{
_source_radius
=
v
;
}
void
intensity
(
float
v
)
noexcept
{
_intensity
=
v
;
}
void
color
(
util
::
Rgb
v
)
noexcept
{
_color
=
v
;
}
...
...
@@ -24,6 +25,7 @@ namespace mirrage::renderer {
void
shadow_near_plane
(
float
v
)
noexcept
{
_shadow_near_plane
=
v
;
}
void
shadow_far_plane
(
float
v
)
noexcept
{
_shadow_far_plane
=
v
;
}
auto
shadowcaster
()
const
noexcept
{
return
_shadowcaster
;
}
auto
source_radius
()
const
noexcept
{
return
_source_radius
;
}
auto
intensity
()
const
noexcept
{
return
_intensity
;
}
auto
color
()
const
noexcept
{
return
_color
;
}
...
...
@@ -31,14 +33,29 @@ namespace mirrage::renderer {
auto
calc_shadowmap_view_proj
(
ecs
::
components
::
Transform_comp
&
transform
)
const
->
glm
::
mat4
;
auto
needs_update
()
{
return
_shadow_last_update
>=
_shadow_update_frequency
;
}
auto
on_update
()
{
if
(
needs_update
())
{
_shadow_last_update
=
1
;
return
true
;
}
else
{
_shadow_last_update
++
;
return
false
;
}
}
private:
util
::
Distance
_source_radius
;
float
_intensity
;
util
::
Rgb
_color
;
int
_shadowmap_id
=
-
1
;
float
_shadow_size
=
128
;
float
_shadow_near_plane
=
1
;
float
_shadow_far_plane
=
128
;
bool
_shadowcaster
=
true
;
int
_shadowmap_id
=
-
1
;
float
_shadow_size
=
128
;
float
_shadow_near_plane
=
1
;
float
_shadow_far_plane
=
128
;
int
_shadow_update_frequency
=
1
;
int
_shadow_last_update
=
999
;
};
extern
auto
temperature_to_color
(
float
kelvin
)
->
util
::
Rgb
;
...
...
src/mirrage/renderer/include/mirrage/renderer/pass/animation_pass.hpp
View file @
a194bb8f
...
...
@@ -3,6 +3,10 @@
#include
<mirrage/renderer/animation_comp.hpp>
#include
<mirrage/renderer/deferred_renderer.hpp>
#include
<mirrage/graphic/streamed_buffer.hpp>
#include
<tsl/robin_map.h>
#include
<gsl/gsl>
namespace
mirrage
::
renderer
::
detail
{
...
...
@@ -51,10 +55,31 @@ namespace mirrage::renderer {
Deferred_renderer
&
_renderer
;
ecs
::
Entity_manager
&
_ecs
;
// data for animation/pose update
std
::
unordered_set
<
detail
::
Animation_key_cache_key
>
_unused_animation_keys
;
Animation_key_cache
_animation_key_cache
;
// data for pose upload
struct
Animation_upload_queue_entry
{
const
Model
*
model
;
const
Pose_comp
*
pose
;
std
::
int32_t
uniform_offset
;
Animation_upload_queue_entry
(
const
Model
*
model
,
Pose_comp
&
pose
,
std
::
int32_t
uniform_offset
)
:
model
(
model
),
pose
(
&
pose
),
uniform_offset
(
uniform_offset
)
{
}
};
graphic
::
Streamed_buffer
_animation_uniforms
;
std
::
vector
<
graphic
::
DescriptorSet
>
_animation_desc_sets
;
tsl
::
robin_map
<
ecs
::
Entity_handle
,
std
::
uint32_t
>
_animation_uniform_offsets
;
std
::
vector
<
Animation_upload_queue_entry
>
_animation_uniform_queue
;
void
_update_animation
(
ecs
::
Entity_handle
owner
,
Animation_comp
&
anim
,
Pose_comp
&
);
void
_compute_poses
(
Frame_data
&
);
void
_upload_poses
(
Frame_data
&
);
};
class
Animation_pass_factory
:
public
Render_pass_factory
{
...
...
src/mirrage/renderer/include/mirrage/renderer/pass/deferred_geometry_subpass.hpp
View file @
a194bb8f
...
...
@@ -32,28 +32,10 @@ namespace mirrage::renderer {
void
draw
(
Frame_data
&
,
graphic
::
Render_pass
&
);
private:
struct
Animation_upload_queue_entry
{
const
Model
*
model
;
const
Pose_comp
*
pose
;
std
::
int32_t
uniform_offset
;
Animation_upload_queue_entry
(
const
Model
*
model
,
Pose_comp
&
pose
,
std
::
int32_t
uniform_offset
)
:
model
(
model
),
pose
(
&
pose
),
uniform_offset
(
uniform_offset
)
{
}
};
ecs
::
Entity_manager
&
_ecs
;
Deferred_renderer
&
_renderer
;
vk
::
UniqueDescriptorSetLayout
_animation_desc_layout
;
graphic
::
Streamed_buffer
_animation_uniforms
;
std
::
vector
<
graphic
::
DescriptorSet
>
_animation_desc_sets
;
util
::
iter_range
<
std
::
vector
<
Geometry
>::
iterator
>
_geometry_range
;
util
::
iter_range
<
std
::
vector
<
Geometry
>::
iterator
>
_rigged_geometry_range
;
std
::
unordered_map
<
ecs
::
Entity_handle
,
std
::
uint32_t
>
_animation_uniform_offsets
;
std
::
vector
<
Animation_upload_queue_entry
>
_animation_uniform_queue
;
};
}
// namespace mirrage::renderer
src/mirrage/renderer/include/mirrage/renderer/render_pass.hpp
View file @
a194bb8f
...
...
@@ -3,6 +3,7 @@
#include
<mirrage/ecs/entity_handle.hpp>
#include
<mirrage/utils/maybe.hpp>
#include
<mirrage/utils/str_id.hpp>
#include
<mirrage/utils/template_utils.hpp>
#include
<mirrage/utils/units.hpp>
#include
<glm/gtx/quaternion.hpp>
...
...
@@ -10,6 +11,7 @@
#include
<vulkan/vulkan.hpp>
#include
<functional>
#include
<variant>
namespace
mirrage
{
...
...
@@ -18,6 +20,9 @@ namespace mirrage {
namespace
mirrage
::
ecs
{
class
Entity_manager
;
namespace
components
{
class
Transform_comp
;
}
}
// namespace mirrage::ecs
namespace
mirrage
::
graphic
{
...
...
@@ -27,6 +32,7 @@ namespace mirrage::graphic {
namespace
mirrage
::
renderer
{
class
Deferred_renderer
;
class
Model
;
class
Directional_light_comp
;
struct
Camera_state
;
struct
Sub_mesh
;
}
// namespace mirrage::renderer
...
...
@@ -36,14 +42,15 @@ namespace mirrage::renderer {
using
Command_buffer_source
=
std
::
function
<
vk
::
CommandBuffer
()
>
;
struct
Geometry
{
ecs
::
Entity_handle
entity
;
glm
::
vec3
position
{
0
,
0
,
0
};
glm
::
quat
orientation
{
1
,
0
,
0
,
0
};
glm
::
vec3
scale
{
1.
f
,
1.
f
,
1.
f
};
const
Model
*
model
;
util
::
Str_id
substance_id
;
std
::
uint32_t
sub_mesh
;
std
::
uint32_t
culling_mask
;
ecs
::
Entity_handle
entity
;
glm
::
vec3
position
{
0
,
0
,
0
};
glm
::
quat
orientation
{
1
,
0
,
0
,
0
};
glm
::
vec3
scale
{
1.
f
,
1.
f
,
1.
f
};
const
Model
*
model
;
util
::
Str_id
substance_id
;
std
::
uint32_t
sub_mesh
;
std
::
uint32_t
culling_mask
;
util
::
maybe
<
std
::
uint32_t
>
animation_uniform_offset
;
Geometry
()
=
default
;
Geometry
(
ecs
::
Entity_handle
entity
,
...
...
@@ -66,6 +73,26 @@ namespace mirrage::renderer {
}
};
struct
Light
{
using
Transform_comp
=
mirrage
::
ecs
::
components
::
Transform_comp
;
using
Light_comp
=
std
::
variant
<
Directional_light_comp
*>
;
ecs
::
Entity_handle
entity
;
Transform_comp
*
transform
;
Light_comp
light
;
std
::
uint32_t
shadow_culling_mask
;
Light
()
=
default
;
template
<
class
L
>
Light
(
ecs
::
Entity_handle
entity
,
Transform_comp
&
transform
,
L
&
light
,
std
::
uint32_t
shadow_culling_mask
)
:
entity
(
entity
),
transform
(
&
transform
),
light
(
&
light
),
shadow_culling_mask
(
shadow_culling_mask
)
{
}
};
class
Frame_data
{
public:
vk
::
CommandBuffer
main_command_buffer
;
...
...
@@ -73,6 +100,9 @@ namespace mirrage::renderer {
std
::
size_t
swapchain_image
;
std
::
vector
<
Geometry
>
geometry_queue
;
std
::
vector
<
Light
>
light_queue
;
auto
partition_geometry
(
std
::
uint32_t
mask
)
->
util
::
vector_range
<
Geometry
>
;
};
class
Render_pass
{
...
...
src/mirrage/renderer/src/deferred_renderer.cpp
View file @
a194bb8f
...
...
@@ -162,6 +162,7 @@ namespace mirrage::renderer {
_frame_data
.
global_uniform_set
=
*
_global_uniform_descriptor_set
;
_frame_data
.
swapchain_image
=
_factory
->
_aquire_next_image
();
_frame_data
.
geometry_queue
.
clear
();
_frame_data
.
light_queue
.
clear
();
// draw subpasses
for
(
auto
&
pass
:
_passes
)
{
...
...
src/mirrage/renderer/src/light_comp.cpp
View file @
a194bb8f
...
...
@@ -20,7 +20,8 @@ namespace mirrage::renderer {
sf2
::
vmember
(
"temperature"
,
temperature
),
sf2
::
vmember
(
"shadow_size"
,
comp
.
_shadow_size
),
sf2
::
vmember
(
"near_plane"
,
comp
.
_shadow_near_plane
),
sf2
::
vmember
(
"far_plane"
,
comp
.
_shadow_far_plane
));
sf2
::
vmember
(
"far_plane"
,
comp
.
_shadow_far_plane
),
sf2
::
vmember
(
"update_frequency"
,
comp
.
_shadow_update_frequency
));
comp
.
_source_radius
=
src_radius
*
1
_m
;
if
(
temperature
>=
0.
f
)
{
...
...
@@ -35,7 +36,8 @@ namespace mirrage::renderer {
sf2
::
vmember
(
"color"
,
comp
.
_color
),
sf2
::
vmember
(
"shadow_size"
,
comp
.
_shadow_size
),
sf2
::
vmember
(
"near_plane"
,
comp
.
_shadow_near_plane
),
sf2
::
vmember
(
"far_plane"
,
comp
.
_shadow_far_plane
));
sf2
::
vmember
(
"far_plane"
,
comp
.
_shadow_far_plane
),
sf2
::
vmember
(
"update_frequency"
,
comp
.
_shadow_update_frequency
));
}
void
Directional_light_comp
::
temperature
(
float
kelvin
)
{
_color
=
temperature_to_color
(
kelvin
);
}
...
...
src/mirrage/renderer/src/pass/animation_pass.cpp
View file @
a194bb8f
...
...
@@ -12,12 +12,54 @@ using mirrage::ecs::components::Transform_comp;
namespace
mirrage
::
renderer
{
Animation_pass
::
Animation_pass
(
Deferred_renderer
&
renderer
,
ecs
::
Entity_manager
&
entities
)
:
_renderer
(
renderer
),
_ecs
(
entities
)
namespace
{
constexpr
auto
initial_animation_capacity
=
256
*
4
*
4
*
4
;
auto
animation_substance
(
util
::
Str_id
substance_id
,
Skinning_type
st
)
{
switch
(
st
)
{
case
Skinning_type
::
linear_blend_skinning
:
return
substance_id
;
case
Skinning_type
::
dual_quaternion_skinning
:
return
"dq_"
_strid
+
substance_id
;
}
return
substance_id
;
}
}
// namespace
Animation_pass
::
Animation_pass
(
Deferred_renderer
&
r
,
ecs
::
Entity_manager
&
entities
)
:
_renderer
(
r
)
,
_ecs
(
entities
)
,
_animation_uniforms
(
r
.
device
(),
initial_animation_capacity
,
vk
::
BufferUsageFlagBits
::
eUniformBuffer
)
{
_ecs
.
register_component_type
<
Pose_comp
>
();
_ecs
.
register_component_type
<
Animation_comp
>
();
_ecs
.
register_component_type
<
Simple_animation_controller_comp
>
();
MIRRAGE_INVARIANT
(
!
r
.
gbuffer
().
animation_data_layout
,
"More than one animation implementation active!"
);
r
.
gbuffer
().
animation_data_layout
=
r
.
device
().
create_descriptor_set_layout
(
vk
::
DescriptorSetLayoutBinding
{
0
,
vk
::
DescriptorType
::
eUniformBufferDynamic
,
1
,
vk
::
ShaderStageFlagBits
::
eVertex
});
auto
buffers
=
_animation_uniforms
.
buffer_count
();
_animation_desc_sets
=
util
::
build_vector
(
buffers
,
[
&
](
auto
)
{
return
r
.
create_descriptor_set
(
*
r
.
gbuffer
().
animation_data_layout
,
1
);
});
auto
anim_desc_buffer_writes
=
util
::
build_vector
(
buffers
,
[
&
](
auto
i
)
{
return
vk
::
DescriptorBufferInfo
{
_animation_uniforms
.
buffer
(
i
),
0
,
initial_animation_capacity
};
});
auto
anim_desc_writes
=
util
::
build_vector
(
buffers
,
[
&
](
auto
i
)
{
return
vk
::
WriteDescriptorSet
{
*
_animation_desc_sets
.
at
(
i
),
0
,
0
,
1
,
vk
::
DescriptorType
::
eUniformBufferDynamic
,
nullptr
,
&
anim_desc_buffer_writes
[
i
]};
});
r
.
device
().
vk_device
()
->
updateDescriptorSets
(
std
::
uint32_t
(
anim_desc_writes
.
size
()),
anim_desc_writes
.
data
(),
0
,
nullptr
);
}
void
Animation_pass
::
update
(
util
::
Time
time
)
...
...
@@ -81,6 +123,14 @@ namespace mirrage::renderer {
}
void
Animation_pass
::
draw
(
Frame_data
&
frame
)
{
_compute_poses
(
frame
);
// TODO: add Animation_listeners to intercept/replace computed poses before drawing
_upload_poses
(
frame
);
}
void
Animation_pass
::
_compute_poses
(
Frame_data
&
frame
)
{
// mark all cached animations as unused
_unused_animation_keys
.
clear
();
...
...
@@ -111,6 +161,90 @@ namespace mirrage::renderer {
_animation_key_cache
.
erase
(
key
);
}
}
void
Animation_pass
::
_upload_poses
(
Frame_data
&
frame
)
{
// upload skeleton pose
_animation_uniform_offsets
.
clear
();
_animation_uniform_queue
.
clear
();
auto
required_size
=
std
::
int32_t
(
0
);
auto
alignment
=
std
::
int32_t
(
_renderer
.
device
().
physical_device_properties
().
limits
.
minUniformBufferOffsetAlignment
);
auto
aligned_byte_size
=
[
&
](
auto
bone_count
)
{
auto
size
=
bone_count
*
std
::
int32_t
(
sizeof
(
Final_bone_transform
));
return
size
<
alignment
?
alignment
:
size
+
(
alignment
-
size
%
alignment
);
};
for
(
auto
&
geo
:
frame
.
geometry_queue
)
{
if
(
!
geo
.
model
->
rigged
())
break
;
auto
offset
=
gsl
::
narrow
<
std
::
uint32_t
>
(
required_size
);
auto
entity
=
_ecs
.
get
(
geo
.
entity
).
get_or_throw
(
"Invalid entity in render queue"
);
auto
upload_required
=
entity
.
get
<
Shared_pose_comp
>
().
process
(
true
,
[
&
](
auto
&
sp
)
{
auto
pose_offset
=
util
::
find_maybe
(
_animation_uniform_offsets
,
sp
.
pose_owner
);
offset
=
pose_offset
.
get_or
(
offset
);
_animation_uniform_offsets
.
emplace
(
geo
.
entity
,
pose_offset
.
get_or
(
offset
));
entity
=
_ecs
.
get
(
sp
.
pose_owner
).
get_or_throw
(
"Invalid entity in render queue"
);
entity
.
get
<
Pose_comp
>
().
process
([
&
](
auto
&
pose
)
{
geo
.
substance_id
=
animation_substance
(
geo
.
substance_id
,
pose
.
skeleton
().
skinning_type
());
});
if
(
pose_offset
.
is_some
())
return
false
;
return
true
;
});
if
(
upload_required
)
{
entity
.
get
<
Pose_comp
>
().
process
([
&
](
auto
&
pose
)
{
geo
.
substance_id
=
animation_substance
(
geo
.
substance_id
,
pose
.
skeleton
().
skinning_type
());
auto
[
ex
,
success
]
=
_animation_uniform_offsets
.
try_emplace
(
entity
.
handle
(),
offset
);
offset
=
ex
->
second
;
if
(
success
)
{
_animation_uniform_queue
.
emplace_back
(
geo
.
model
,
pose
,
required_size
);
required_size
+=
aligned_byte_size
(
geo
.
model
->
bone_count
());
}
});
}
geo
.
animation_uniform_offset
=
offset
;
}
if
(
_animation_uniforms
.
resize
(
required_size
))
{
// recreate DescriptorSet if the buffer has been recreated
auto
anim_desc_buffer_write
=
vk
::
DescriptorBufferInfo
{
_animation_uniforms
.
write_buffer
(),
0
,
vk
::
DeviceSize
(
required_size
)};
auto
anim_desc_writes
=
vk
::
WriteDescriptorSet
{
*
_animation_desc_sets
.
at
(
std
::
size_t
(
_animation_uniforms
.
write_buffer_index
())),
0
,
0
,
1
,
vk
::
DescriptorType
::
eUniformBufferDynamic
,
nullptr
,
&
anim_desc_buffer_write
};
_renderer
.
device
().
vk_device
()
->
updateDescriptorSets
(
1
,
&
anim_desc_writes
,
0
,
nullptr
);
}
for
(
auto
&
upload
:
_animation_uniform_queue
)
{
_animation_uniforms
.
update_objects
<
Final_bone_transform
>
(
upload
.
uniform_offset
,
[
&
](
auto
out
)
{
auto
geo_matrices
=
out
.
subspan
(
0
,
upload
.
model
->
bone_count
());
upload
.
pose
->
skeleton
().
to_final_transforms
(
upload
.
pose
->
bone_transforms
(),
geo_matrices
);
});
}
_animation_uniforms
.
flush
(
frame
.
main_command_buffer
,
vk
::
PipelineStageFlagBits
::
eVertexShader
,
vk
::
AccessFlagBits
::
eUniformRead
|
vk
::
AccessFlagBits
::
eShaderRead
);
_renderer
.
gbuffer
().
animation_data
=
*
_animation_desc_sets
.
at
(
std
::
size_t
(
_animation_uniforms
.
read_buffer_index
()));
}
void
Animation_pass
::
_update_animation
(
ecs
::
Entity_handle
owner
,
Animation_comp
&
anim_comp
,
...
...
src/mirrage/renderer/src/pass/deferred_geometry_subpass.cpp
View file @
a194bb8f
...
...
@@ -14,41 +14,12 @@ using mirrage::ecs::components::Transform_comp;
namespace
mirrage
::
renderer
{
namespace
{
constexpr
auto
initial_animation_capacity
=
256
*
4
*
4
*
4
;
}
Deferred_geometry_subpass
::
Deferred_geometry_subpass
(
Deferred_renderer
&
r
,
ecs
::
Entity_manager
&
entities
)
:
_ecs
(
entities
)
,
_renderer
(
r
)
,
_animation_desc_layout
(
r
.
device
().
create_descriptor_set_layout
(
vk
::
DescriptorSetLayoutBinding
{
0
,
vk
::
DescriptorType
::
eUniformBufferDynamic
,
1
,
vk
::
ShaderStageFlagBits
::
eVertex
}))
,
_animation_uniforms
(
r
.
device
(),
initial_animation_capacity
,
vk
::
BufferUsageFlagBits
::
eUniformBuffer
)