Skip to content

Commit dd96d25

Browse files
committed
Implemented basic BRDF demo
1 parent 772b3b6 commit dd96d25

22 files changed

+882
-1
lines changed

aggregated-graphics-samples.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cook-torrance", "cook-torra
105105
{67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1}
106106
EndProjectSection
107107
EndProject
108+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "brdf", "brdf\brdf.vcxproj", "{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}"
109+
ProjectSection(ProjectDependencies) = postProject
110+
{8D9D4A3E-439A-4210-8879-259B20D992CA} = {8D9D4A3E-439A-4210-8879-259B20D992CA}
111+
{51CC36B3-921E-4853-ACD5-CB6CBC27FBA1} = {51CC36B3-921E-4853-ACD5-CB6CBC27FBA1}
112+
{67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1}
113+
EndProjectSection
114+
EndProject
108115
Global
109116
GlobalSection(SolutionConfigurationPlatforms) = preSolution
110117
Debug|x64 = Debug|x64
@@ -241,6 +248,14 @@ Global
241248
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x64.Build.0 = Release|x64
242249
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x86.ActiveCfg = Release|Win32
243250
{BD1204E5-C806-45FB-B095-50DB7D323C1D}.Release|x86.Build.0 = Release|Win32
251+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x64.ActiveCfg = Debug|x64
252+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x64.Build.0 = Debug|x64
253+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x86.ActiveCfg = Debug|Win32
254+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Debug|x86.Build.0 = Debug|Win32
255+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x64.ActiveCfg = Release|x64
256+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x64.Build.0 = Release|x64
257+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x86.ActiveCfg = Release|Win32
258+
{B013429B-E9FC-4097-AC72-D3AE5D5A43EC}.Release|x86.Build.0 = Release|Win32
244259
EndGlobalSection
245260
GlobalSection(SolutionProperties) = preSolution
246261
HideSolutionNode = FALSE

assets/textures/aniso2.dds

341 KB
Binary file not shown.

