Fix skinning bugs
- We were not setting the bones ubo staging buffer size correctly - The bones UBO was never bound to the shader - The default values for the bones ubo wasn’t identity
This commit is contained in:
@@ -54,8 +54,9 @@ public:
|
||||
Instance getInstance(utils::Entity e) const noexcept;
|
||||
|
||||
struct Bone {
|
||||
math::quatf unitQuaternion;
|
||||
math::float3 translation = {};
|
||||
math::quatf unitQuaternion = { 1, 0, 0, 0 };
|
||||
math::float3 translation = { 0, 0, 0 };
|
||||
float reserved = 0;
|
||||
};
|
||||
|
||||
class Builder : public BuilderBase<BuilderDetails> {
|
||||
|
||||
@@ -305,6 +305,10 @@ Handle<HwProgram> FMaterial::getProgramSlow(uint8_t variantKey) const noexcept {
|
||||
.addSamplerBlock(BindingPoints::PER_VIEW, &SibGenerator::getPerViewSib())
|
||||
.addSamplerBlock(BindingPoints::PER_MATERIAL_INSTANCE, &mSamplerInterfaceBlock);
|
||||
|
||||
if (Variant(variantKey).hasSkinning()) {
|
||||
pb.addUniformBlock(BindingPoints::PER_RENDERABLE_BONES, &UibGenerator::getPerRenderableBonesUib());
|
||||
}
|
||||
|
||||
auto program = mEngine.getDriverApi().createProgram(std::move(pb));
|
||||
assert(program);
|
||||
|
||||
|
||||
@@ -132,6 +132,9 @@ void RenderPass::recordDriverCommands(
|
||||
// per-renderable uniform
|
||||
PrimitiveInfo const& UTILS_RESTRICT info = c->primitive;
|
||||
driver.bindUniforms(BindingPoints::PER_RENDERABLE, info.perRenderableUniforms);
|
||||
if (info.perRenderableBones) {
|
||||
driver.bindUniforms(BindingPoints::PER_RENDERABLE_BONES, info.perRenderableBones);
|
||||
}
|
||||
|
||||
FMaterialInstance const* const UTILS_RESTRICT mi = info.mi;
|
||||
if (UTILS_UNLIKELY(mi != previousMi)) {
|
||||
@@ -271,6 +274,7 @@ void RenderPass::generateCommandsImpl(uint32_t,
|
||||
auto const* const UTILS_RESTRICT soaVisibility = soa.data<FScene::VISIBILITY_STATE>();
|
||||
auto const* const UTILS_RESTRICT soaPrimitives = soa.data<FScene::PRIMITIVES>();
|
||||
auto const* const UTILS_RESTRICT soaUbh = soa.data<FScene::UBH>();
|
||||
auto const* const UTILS_RESTRICT soaBonesUbh = soa.data<FScene::BONES_UBH>();
|
||||
|
||||
const bool hasShadowing = view->hasShadowing();
|
||||
Variant materialVariant;
|
||||
@@ -321,6 +325,7 @@ void RenderPass::generateCommandsImpl(uint32_t,
|
||||
|
||||
cmdColor.key = makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
|
||||
cmdColor.primitive.perRenderableUniforms = soaUbh[i];
|
||||
cmdColor.primitive.perRenderableBones = soaBonesUbh[i];
|
||||
materialVariant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing);
|
||||
materialVariant.setSkinning(soaVisibility[i].skinning);
|
||||
|
||||
@@ -330,6 +335,7 @@ void RenderPass::generateCommandsImpl(uint32_t,
|
||||
cmdDepth.key |= makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
|
||||
cmdDepth.key |= makeField(distanceBits, DISTANCE_BITS_MASK, DISTANCE_BITS_SHIFT);
|
||||
cmdDepth.primitive.perRenderableUniforms = soaUbh[i];
|
||||
cmdDepth.primitive.perRenderableBones = soaBonesUbh[i];
|
||||
cmdDepth.primitive.materialVariant.setSkinning(soaVisibility[i].skinning);
|
||||
|
||||
const bool shadowCaster = soaVisibility[i].castShadows & hasShadowing;
|
||||
|
||||
@@ -171,10 +171,11 @@ public:
|
||||
return boolish ? -1llu : 0llu;
|
||||
}
|
||||
|
||||
struct PrimitiveInfo { // 24 bytes (20)
|
||||
struct PrimitiveInfo { // 28 bytes
|
||||
FMaterialInstance const* mi = nullptr; // 8 bytes (4)
|
||||
Handle<HwRenderPrimitive> primitiveHandle; // 4 bytes
|
||||
Handle<HwUniformBuffer> perRenderableUniforms; // 4 bytes
|
||||
Handle<HwUniformBuffer> perRenderableBones; // 4 bytes
|
||||
Driver::RasterState rasterState; // 4 bytes
|
||||
Variant materialVariant; // 1 byte
|
||||
uint8_t reserved[3] = { }; // 3 bytes (that helps the compiler)
|
||||
|
||||
@@ -120,6 +120,7 @@ void FScene::prepare(FEngine& engine, mat4f const& worldOriginTansform) {
|
||||
worldTransform,
|
||||
rcm.getVisibility(ri),
|
||||
rcm.getUbh(ri),
|
||||
rcm.getBonesUbh(ri),
|
||||
worldAABB.center,
|
||||
0,
|
||||
rcm.getLayerMask(ri),
|
||||
|
||||
@@ -288,8 +288,8 @@ void FRenderableManager::create(const RenderableManager::Builder& UTILS_RESTRICT
|
||||
std::unique_ptr<Bones>& bones = manager[ci].bones;
|
||||
|
||||
bones.reset(new Bones); // FIXME: maybe use a pool allocator
|
||||
bones->bones = UniformBuffer(CONFIG_MAX_BONE_COUNT * 2);
|
||||
bones->handle = driver.createUniformBuffer(CONFIG_MAX_BONE_COUNT * 2);
|
||||
bones->bones = UniformBuffer(CONFIG_MAX_BONE_COUNT * sizeof(Bone));
|
||||
bones->handle = driver.createUniformBuffer(CONFIG_MAX_BONE_COUNT * sizeof(Bone));
|
||||
}
|
||||
}
|
||||
if (builder->mSkinningBoneCount) {
|
||||
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
inline UniformBuffer& getUniformBuffer(Instance instance) noexcept;
|
||||
|
||||
inline Handle<HwUniformBuffer> getUbh(Instance instance) const noexcept;
|
||||
inline Handle<HwUniformBuffer> getBonesUbh(Instance instance) const noexcept;
|
||||
|
||||
|
||||
inline size_t getLevelCount(Instance instance) const noexcept { return 1; }
|
||||
@@ -310,6 +311,11 @@ Handle<HwUniformBuffer> FRenderableManager::getUbh(Instance instance) const noex
|
||||
return mManager[instance].uniformsHandle;
|
||||
}
|
||||
|
||||
Handle<HwUniformBuffer> FRenderableManager::getBonesUbh(Instance instance) const noexcept {
|
||||
std::unique_ptr<Bones> const& bones = mManager[instance].bones;
|
||||
return bones ? bones->handle : Handle<HwUniformBuffer>{};
|
||||
}
|
||||
|
||||
utils::Slice<FRenderPrimitive> const& FRenderableManager::getRenderPrimitives(
|
||||
Instance instance, uint8_t level) const noexcept {
|
||||
return mManager[instance].primitives;
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
WORLD_TRANSFORM, // 16 instance of the Transform component
|
||||
VISIBILITY_STATE, // 1 visibility data of the component
|
||||
UBH, // 4 uniform buffer handle
|
||||
BONES_UBH, // 4 bones uniform buffer handle
|
||||
WORLD_AABB_CENTER, // 12 world-space bounding box center of the renderable
|
||||
VISIBLE_MASK, // 1 each bit represents a visibility in a pass
|
||||
|
||||
@@ -109,6 +110,7 @@ public:
|
||||
math::mat4f,
|
||||
FRenderableManager::Visibility,
|
||||
Handle<HwUniformBuffer>,
|
||||
Handle<HwUniformBuffer>,
|
||||
math::float3,
|
||||
Culler::result_type,
|
||||
uint8_t,
|
||||
|
||||
Reference in New Issue
Block a user