Skip to content

Commit

Permalink
Implemented self-shadowing demo
Browse files Browse the repository at this point in the history
  • Loading branch information
vcoda committed Jul 28, 2020
1 parent e7e937d commit c861e61
Show file tree
Hide file tree
Showing 15 changed files with 565 additions and 16 deletions.
15 changes: 15 additions & 0 deletions aggregated-graphics-samples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "displacement-mapping", "dis
{67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "self-shadowing", "self-shadowing\self-shadowing.vcxproj", "{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}"
ProjectSection(ProjectDependencies) = postProject
{8D9D4A3E-439A-4210-8879-259B20D992CA} = {8D9D4A3E-439A-4210-8879-259B20D992CA}
{51CC36B3-921E-4853-ACD5-CB6CBC27FBA1} = {51CC36B3-921E-4853-ACD5-CB6CBC27FBA1}
{67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand Down Expand Up @@ -183,6 +190,14 @@ Global
{6642AD41-5A38-45DC-9646-A265B73E0858}.Release|x64.Build.0 = Release|x64
{6642AD41-5A38-45DC-9646-A265B73E0858}.Release|x86.ActiveCfg = Release|Win32
{6642AD41-5A38-45DC-9646-A265B73E0858}.Release|x86.Build.0 = Release|Win32
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Debug|x64.ActiveCfg = Debug|x64
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Debug|x64.Build.0 = Debug|x64
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Debug|x86.ActiveCfg = Debug|Win32
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Debug|x86.Build.0 = Debug|Win32
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Release|x64.ActiveCfg = Release|x64
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Release|x64.Build.0 = Release|x64
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Release|x86.ActiveCfg = Release|Win32
{1C2F65F9-6268-4271-A0F7-EE3E6DBF8F9E}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
7 changes: 5 additions & 2 deletions framework/graphicsApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,11 @@ void GraphicsApp::updateObjectTransforms(const std::vector<rapid::matrix, core::

void GraphicsApp::updateLightSource()
{
lightViewProj->updateView();
lightViewProj->updateProjection();
if (lightViewProj)
{
lightViewProj->updateView();
lightViewProj->updateProjection();
}
magma::helpers::mapScoped<LightSource>(lightSource,
[this](auto *light)
{
Expand Down
25 changes: 13 additions & 12 deletions framework/textureLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
#include "magma/magma.h"
#include "gliml/gliml.h"

static VkFormat blockCompressedFormat(const gliml::context& ctx)
static VkFormat blockCompressedFormat(const gliml::context& ctx, bool sRGB)
{
const int internalFormat = ctx.image_internal_format();
switch (internalFormat)
{
case GLIML_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
return sRGB ? VK_FORMAT_BC1_RGBA_SRGB_BLOCK : VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case GLIML_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
return VK_FORMAT_BC2_UNORM_BLOCK;
return sRGB ? VK_FORMAT_BC2_SRGB_BLOCK : VK_FORMAT_BC2_UNORM_BLOCK;
case GLIML_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return VK_FORMAT_BC3_UNORM_BLOCK;
return sRGB ? VK_FORMAT_BC3_SRGB_BLOCK : VK_FORMAT_BC3_UNORM_BLOCK;
default:
throw std::invalid_argument("unknown block compressed format");
return VK_FORMAT_UNDEFINED;
Expand All @@ -23,12 +23,12 @@ static VkFormat blockCompressedExtFormat(unsigned int fourCC)
{
switch (fourCC)
{
// ATI2
// ATI1
case MAKEFOURCC('B', 'C', '4', 'U'):
return VK_FORMAT_BC4_UNORM_BLOCK;
case MAKEFOURCC('B', 'C', '4', 'S'):
return VK_FORMAT_BC4_SNORM_BLOCK;
// ATI1
// ATI2
case MAKEFOURCC('B', 'C', '5', 'U'):
return VK_FORMAT_BC5_UNORM_BLOCK;
case MAKEFOURCC('B', 'C', '5', 'S'):
Expand Down Expand Up @@ -92,7 +92,8 @@ static VkFormat loadDxtTextureExt(const gliml::dds_header *hdr, VkExtent2D& exte
return format;
}

std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandBuffer> cmdCopy, const std::string& filename)
std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandBuffer> cmdCopy, const std::string& filename,
bool sRGB /* false */)
{
std::ifstream file("../assets/textures/" + filename, std::ios::in | std::ios::binary | std::ios::ate);
if (!file.is_open())
Expand All @@ -112,7 +113,7 @@ std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandB
ctx.enable_dxt(true);
if (ctx.load(data, static_cast<unsigned>(size)))
{ // Setup texture data description
format = blockCompressedFormat(ctx);
format = blockCompressedFormat(ctx, sRGB);
extent.width = static_cast<uint32_t>(ctx.image_width(0, 0));
extent.height = static_cast<uint32_t>(ctx.image_height(0, 0));
for (int level = 1; level < ctx.num_mipmaps(0); ++level)
Expand All @@ -128,10 +129,10 @@ std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandB
const gliml::dds_header *hdr = (const gliml::dds_header *)data;
switch (hdr->ddspf.dwFourCC)
{
case MAKEFOURCC('B', 'C', '4', 'U'): // ATI2
case MAKEFOURCC('B', 'C', '4', 'S'): // ATI2
case MAKEFOURCC('B', 'C', '5', 'U'): // ATI1
case MAKEFOURCC('B', 'C', '5', 'S'): // ATI1
case MAKEFOURCC('B', 'C', '4', 'U'): // ATI1
case MAKEFOURCC('B', 'C', '4', 'S'): // ATI1
case MAKEFOURCC('B', 'C', '5', 'U'): // ATI2
case MAKEFOURCC('B', 'C', '5', 'S'): // ATI2
format = loadDxtTextureExt(hdr, extent, mipOffsets, baseMipOffset);
break;
default:
Expand Down
3 changes: 2 additions & 1 deletion framework/textureLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ namespace magma
class CommandBuffer;
}

std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandBuffer> device, const std::string& filename);
std::shared_ptr<magma::ImageView> loadDxtTexture(std::shared_ptr<magma::CommandBuffer> device, const std::string& filename,
bool sRGB = false);
Binary file added screenshots/self-shadowing.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
201 changes: 201 additions & 0 deletions self-shadowing/self-shadowing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#include "graphicsApp.h"
#include "colorTable.h"
#include "textureLoader.h"
#include "quadric/include/cube.h"
#include "quadric/include/sphere.h"

class SelfShadowing : public GraphicsApp
{
struct Constants
{
VkBool32 selfShadowing;
};

std::unique_ptr<quadric::Cube> box;
std::unique_ptr<quadric::Sphere> sphere;
std::shared_ptr<magma::ImageView> diffuseMap;
std::shared_ptr<magma::ImageView> normalMap;
std::shared_ptr<magma::ImageView> specularMap;
std::shared_ptr<magma::GraphicsPipeline> phongPipeline;
std::shared_ptr<magma::GraphicsPipeline> spherePipeline;
DescriptorSet phongDescriptor;
DescriptorSet fillDescriptor;

Constants constants = {false};

public:
explicit SelfShadowing(const AppEntry& entry):
GraphicsApp(entry, TEXT("Self-shadowing"), 1280, 720, true)
{
setupViewProjection();
createTransformBuffer(2);
createMeshObjects();
loadTexture();
setupDescriptorSets();
setupGraphicsPipelines();

renderScene(drawCmdBuffer);
blit(msaaFramebuffer->getColorView(), FrontBuffer);
blit(msaaFramebuffer->getColorView(), BackBuffer);
}

virtual void render(uint32_t bufferIndex) override
{
updateTransforms();
submitCommandBuffers(bufferIndex);
std::this_thread::sleep_for(std::chrono::milliseconds(2)); // Cap fps
}

virtual void onKeyDown(char key, int repeat, uint32_t flags) override
{
switch (key)
{
case AppKey::Space:
constants.selfShadowing = !constants.selfShadowing;
setupGraphicsPipelines();
renderScene(drawCmdBuffer);
break;
}
updateTransforms();
updateLightSource();
VulkanApp::onKeyDown(key, repeat, flags);
}

virtual void onMouseWheel(float distance) override
{
float step = distance * 0.2f;
float z = viewProj->getPosition().z;
if ((z + step < -3.3f) && (z + step > -15.f))
viewProj->translate(0.f, 0.f, step);
updateViewProjTransforms();
}

virtual void updateLightSource()
{
magma::helpers::mapScoped<LightSource>(lightSource,
[this](auto *light)
{
constexpr float ambientFactor = 0.2f;
light->viewPosition = viewProj->getView() * lightViewProj->getPosition();
light->ambient = ivory * ambientFactor;
light->diffuse = ivory;
light->specular = old_lace;
});
}

void setupViewProjection()
{
viewProj = std::make_unique<LeftHandedViewProjection>();
viewProj->setPosition(0.f, 0.f, -5.f);
viewProj->setFocus(0.f, 0.f, 0.f);
viewProj->setFieldOfView(45.f);
viewProj->setNearZ(1.f);
viewProj->setFarZ(100.f);
viewProj->setAspectRatio(width / (float)height);
viewProj->updateView();
viewProj->updateProjection();

lightViewProj = std::make_unique<LeftHandedViewProjection>();
lightViewProj->setPosition(-1.f, 1.f, -2.f);

updateViewProjTransforms();
}

void updateTransforms()
{
rapid::matrix lightTransform = rapid::translation(rapid::vector3(lightViewProj->getPosition()));
const std::vector<rapid::matrix, core::aligned_allocator<rapid::matrix>> transforms = {
arcball->transform(),
lightTransform
};
updateObjectTransforms(transforms);
}

void createMeshObjects()
{
box = std::make_unique<quadric::Cube>(cmdCopyBuf);
sphere = std::make_unique<quadric::Sphere>(0.02f, 8, 8, true, cmdCopyBuf);
}

void loadTexture()
{ // https://freepbr.com/materials/storage-container2/
diffuseMap = loadDxtTexture(cmdCopyImg, "storage-container2/storage-container2-albedo.dds", true);
normalMap = loadDxtTexture(cmdCopyImg, "storage-container2/storage-container2-normal-dx.dds");
specularMap = loadDxtTexture(cmdCopyImg, "storage-container2/storage-container2-roughness.dds");
}

void setupDescriptorSets()
{
using namespace magma::bindings;
using namespace magma::descriptors;
// Bump shader
phongDescriptor.layout = std::shared_ptr<magma::DescriptorSetLayout>(new magma::DescriptorSetLayout(device,
{
VertexFragmentStageBinding(0, DynamicUniformBuffer(1)),
FragmentStageBinding(1, UniformBuffer(1)),
FragmentStageBinding(2, UniformBuffer(1)),
FragmentStageBinding(3, CombinedImageSampler(1)),
FragmentStageBinding(4, CombinedImageSampler(1)),
FragmentStageBinding(5, CombinedImageSampler(1))
}));
phongDescriptor.set = descriptorPool->allocateDescriptorSet(phongDescriptor.layout);
phongDescriptor.set->update(0, transforms);
phongDescriptor.set->update(1, viewProjTransforms);
phongDescriptor.set->update(2, lightSource);
phongDescriptor.set->update(3, diffuseMap, anisotropicClampToEdge);
phongDescriptor.set->update(4, normalMap, anisotropicClampToEdge);
phongDescriptor.set->update(5, specularMap, anisotropicClampToEdge);
// Fill shader
fillDescriptor.layout = std::shared_ptr<magma::DescriptorSetLayout>(new magma::DescriptorSetLayout(device,
{
VertexStageBinding(0, DynamicUniformBuffer(1))
}));
fillDescriptor.set = descriptorPool->allocateDescriptorSet(fillDescriptor.layout);
fillDescriptor.set->update(0, transforms);
}

void setupGraphicsPipelines()
{
auto specialization(std::make_shared<magma::Specialization>(constants,
magma::SpecializationEntry(0, &Constants::selfShadowing)));
phongPipeline = createCommonSpecializedPipeline(
"transform.o", "phong.o",
std::move(specialization),
box->getVertexInput(),
phongDescriptor.layout);
if (!spherePipeline)
{
spherePipeline = createCommonPipeline(
"transform.o", "fill.o",
sphere->getVertexInput(),
fillDescriptor.layout);
}
}

void renderScene(std::shared_ptr<magma::CommandBuffer> cmdBuffer)
{
cmdBuffer->begin();
{
cmdBuffer->beginRenderPass(msaaFramebuffer->getRenderPass(), msaaFramebuffer->getFramebuffer(),
{
magma::ClearColor(0.1f, 0.243f, 0.448f, 1.f),
magma::clears::depthOne
});
{
cmdBuffer->bindPipeline(phongPipeline);
cmdBuffer->bindDescriptorSet(phongPipeline, phongDescriptor.set, transforms->getDynamicOffset(0));
box->draw(cmdBuffer);
cmdBuffer->bindPipeline(spherePipeline);
cmdBuffer->bindDescriptorSet(spherePipeline, fillDescriptor.set, transforms->getDynamicOffset(1));
sphere->draw(cmdBuffer);
}
cmdBuffer->endRenderPass();
}
cmdBuffer->end();
}
};

std::unique_ptr<IApplication> appFactory(const AppEntry& entry)
{
return std::unique_ptr<SelfShadowing>(new SelfShadowing(entry));
}
Loading

0 comments on commit c861e61

Please sign in to comment.