brdf/brdf.cpp

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#include "graphicsApp.h"
2+
#include "colorTable.h"
3+
#include "textureLoader.h"
4+
#include "quadric/include/teapot.h"
5+
6+
class BasicBrdf : public GraphicsApp
7+
{
8+
struct Constants
9+
{
10+
VkBool32 gammaCorrection = true;
11+
};
12+
13+
enum Brdf : uint32_t
14+
{
15+
Lambert = 0, PhongMetallic, PhongPlastic,
16+
OrenNayar, BlinnPhongMetallic, BlinnPhongPlastic,
17+
Minnaert, Aniso, Ward,
18+
Max
19+
};
20+
21+
std::unique_ptr<quadric::Teapot> teapot;
22+
std::shared_ptr<magma::DynamicUniformBuffer<PhongMaterial>> materials;
23+
std::shared_ptr<magma::ImageView> aniso;
24+
std::shared_ptr<magma::GraphicsPipeline> lambertPipeline;
25+
std::shared_ptr<magma::GraphicsPipeline> phongPipeline;
26+
std::shared_ptr<magma::GraphicsPipeline> blinnPhongPipeline;
27+
std::shared_ptr<magma::GraphicsPipeline> orenNayarPipeline;
28+
std::shared_ptr<magma::GraphicsPipeline> minnaertPipeline;
29+
std::shared_ptr<magma::GraphicsPipeline> anisoPipeline;
30+
std::shared_ptr<magma::GraphicsPipeline> wardPipeline;
31+
DescriptorSet descriptor;
32+
33+
Constants constants;
34+
35+
public:
36+
explicit BasicBrdf(const AppEntry& entry):
37+
GraphicsApp(entry, TEXT("Basic BRDFs"), 1280, 720, true)
38+
{
39+
createTransformBuffer(9);
40+
setupViewProjection();
41+
setupMaterials();
42+
createMesh();
43+
loadAnisoTexture();
44+
setupDescriptorSets();
45+
setupGraphicsPipelines();
46+
47+
renderScene(drawCmdBuffer);
48+
blit(msaaFramebuffer->getColorView(), FrontBuffer);
49+
blit(msaaFramebuffer->getColorView(), BackBuffer);
50+
}
51+
52+
virtual void render(uint32_t bufferIndex) override
53+
{
54+
updateTransforms();
55+
submitCommandBuffers(bufferIndex);
56+
sleep(2); // Cap fps
57+
}
58+
59+
virtual void onKeyDown(char key, int repeat, uint32_t flags) override
60+
{
61+
switch (key)
62+
{
63+
case AppKey::Space:
64+
constants.gammaCorrection = !constants.gammaCorrection;
65+
setupGraphicsPipelines();
66+
renderScene(drawCmdBuffer);
67+
break;
68+
}
69+
VulkanApp::onKeyDown(key, repeat, flags);
70+
}
71+
72+
virtual void updateLightSource() override
73+
{
74+
magma::helpers::mapScoped<LightSource>(lightSource,
75+
[this](auto *light)
76+
{ // Directional light
77+
constexpr float ambientFactor = 0.4f;
78+
const rapid::matrix normalMatrix = rapid::transpose(rapid::inverse(viewProj->getView()));
79+
const rapid::vector3 lightViewDir = normalMatrix * lightViewProj->getPosition();
80+
light->viewPosition = lightViewDir.normalized();
81+
light->ambient = white * ambientFactor;
82+
light->diffuse = white;
83+
light->specular = white;
84+
});
85+
}
86+
87+
void updateTransforms()
88+
{
89+
constexpr float dx = 8.f, dy = 5.f;
90+
static const rapid::matrix offset = rapid::translation(0.f, -1.5f, 0.f);
91+
static const rapid::matrix grid3x3[Brdf::Max] = {
92+
rapid::translation(-dx, dy),
93+
rapid::translation(0.f, dy),
94+
rapid::translation( dx, dy),
95+
rapid::translation(-dx, 0.f),
96+
rapid::translation(0.f, 0.f),
97+
rapid::translation( dx, 0.f),
98+
rapid::translation(-dx, -dy),
99+
rapid::translation(0.f, -dy),
100+
rapid::translation( dx, -dy)
101+
};
102+
const rapid::matrix rotation = arcball->transform();
103+
std::vector<rapid::matrix, core::aligned_allocator<rapid::matrix>> transforms(Brdf::Max);
104+
for (uint32_t i = 0; i < Brdf::Max; ++i)
105+
transforms[i] = offset * rotation * grid3x3[i];
106+
updateObjectTransforms(transforms);
107+
}
108+
109+
void setupViewProjection()
110+
{
111+
viewProj = std::make_unique<LeftHandedViewProjection>();
112+
viewProj->setPosition(0.f, 0.f, -100.0f);
113+
viewProj->setFocus(0.f, 0.f, 0.f);
114+
viewProj->setFieldOfView(9.f);
115+
viewProj->setNearZ(90.f);
116+
viewProj->setFarZ(110.f);
117+
viewProj->setAspectRatio(width/(float)height);
118+
viewProj->updateView();
119+
viewProj->updateProjection();
120+
121+
lightViewProj = std::make_unique<LeftHandedViewProjection>();
122+
lightViewProj->setPosition(0.3f, 0.7f, -0.3f);
123+
lightViewProj->setFocus(0.f, 0.f, 0.f);
124+
lightViewProj->setFieldOfView(70.f);
125+
lightViewProj->setNearZ(5.f);
126+
lightViewProj->setFarZ(30.f);
127+
lightViewProj->setAspectRatio(1.f);
128+
lightViewProj->updateView();
129+
lightViewProj->updateProjection();
130+
131+
updateViewProjTransforms();
132+
}
133+
134+
void setupMaterials()
135+
{
136+
materials = std::make_shared<magma::DynamicUniformBuffer<PhongMaterial>>(device, Brdf::Max);
137+
magma::helpers::mapScoped<PhongMaterial>(materials,
138+
[this](magma::helpers::AlignedUniformArray<PhongMaterial>& materials)
139+
{
140+
constexpr float ambientFactor = 0.4f;
141+
142+
materials[Lambert].diffuse = white;
143+
materials[OrenNayar].diffuse = white;
144+
materials[Minnaert].diffuse = white;
145+
146+
materials[PhongMetallic].ambient = medium_blue * ambientFactor;
147+
materials[PhongMetallic].diffuse = medium_blue;
148+
materials[PhongMetallic].specular = deep_sky_blue;
149+
materials[PhongMetallic].shininess = 2.f; // High roughness for metal look like
150+
151+
materials[PhongPlastic].ambient = royal_blue * ambientFactor;
152+
materials[PhongPlastic].diffuse = royal_blue;
153+
materials[PhongPlastic].specular = light_blue;
154+
materials[PhongPlastic].shininess = 64.f; // Low roughness for plastic look like
155+
156+
materials[BlinnPhongMetallic].ambient = coral * ambientFactor;
157+
materials[BlinnPhongMetallic].diffuse = coral;
158+
materials[BlinnPhongMetallic].specular = light_coral;
159+
materials[BlinnPhongMetallic].shininess = materials[PhongMetallic].shininess * 4.f;
160+
161+
materials[BlinnPhongPlastic].ambient = medium_sea_green * ambientFactor;
162+
materials[BlinnPhongPlastic].diffuse = medium_sea_green;
163+
materials[BlinnPhongPlastic].specular = light_green;
164+
materials[BlinnPhongPlastic].shininess = materials[PhongPlastic].shininess * 4.f;
165+
});
166+
}
167+
168+
void createMesh()
169+
{
170+
teapot = std::make_unique<quadric::Teapot>(16, cmdCopyBuf);
171+
}
172+
173+
void loadAnisoTexture()
174+
{
175+
aniso = loadDxtTexture(cmdCopyImg, "aniso2.dds");
176+
}
177+
178+
void setupDescriptorSets()
179+
{
180+
using namespace magma::bindings;
181+
using namespace magma::descriptors;
182+
descriptor.layout = std::shared_ptr<magma::DescriptorSetLayout>(new magma::DescriptorSetLayout(device,
183+
{
184+
VertexStageBinding(0, DynamicUniformBuffer(1)),
185+
FragmentStageBinding(1, UniformBuffer(1)),
186+
FragmentStageBinding(2, UniformBuffer(1)),
187+
FragmentStageBinding(3, DynamicUniformBuffer(1)),
188+
FragmentStageBinding(4, CombinedImageSampler(1))
189+
}));
190+
descriptor.set = descriptorPool->allocateDescriptorSet(descriptor.layout);
191+
descriptor.set->update(0, transforms);
192+
descriptor.set->update(1, viewProjTransforms);
193+
descriptor.set->update(2, lightSource);
194+
descriptor.set->update(3, materials);
195+
descriptor.set->update(4, aniso, anisotropicClampToEdge);
196+
}
197+
198+
void setupGraphicsPipelines()
199+
{
200+
auto specialization(std::make_shared<magma::Specialization>(constants,
201+
magma::SpecializationEntry(0, &Constants::gammaCorrection)));
202+
lambertPipeline = createCommonSpecializedPipeline(
203+
"transform.o", "lambert.o", specialization,
204+
teapot->getVertexInput(), descriptor.layout);
205+
phongPipeline = createCommonSpecializedPipeline(
206+
"transform.o", "phong.o", specialization,
207+
teapot->getVertexInput(), descriptor.layout);
208+
blinnPhongPipeline = createCommonSpecializedPipeline(
209+
"transform.o", "blinnPhong.o", specialization,
210+
teapot->getVertexInput(), descriptor.layout);
211+
orenNayarPipeline = createCommonSpecializedPipeline(
212+
"transform.o", "orenNayar.o", specialization,
213+
teapot->getVertexInput(), descriptor.layout);
214+
minnaertPipeline = createCommonSpecializedPipeline(
215+
"transform.o", "minnaert.o", specialization,
216+
teapot->getVertexInput(), descriptor.layout);
217+
anisoPipeline = createCommonSpecializedPipeline(
218+
"transform.o", "aniso.o", specialization,
219+
teapot->getVertexInput(), descriptor.layout);
220+
wardPipeline = createCommonSpecializedPipeline(
221+
"transform.o", "ward.o", specialization,
222+
teapot->getVertexInput(), descriptor.layout);
223+
}
224+
225+
void renderScene(std::shared_ptr<magma::CommandBuffer> cmdBuffer)
226+
{
227+
cmdBuffer->begin();
228+
{
229+
cmdBuffer->beginRenderPass(msaaFramebuffer->getRenderPass(), msaaFramebuffer->getFramebuffer(),
230+
{
231+
magma::ClearColor(0.349f, 0.289f, 0.255f, 1.f),
232+
magma::clears::depthOne
233+
});
234+
{
235+
cmdBuffer->setViewport(magma::Viewport(0, 0, msaaFramebuffer->getExtent()));
236+
cmdBuffer->setScissor(magma::Scissor(0, 0, msaaFramebuffer->getExtent()));
237+
std::shared_ptr<magma::GraphicsPipeline> pipelines[] = {
238+
lambertPipeline,
239+
phongPipeline,
240+
phongPipeline,
241+
orenNayarPipeline,
242+
blinnPhongPipeline,
243+
blinnPhongPipeline,
244+
minnaertPipeline,
245+
anisoPipeline,
246+
wardPipeline
247+
};
248+
for (uint32_t i = 0; i < Brdf::Max; ++i)
249+
{
250+
cmdBuffer->bindPipeline(pipelines[i]);
251+
cmdBuffer->bindDescriptorSet(pipelines[i], descriptor.set, {
252+
transforms->getDynamicOffset(i),
253+
materials->getDynamicOffset(i)
254+
});
255+
teapot->draw(cmdBuffer);
256+
}
257+
}
258+
cmdBuffer->endRenderPass();
259+
}
260+
cmdBuffer->end();
261+
}
262+
};
263+
264+
std::unique_ptr<IApplication> appFactory(const AppEntry& entry)
265+
{
266+
return std::unique_ptr<BasicBrdf>(new BasicBrdf(entry));
267+
}

0 commit comments

Comments
 (0)