Commit 54a68c1f authored by Nicholas Milef's avatar Nicholas Milef

ENH: added decals to the Vulkan renderer

parent e8f7de37
......@@ -94,9 +94,10 @@ if(${PROJECT_NAME}_SUPERBUILD)
option(${PROJECT_NAME}_USE_Vulkan "Use the custom Vulkan renderer." OFF)
imstk_define_dependency(glm)
if(${PROJECT_NAME}_USE_Vulkan)
imstk_define_dependency(glfw)
imstk_define_dependency(glm)
imstk_define_dependency(glfw)
imstk_define_dependency(gli)
endif()
......
......@@ -79,6 +79,8 @@ if( iMSTK_USE_Vulkan )
compileShaders(Mesh/mesh_tesc.tesc Mesh/mesh_tesc.spv)
compileShaders(Mesh/mesh_tese.tese Mesh/mesh_tese.spv)
compileShaders(Mesh/mesh_frag.frag Mesh/mesh_frag.spv)
compileShaders(Mesh/decal_vert.vert Mesh/decal_vert.spv)
compileShaders(Mesh/decal_frag.frag Mesh/decal_frag.spv)
# Post processing shaders
compileShaders(PostProcessing/HDR_tonemap_frag.frag PostProcessing/HDR_tonemap_frag.spv)
......
......@@ -6,6 +6,7 @@ imstk_add_library( Geometry
DEPENDS
Core
Datastructures
glm
Assimp
Materials
VegaFEM::volumetricMesh
......
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#include "imstkDecal.h"
namespace imstk
{
Decal::Decal()
: AnalyticalGeometry(Geometry::Type::Decal)
{
m_dimensions = glm::vec3(1);
}
void
Decal::print() const
{
Geometry::print();
LOG(INFO) << "Dimensions: " << m_dimensions.x
<< ", " << m_dimensions.y
<< ", " << m_dimensions.z;
}
double
Decal::getVolume() const
{
return m_dimensions.x * m_dimensions.y * m_dimensions.z;
}
void
Decal::applyScaling(const double s)
{
m_dimensions *= s;
}
void
Decal::updateDecal(glm::mat4& viewMatrix)
{
glm::mat4 transform;
glm::vec3 scale((float)this->getScaling());
transform = glm::scale(transform, scale);
auto rotation = this->getRotation();
glm::mat3 rotationMatrix(rotation(0, 0), rotation(0, 1), rotation(0, 2),
rotation(1, 0), rotation(1, 1), rotation(1, 2),
rotation(2, 0), rotation(2, 1), rotation(2, 2));
transform = glm::mat4(rotationMatrix) * transform;
transform[3][0] = (float)this->getPosition().x();
transform[3][1] = (float)this->getPosition().y();
transform[3][2] = (float)this->getPosition().z();
m_transform = transform;
m_inverse = glm::inverse(m_transform);
}
}
\ No newline at end of file
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#ifndef imstkDecal_h
#define imstkDecal_h
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/quaternion.hpp"
#include "imstkMath.h"
#include "imstkAnalyticalGeometry.h"
namespace imstk
{
class Decal : public AnalyticalGeometry
{
public:
Decal();
~Decal() = default;
///
/// \brief Print the cube info
///
void print() const override;
///
/// \brief Returns the volume of the cube
///
double getVolume() const override;
///
/// \brief Update decal transforms
///
void updateDecal(glm::mat4& viewMatrix);
protected:
friend class VulkanDecalRenderDelegate;
void applyScaling(const double s) override;
glm::vec3 m_dimensions;
glm::mat4 m_transform;
glm::mat4 m_inverse;
};
}
#endif
\ No newline at end of file
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#include "imstkDecalPool.h"
namespace imstk
{
DecalPool::DecalPool(unsigned int maxNumDecals /*= 128*/)
: Geometry(Geometry::Type::DecalPool)
{
if (maxNumDecals <= 256)
{
m_maxNumDecals = maxNumDecals;
}
else
{
m_maxNumDecals = 256;
LOG(WARNING) << "The maximum number of decals is 256";
}
m_vertexPositions[0] = glm::vec3(0.5, 0.5, 0.5);
m_vertexPositions[1] = glm::vec3(0.5, 0.5, -0.5);
m_vertexPositions[2] = glm::vec3(0.5, -0.5, 0.5);
m_vertexPositions[3] = glm::vec3(0.5, -0.5, -0.5);
m_vertexPositions[4] = glm::vec3(-0.5, 0.5, 0.5);
m_vertexPositions[5] = glm::vec3(-0.5, 0.5, -0.5);
m_vertexPositions[6] = glm::vec3(-0.5, -0.5, 0.5);
m_vertexPositions[7] = glm::vec3(-0.5, -0.5, -0.5);
m_triangles[0] = glm::ivec3(2, 1, 0);
m_triangles[1] = glm::ivec3(1, 2, 3);
m_triangles[2] = glm::ivec3(4, 5, 6);
m_triangles[3] = glm::ivec3(7, 6, 5);
m_triangles[4] = glm::ivec3(0, 1, 4);
m_triangles[5] = glm::ivec3(5, 4, 1);
m_triangles[6] = glm::ivec3(6, 3, 2);
m_triangles[7] = glm::ivec3(3, 6, 7);
m_triangles[8] = glm::ivec3(4, 2, 0);
m_triangles[9] = glm::ivec3(2, 4, 6);
m_triangles[10] = glm::ivec3(1, 3, 5);
m_triangles[11] = glm::ivec3(7, 5, 3);
for (unsigned int i = 0; i < maxNumDecals; i++)
{
m_freeDecals.push_back(std::make_shared<Decal>());
}
}
std::shared_ptr<Decal>
DecalPool::addDecal()
{
if (m_numDecals >= m_maxNumDecals && !m_recycle)
{
LOG(WARNING) << "Decal pool exhausted, unable to add more decals";
return nullptr;
}
if (m_recycle && m_numDecals >= m_maxNumDecals)
{
m_freeDecals.push_back(m_orderedDecals.front());
m_orderedDecals.pop_front();
}
auto decal = m_freeDecals.front();
m_orderedDecals.push_back(decal);
m_freeDecals.pop_front();
if (m_numDecals < m_maxNumDecals)
{
m_numDecals++;
}
return decal;
}
void
DecalPool::removeDecal()
{
m_freeDecals.push_back(m_orderedDecals.front());
m_orderedDecals.pop_front();
m_numDecals--;
}
std::deque<std::shared_ptr<Decal>>&
DecalPool::getDecals()
{
return m_orderedDecals;
}
void
DecalPool::setRecycle(bool recycle)
{
m_recycle = recycle;
}
bool
DecalPool::getRecycle()
{
return m_recycle;
}
unsigned int
DecalPool::getNumDecals()
{
return m_numDecals;
}
unsigned int
DecalPool::getMaxNumDecals()
{
return m_maxNumDecals;
}
}
\ No newline at end of file
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#ifndef imstkDecalPool_h
#define imstkDecalPool_h
#include <queue>
#include <array>
#include "imstkDecal.h"
#include "imstkGeometry.h"
#include "imstkRenderMaterial.h"
namespace imstk
{
class DecalPool : public Geometry
{
public:
DecalPool(unsigned int maxNumDecals = 128);
std::shared_ptr<Decal> addDecal();
void removeDecal();
std::deque<std::shared_ptr<Decal>>& getDecals();
void setRecycle(bool recycle);
bool getRecycle();
unsigned int getNumDecals();
unsigned int getMaxNumDecals();
///
/// \brief Returns the volume of the cube
///
double getVolume() const override { return 0; };
protected:
friend class VulkanDecalRenderDelegate;
std::deque<std::shared_ptr<Decal>> m_orderedDecals;
std::deque<std::shared_ptr<Decal>> m_freeDecals;
void applyTranslation(const Vec3d t) override {};
void applyRotation(const Mat3d r) override {};
void applyScaling(const double s) override {};
virtual void updatePostTransformData() override {};
unsigned int m_maxNumDecals;
unsigned int m_numDecals = 0;
bool m_recycle = true;
glm::vec3 m_vertexPositions[8];
glm::ivec3 m_triangles[12];
};
}
#endif
\ No newline at end of file
......@@ -51,7 +51,9 @@ public:
TetrahedralMesh,
HexahedralMesh,
LineMesh,
Capsule
Capsule,
Decal,
DecalPool
};
///
......@@ -170,6 +172,8 @@ public:
protected:
friend class VTKRenderDelegate;
friend class VulkanRenderDelegate;
friend class VulkanSurfaceMeshRenderDelegate;
virtual void applyTranslation(const Vec3d t) = 0;
virtual void applyRotation(const Mat3d r) = 0;
......
......@@ -249,4 +249,11 @@ RenderMaterial::getVisibility() const
{
return m_isVisible;
}
bool
RenderMaterial::isDecal()
{
return m_isDecal;
}
}
......@@ -130,8 +130,12 @@ public:
void setVisibilityOn();
bool getVisibility() const;
bool isDecal();
protected:
friend class VTKRenderDelegate;
friend class VulkanRenderDelegate;
friend class VulkanDecalRenderDelegate;
// State
DisplayMode m_displayMode = DisplayMode::SURFACE;
......@@ -139,6 +143,7 @@ protected:
float m_lineWidth = 1.0;
float m_pointSize = 1.0;
bool m_backfaceCulling = true; ///< For performance, uncommon for this to be false
bool m_isDecal = false;
// Sphere size used for glyph in rendering (valid only for point set)
double m_sphereGlyphSize = 0.05;
......
......@@ -38,6 +38,7 @@ set(VULKAN_H_FILES
VulkanRenderer/imstkVulkanRenderer.h
VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.h
VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.h
VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.h
VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.h
VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.h
......@@ -50,6 +51,8 @@ set(VULKAN_H_FILES
VulkanRenderer/imstkVulkanUniformBuffer.h
VulkanRenderer/imstkVulkanVertexBuffer.h
VulkanRenderer/imstkVulkanFramebuffer.h
VulkanRenderer/imstkVulkanUtilities.h
VulkanRenderer/imstkVulkanRenderPassGenerator.h
VulkanRenderer/PostProcessing/imstkVulkanPostProcess.h
VulkanRenderer/PostProcessing/imstkVulkanPostProcessingChain.h)
......@@ -57,6 +60,7 @@ set(VULKAN_CPP_FILES
VulkanRenderer/imstkVulkanRenderer.cpp
VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.cpp
VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.cpp
VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.cpp
VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.cpp
VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.cpp
......@@ -67,6 +71,7 @@ set(VULKAN_CPP_FILES
VulkanRenderer/imstkVulkanUniformBuffer.cpp
VulkanRenderer/imstkVulkanVertexBuffer.cpp
VulkanRenderer/imstkVulkanFramebuffer.cpp
VulkanRenderer/imstkVulkanRenderPassGenerator.cpp
VulkanRenderer/PostProcessing/imstkVulkanPostProcess.cpp
VulkanRenderer/PostProcessing/imstkVulkanPostProcessingChain.cpp)
......
......@@ -114,7 +114,7 @@ VulkanPostProcessingChain::VulkanPostProcessingChain(VulkanRenderer * renderer)
auto bloomVerticalBlurPass = std::make_shared<VulkanPostProcess>(renderer, level);
bloomVerticalBlurPass->addInputImage(&renderer->m_HDRImageSampler, &renderer->m_HDRImageView[m_lastOutput][level]);
bloomVerticalBlurPass->m_framebuffer->setColor(&renderer->m_HDRImageView[m_lastInput][level], VK_FORMAT_R16G16B16A16_SFLOAT);
bloomVerticalBlurPass->initialize(renderer, "./Shaders/Vulkan/PostProcessing/blur_vertical_frag.spv");
bloomVerticalBlurPass->initialize(renderer, "./Shaders/VulkanShaders/PostProcessing/blur_vertical_frag.spv");
bloomVerticalBlurPass->m_pushConstantData[0] = std::max(renderer->m_width >> level, 1u);
bloomVerticalBlurPass->m_pushConstantData[1] = std::max(renderer->m_height >> level, 1u);
bloomVerticalBlurPass->m_pushConstantData[2] = bloomSamples;
......
......@@ -84,7 +84,12 @@ VulkanCapsuleRenderDelegate::VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule
m_numTriangles = (uint32_t)m_capsuleTriangles.size();
m_vertexSize = sizeof(VulkanBasicVertex);
this->initializeData(memoryManager);
if (!m_geometry->getRenderMaterial())
{
m_geometry->setRenderMaterial(std::make_shared<RenderMaterial>());
}
this->initializeData(memoryManager, m_geometry->getRenderMaterial());
m_vertexBuffer->updateVertexBuffer(&m_capsuleVertices, &m_capsuleTriangles);
......@@ -94,9 +99,7 @@ VulkanCapsuleRenderDelegate::VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule
void
VulkanCapsuleRenderDelegate::update()
{
this->updateTransform(m_geometry);
m_vertexUniformBuffer->updateUniforms(sizeof(VulkanLocalVertexUniforms),
(void *)&m_localVertexUniforms);
this->updateUniforms(m_geometry);
}
std::shared_ptr<Geometry>
......
......@@ -84,7 +84,12 @@ VulkanCubeRenderDelegate::VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube, V
m_numTriangles = (uint32_t)m_cubeTriangles.size();
m_vertexSize = sizeof(VulkanBasicVertex);
this->initializeData(memoryManager);
if (!m_geometry->getRenderMaterial())
{
m_geometry->setRenderMaterial(std::make_shared<RenderMaterial>());
}
this->initializeData(memoryManager, m_geometry->getRenderMaterial());
m_vertexBuffer->updateVertexBuffer(&m_cubeVertices, &m_cubeTriangles);
......@@ -94,9 +99,7 @@ VulkanCubeRenderDelegate::VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube, V
void
VulkanCubeRenderDelegate::update()
{
this->updateTransform(m_geometry);
m_vertexUniformBuffer->updateUniforms(sizeof(VulkanLocalVertexUniforms),
(void *)&m_localVertexUniforms);
this->updateUniforms(m_geometry);
}
std::shared_ptr<Geometry>
......
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#include "imstkVulkanDecalRenderDelegate.h"
namespace imstk
{
VulkanDecalRenderDelegate::VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool, VulkanMemoryManager& memoryManager)
: m_geometry(decalPool)
{
m_numVertices = 8;
m_numTriangles = 12;
m_vertexSize = sizeof(VulkanBasicVertex);
if (!m_geometry->getRenderMaterial())
{
auto material = std::make_shared<RenderMaterial>();
m_geometry->setRenderMaterial(material);
}
m_geometry->getRenderMaterial()->m_isDecal = true;
this->initializeData(memoryManager, m_geometry->getRenderMaterial());
this->updateVertexBuffer();
}
void
VulkanDecalRenderDelegate::updateVertexBuffer()
{
auto vertices = (VulkanBasicVertex *)m_vertexBuffer->mapVertices();
for (unsigned i = 0; i < m_numVertices; i++)
{
vertices[i].position =
m_geometry->m_vertexPositions[i];
}
m_vertexBuffer->unmapVertices();
auto triangles = (std::array<uint32_t, 3> *)m_vertexBuffer->mapTriangles();
for (unsigned i = 0; i < m_numTriangles; i++)
{
triangles[i][0] = (uint32_t)m_geometry->m_triangles[i].x;
triangles[i][1] = (uint32_t)m_geometry->m_triangles[i].y;
triangles[i][2] = (uint32_t)m_geometry->m_triangles[i].z;
}
m_vertexBuffer->unmapTriangles();
}
void
VulkanDecalRenderDelegate::initializeData(VulkanMemoryManager& memoryManager, std::shared_ptr<RenderMaterial> material)
{
m_vertexUniformBuffer = std::make_shared<VulkanUniformBuffer>(memoryManager, (uint32_t)sizeof(VulkanLocalDecalVertexUniforms));
m_fragmentUniformBuffer = std::make_shared<VulkanUniformBuffer>(memoryManager, (uint32_t)sizeof(VulkanLocalDecalFragmentUniforms));
m_material = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
m_fragmentUniformBuffer,
material,
memoryManager);
m_vertexBuffer = std::make_shared<VulkanVertexBuffer>(memoryManager, m_numVertices, m_vertexSize, m_numTriangles);
}
void
VulkanDecalRenderDelegate::update(std::shared_ptr<Camera> camera)
{
unsigned int index = 0;
auto eye = glm::tvec3<float>(camera->getPosition().x(), camera->getPosition().y(), camera->getPosition().z());
auto center = glm::tvec3<float>(camera->getFocalPoint().x(), camera->getFocalPoint().y(), camera->getFocalPoint().z());
auto up = glm::tvec3<float>(camera->getViewUp().x(), camera->getViewUp().y(), camera->getViewUp().z());
auto viewMatrix = glm::lookAt(eye, center, up);
for (auto decal : m_geometry->getDecals())
{
decal->updateDecal(viewMatrix);
m_decalVertexUniforms.transform[index] = decal->m_transform;
m_decalFragmentUniforms.inverse[index] = decal->m_inverse;
index++;
}
m_vertexUniformBuffer->updateUniforms(sizeof(glm::mat4) * m_geometry->getMaxNumDecals(),
(void *)&m_decalVertexUniforms);
m_fragmentUniformBuffer->updateUniforms(sizeof(glm::mat4) * m_geometry->getMaxNumDecals(),
(void *)&m_decalFragmentUniforms);
}
std::shared_ptr<Geometry>
VulkanDecalRenderDelegate::getGeometry() const
{
return m_geometry;
}
}
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#ifndef imstkVulkanDecalRenderDelegate_h
#define imstkVulkanDecalRenderDelegate_h
#include "imstkDecalPool.h"
#include "imstkCamera.h"
#include "imstkVulkanRenderDelegate.h"
namespace imstk
{
class VulkanDecalRenderDelegate : public VulkanRenderDelegate {
public:
///
/// \brief Default destructor
///
~VulkanDecalRenderDelegate() = default;
///
/// \brief Default constructor
///
VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool, VulkanMemoryManager& memoryManager);
///
/// \brief Update render geometry
///
void update(std::shared_ptr<Camera> camera);
///