Skip to content

Commit

Permalink
Implemented basic BRDF demo
Browse files Browse the repository at this point in the history
  • Loading branch information
vcoda committed Aug 24, 2020
1 parent 772b3b6 commit dd96d25
Show file tree
Hide file tree
Showing 22 changed files with 882 additions and 1 deletion.
15 changes: 15 additions & 0 deletions aggregated-graphics-samples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cook-torrance", "cook-torra
{67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "brdf", "brdf\brdf.vcxproj", "{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}"
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 @@ -241,6 +248,14 @@ Global
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x64.Build.0 = Release|x64
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x86.ActiveCfg = Release|Win32
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x86.Build.0 = Release|Win32
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x64.ActiveCfg = Debug|x64
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x64.Build.0 = Debug|x64
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x86.ActiveCfg = Debug|Win32
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x86.Build.0 = Debug|Win32
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x64.ActiveCfg = Release|x64
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x64.Build.0 = Release|x64
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x86.ActiveCfg = Release|Win32
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Binary file added assets/textures/aniso2.dds
Binary file not shown.
267 changes: 267 additions & 0 deletions brdf/brdf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
#include "graphicsApp.h"
#include "colorTable.h"
#include "textureLoader.h"
#include "quadric/include/teapot.h"

class BasicBrdf : public GraphicsApp
{
struct Constants
{
VkBool32 gammaCorrection = true;
};

enum Brdf : uint32_t
{
Lambert = 0, PhongMetallic, PhongPlastic,
OrenNayar, BlinnPhongMetallic, BlinnPhongPlastic,
Minnaert, Aniso, Ward,
Max
};

std::unique_ptr<quadric::Teapot> teapot;
std::shared_ptr<magma::DynamicUniformBuffer<PhongMaterial>> materials;
std::shared_ptr<magma::ImageView> aniso;
std::shared_ptr<magma::GraphicsPipeline> lambertPipeline;
std::shared_ptr<magma::GraphicsPipeline> phongPipeline;
std::shared_ptr<magma::GraphicsPipeline> blinnPhongPipeline;
std::shared_ptr<magma::GraphicsPipeline> orenNayarPipeline;
std::shared_ptr<magma::GraphicsPipeline> minnaertPipeline;
std::shared_ptr<magma::GraphicsPipeline> anisoPipeline;
std::shared_ptr<magma::GraphicsPipeline> wardPipeline;
DescriptorSet descriptor;

Constants constants;

public:
explicit BasicBrdf(const AppEntry& entry):
GraphicsApp(entry, TEXT("Basic BRDFs"), 1280, 720, true)
{
createTransformBuffer(9);
setupViewProjection();
setupMaterials();
createMesh();
loadAnisoTexture();
setupDescriptorSets();
setupGraphicsPipelines();

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

virtual void render(uint32_t bufferIndex) override
{
updateTransforms();
submitCommandBuffers(bufferIndex);
sleep(2); // Cap fps
}

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

virtual void updateLightSource() override
{
magma::helpers::mapScoped<LightSource>(lightSource,
[this](auto *light)
{ // Directional light
constexpr float ambientFactor = 0.4f;
const rapid::matrix normalMatrix = rapid::transpose(rapid::inverse(viewProj->getView()));
const rapid::vector3 lightViewDir = normalMatrix * lightViewProj->getPosition();
light->viewPosition = lightViewDir.normalized();
light->ambient = white * ambientFactor;
light->diffuse = white;
light->specular = white;
});
}

void updateTransforms()
{
constexpr float dx = 8.f, dy = 5.f;
static const rapid::matrix offset = rapid::translation(0.f, -1.5f, 0.f);
static const rapid::matrix grid3x3[Brdf::Max] = {
rapid::translation(-dx, dy),
rapid::translation(0.f, dy),
rapid::translation( dx, dy),
rapid::translation(-dx, 0.f),
rapid::translation(0.f, 0.f),
rapid::translation( dx, 0.f),
rapid::translation(-dx, -dy),
rapid::translation(0.f, -dy),
rapid::translation( dx, -dy)
};
const rapid::matrix rotation = arcball->transform();
std::vector<rapid::matrix, core::aligned_allocator<rapid::matrix>> transforms(Brdf::Max);
for (uint32_t i = 0; i < Brdf::Max; ++i)
transforms[i] = offset * rotation * grid3x3[i];
updateObjectTransforms(transforms);
}

void setupViewProjection()
{
viewProj = std::make_unique<LeftHandedViewProjection>();
viewProj->setPosition(0.f, 0.f, -100.0f);
viewProj->setFocus(0.f, 0.f, 0.f);
viewProj->setFieldOfView(9.f);
viewProj->setNearZ(90.f);
viewProj->setFarZ(110.f);
viewProj->setAspectRatio(width/(float)height);
viewProj->updateView();
viewProj->updateProjection();

lightViewProj = std::make_unique<LeftHandedViewProjection>();
lightViewProj->setPosition(0.3f, 0.7f, -0.3f);
lightViewProj->setFocus(0.f, 0.f, 0.f);
lightViewProj->setFieldOfView(70.f);
lightViewProj->setNearZ(5.f);
lightViewProj->setFarZ(30.f);
lightViewProj->setAspectRatio(1.f);
lightViewProj->updateView();
lightViewProj->updateProjection();

updateViewProjTransforms();
}

void setupMaterials()
{
materials = std::make_shared<magma::DynamicUniformBuffer<PhongMaterial>>(device, Brdf::Max);
magma::helpers::mapScoped<PhongMaterial>(materials,
[this](magma::helpers::AlignedUniformArray<PhongMaterial>& materials)
{
constexpr float ambientFactor = 0.4f;

materials[Lambert].diffuse = white;
materials[OrenNayar].diffuse = white;
materials[Minnaert].diffuse = white;

materials[PhongMetallic].ambient = medium_blue * ambientFactor;
materials[PhongMetallic].diffuse = medium_blue;
materials[PhongMetallic].specular = deep_sky_blue;
materials[PhongMetallic].shininess = 2.f; // High roughness for metal look like

materials[PhongPlastic].ambient = royal_blue * ambientFactor;
materials[PhongPlastic].diffuse = royal_blue;
materials[PhongPlastic].specular = light_blue;
materials[PhongPlastic].shininess = 64.f; // Low roughness for plastic look like

materials[BlinnPhongMetallic].ambient = coral * ambientFactor;
materials[BlinnPhongMetallic].diffuse = coral;
materials[BlinnPhongMetallic].specular = light_coral;
materials[BlinnPhongMetallic].shininess = materials[PhongMetallic].shininess * 4.f;

materials[BlinnPhongPlastic].ambient = medium_sea_green * ambientFactor;
materials[BlinnPhongPlastic].diffuse = medium_sea_green;
materials[BlinnPhongPlastic].specular = light_green;
materials[BlinnPhongPlastic].shininess = materials[PhongPlastic].shininess * 4.f;
});
}

void createMesh()
{
teapot = std::make_unique<quadric::Teapot>(16, cmdCopyBuf);
}

void loadAnisoTexture()
{
aniso = loadDxtTexture(cmdCopyImg, "aniso2.dds");
}

void setupDescriptorSets()
{
using namespace magma::bindings;
using namespace magma::descriptors;
descriptor.layout = std::shared_ptr<magma::DescriptorSetLayout>(new magma::DescriptorSetLayout(device,
{
VertexStageBinding(0, DynamicUniformBuffer(1)),
FragmentStageBinding(1, UniformBuffer(1)),
FragmentStageBinding(2, UniformBuffer(1)),
FragmentStageBinding(3, DynamicUniformBuffer(1)),
FragmentStageBinding(4, CombinedImageSampler(1))
}));
descriptor.set = descriptorPool->allocateDescriptorSet(descriptor.layout);
descriptor.set->update(0, transforms);
descriptor.set->update(1, viewProjTransforms);
descriptor.set->update(2, lightSource);
descriptor.set->update(3, materials);
descriptor.set->update(4, aniso, anisotropicClampToEdge);
}

void setupGraphicsPipelines()
{
auto specialization(std::make_shared<magma::Specialization>(constants,
magma::SpecializationEntry(0, &Constants::gammaCorrection)));
lambertPipeline = createCommonSpecializedPipeline(
"transform.o", "lambert.o", specialization,
teapot->getVertexInput(), descriptor.layout);
phongPipeline = createCommonSpecializedPipeline(
"transform.o", "phong.o", specialization,
teapot->getVertexInput(), descriptor.layout);
blinnPhongPipeline = createCommonSpecializedPipeline(
"transform.o", "blinnPhong.o", specialization,
teapot->getVertexInput(), descriptor.layout);
orenNayarPipeline = createCommonSpecializedPipeline(
"transform.o", "orenNayar.o", specialization,
teapot->getVertexInput(), descriptor.layout);
minnaertPipeline = createCommonSpecializedPipeline(
"transform.o", "minnaert.o", specialization,
teapot->getVertexInput(), descriptor.layout);
anisoPipeline = createCommonSpecializedPipeline(
"transform.o", "aniso.o", specialization,
teapot->getVertexInput(), descriptor.layout);
wardPipeline = createCommonSpecializedPipeline(
"transform.o", "ward.o", specialization,
teapot->getVertexInput(), descriptor.layout);
}

void renderScene(std::shared_ptr<magma::CommandBuffer> cmdBuffer)
{
cmdBuffer->begin();
{
cmdBuffer->beginRenderPass(msaaFramebuffer->getRenderPass(), msaaFramebuffer->getFramebuffer(),
{
magma::ClearColor(0.349f, 0.289f, 0.255f, 1.f),
magma::clears::depthOne
});
{
cmdBuffer->setViewport(magma::Viewport(0, 0, msaaFramebuffer->getExtent()));
cmdBuffer->setScissor(magma::Scissor(0, 0, msaaFramebuffer->getExtent()));
std::shared_ptr<magma::GraphicsPipeline> pipelines[] = {
lambertPipeline,
phongPipeline,
phongPipeline,
orenNayarPipeline,
blinnPhongPipeline,
blinnPhongPipeline,
minnaertPipeline,
anisoPipeline,
wardPipeline
};
for (uint32_t i = 0; i < Brdf::Max; ++i)
{
cmdBuffer->bindPipeline(pipelines[i]);
cmdBuffer->bindDescriptorSet(pipelines[i], descriptor.set, {
transforms->getDynamicOffset(i),
materials->getDynamicOffset(i)
});
teapot->draw(cmdBuffer);
}
}
cmdBuffer->endRenderPass();
}
cmdBuffer->end();
}
};

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

0 comments on commit dd96d25

Please sign in to comment.