diff --git a/aggregated-graphics-samples.sln b/aggregated-graphics-samples.sln index 1c3f055..ca72da0 100644 --- a/aggregated-graphics-samples.sln +++ b/aggregated-graphics-samples.sln @@ -126,6 +126,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge-detection", "edge-dete {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} = {67B01ECD-2613-4FA0-84F7-87F5BCF40EB1} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srgb", "srgb\srgb.vcxproj", "{E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}" + 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 @@ -286,6 +293,14 @@ Global {591F9775-8088-457A-B237-A7EA1DEF699D}.Release|x64.Build.0 = Release|x64 {591F9775-8088-457A-B237-A7EA1DEF699D}.Release|x86.ActiveCfg = Release|Win32 {591F9775-8088-457A-B237-A7EA1DEF699D}.Release|x86.Build.0 = Release|Win32 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Debug|x64.ActiveCfg = Debug|x64 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Debug|x64.Build.0 = Debug|x64 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Debug|x86.ActiveCfg = Debug|Win32 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Debug|x86.Build.0 = Debug|Win32 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Release|x64.ActiveCfg = Release|x64 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Release|x64.Build.0 = Release|x64 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Release|x86.ActiveCfg = Release|Win32 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/framework/common.h b/framework/common.h index 1032a47..3f7d118 100644 --- a/framework/common.h +++ b/framework/common.h @@ -24,7 +24,10 @@ struct alignas(16) ViewProjTransforms struct alignas(16) LightSource { - rapid::vector viewPosition; + union { + rapid::vector viewPosition; + rapid::vector viewDirection; + }; LinearColor ambient; LinearColor diffuse; LinearColor specular; diff --git a/screenshots/sRGB.jpg b/screenshots/sRGB.jpg new file mode 100644 index 0000000..a20508f Binary files /dev/null and b/screenshots/sRGB.jpg differ diff --git a/srgb/shaders/phong.frag b/srgb/shaders/phong.frag new file mode 100644 index 0000000..9d15b60 --- /dev/null +++ b/srgb/shaders/phong.frag @@ -0,0 +1,42 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable +#include "common/transforms.h" +#include "common/sRGB.h" +#include "brdf/phong.h" + +layout(binding = 2) uniform Light { + vec3 viewDir; +} light; + +layout(constant_id = 0) const bool c_sRGB = false; + +layout(location = 0) in vec3 viewPos; +layout(location = 1) in vec3 viewNormal; + +layout(location = 0) out vec3 oColor; + +vec3 gamma(vec3 color) +{ + return c_sRGB ? linear(color) : color; +} + +void main() +{ + const float ambient = 0.2; + const vec3 alice_blue = vec3(240, 248, 255)/255.; + const vec3 white = vec3(1.); + const float shininess = 128.; + + vec3 n = normalize(viewNormal); + vec3 l = normalize(light.viewDir); + vec3 v = normalize(-viewPos); + + oColor = phong(n, l, v, + gamma(alice_blue * ambient), gamma(white * ambient), + gamma(alice_blue), gamma(white), + gamma(alice_blue), gamma(white), + shininess, 1.); + + if (c_sRGB) + oColor = sRGB(oColor); +} diff --git a/srgb/shaders/transform.vert b/srgb/shaders/transform.vert new file mode 100644 index 0000000..de293f1 --- /dev/null +++ b/srgb/shaders/transform.vert @@ -0,0 +1,20 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable +#include "common/transforms.h" + +layout(location = 0) in vec4 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 texCoord; + +layout(location = 0) out vec3 oViewPos; +layout(location = 1) out vec3 oViewNormal; +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() +{ + oViewPos = (worldView * position).xyz; + oViewNormal = mat3(normalMatrix) * normal; + gl_Position = worldViewProj * position; +} diff --git a/srgb/srgb.cpp b/srgb/srgb.cpp new file mode 100644 index 0000000..a163d68 --- /dev/null +++ b/srgb/srgb.cpp @@ -0,0 +1,148 @@ +#include "graphicsApp.h" +#include "colorTable.h" +#include "quadric/include/sphere.h" + +class GammaCorrection : public GraphicsApp +{ + std::unique_ptr sphere; + std::shared_ptr rgbPipeline; + std::shared_ptr srgbPipeline; + DescriptorSet descriptor; + +public: + explicit GammaCorrection(const AppEntry& entry): + GraphicsApp(entry, TEXT("Gamma correction"), 1280, 720, false) + { + createTransformBuffer(2); + setupViewProjection(); + createMesh(); + 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 updateLightSource() override + { + magma::helpers::mapScoped(lightSource, + [this](auto *light) + { + const rapid::matrix normalMatrix = viewProj->calculateNormal(rapid::identity()); + const rapid::vector3 lightViewDir = normalMatrix * lightViewProj->getPosition(); + light->viewDirection = lightViewDir.normalized(); + }); + } + + void updateTransforms() + { + std::vector> transforms = { + rapid::translation(-1.5f, 0.f), + rapid::translation(1.5f, 0.f), + }; + updateObjectTransforms(transforms); + } + + void setupViewProjection() + { + viewProj = std::make_unique(); + viewProj->setPosition(0.f, 0.f, -100.f); + viewProj->setFocus(0.f, 0.f, 0.f); + viewProj->setFieldOfView(2.f); + viewProj->setNearZ(90.f); + viewProj->setFarZ(110.f); + viewProj->setAspectRatio(width/(float)height); + viewProj->updateView(); + viewProj->updateProjection(); + + lightViewProj = std::make_unique(); + lightViewProj->setPosition(1.f, 1.f, -0.4f); + 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 createMesh() + { + sphere = std::make_unique(1.f, 64, 64, false, cmdCopyBuf); + } + + void setupDescriptorSets() + { + using namespace magma::bindings; + using namespace magma::descriptors; + descriptor.layout = std::shared_ptr(new magma::DescriptorSetLayout(device, + { + VertexStageBinding(0, DynamicUniformBuffer(1)), + FragmentStageBinding(1, UniformBuffer(1)), + FragmentStageBinding(2, UniformBuffer(1)) + })); + descriptor.set = descriptorPool->allocateDescriptorSet(descriptor.layout); + descriptor.set->update(0, transforms); + descriptor.set->update(1, viewProjTransforms); + descriptor.set->update(2, lightSource); + } + + void setupGraphicsPipelines() + { + struct Constants + { + VkBool32 sRGB; + } constants; + constants.sRGB = false; + auto rgb(std::make_shared(constants, + magma::SpecializationEntry(0, &Constants::sRGB))); + rgbPipeline = createCommonSpecializedPipeline( + "transform.o", "phong.o", std::move(rgb), + sphere->getVertexInput(), + descriptor.layout); + constants.sRGB = true; + auto sRGB(std::make_shared(constants, + magma::SpecializationEntry(0, &Constants::sRGB))); + srgbPipeline = createCommonSpecializedPipeline( + "transform.o", "phong.o", std::move(sRGB), + sphere->getVertexInput(), + descriptor.layout); + } + + void renderScene(std::shared_ptr cmdBuffer) + { + cmdBuffer->begin(); + { + cmdBuffer->beginRenderPass(msaaFramebuffer->getRenderPass(), msaaFramebuffer->getFramebuffer(), + { + magma::ClearColor(0.35f, 0.53f, 0.7f, 1.f), + magma::clears::depthOne + }); + { + cmdBuffer->bindPipeline(rgbPipeline); + cmdBuffer->bindDescriptorSet(rgbPipeline, descriptor.set, transforms->getDynamicOffset(0)); + sphere->draw(cmdBuffer); + cmdBuffer->bindPipeline(srgbPipeline); + cmdBuffer->bindDescriptorSet(srgbPipeline, descriptor.set, transforms->getDynamicOffset(1)); + sphere->draw(cmdBuffer); + } + cmdBuffer->endRenderPass(); + } + cmdBuffer->end(); + } +}; + +std::unique_ptr appFactory(const AppEntry& entry) +{ + return std::unique_ptr(new GammaCorrection(entry)); +} diff --git a/srgb/srgb.vcxproj b/srgb/srgb.vcxproj new file mode 100644 index 0000000..5dce60e --- /dev/null +++ b/srgb/srgb.vcxproj @@ -0,0 +1,173 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + Document + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + %(Filename).o + + + Document + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + $(VK_SDK_PATH)\Bin32\glslangValidator.exe -V %(FullPath) -I..\framework\shaders -o %(Filename).o + %(Filename).o + %(Filename).o + %(Filename).o + %(Filename).o + + + + 15.0 + {E8FAC55E-ACDF-497D-B8F9-A85599BBEEA6} + template + 10.0.16299.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + _DEBUG;VK_USE_PLATFORM_WIN32_KHR;%(PreprocessorDefinitions) + $(VK_SDK_PATH)\Include;..\third-party;..\framework + + + vulkan-1.lib;magma.lib;quadric.lib;framework.lib;Shcore.lib;%(AdditionalDependencies) + $(VK_SDK_PATH)\Lib32;..\Debug + Windows + + + + + Level3 + Disabled + true + true + _DEBUG;VK_USE_PLATFORM_WIN32_KHR;%(PreprocessorDefinitions) + $(VK_SDK_PATH)\Include;..\third-party;..\framework + + + Windows + vulkan-1.lib;magma.lib;quadric.lib;framework.lib;Shcore.lib;%(AdditionalDependencies) + $(VK_SDK_PATH)\Lib;..\x64\Debug + + + + + Level3 + MaxSpeed + true + true + true + true + NDEBUG;VK_USE_PLATFORM_WIN32_KHR;%(PreprocessorDefinitions) + $(VK_SDK_PATH)\Include;..\third-party;..\framework + MultiThreaded + + + true + true + vulkan-1.lib;magma.lib;quadric.lib;framework.lib;Shcore.lib;%(AdditionalDependencies) + $(VK_SDK_PATH)\Lib32;..\Release + Windows + + + + + Level3 + MaxSpeed + true + true + true + true + NDEBUG;VK_USE_PLATFORM_WIN32_KHR;%(PreprocessorDefinitions) + $(VK_SDK_PATH)\Include;..\third-party;..\framework + MultiThreaded + + + true + true + Windows + vulkan-1.lib;magma.lib;quadric.lib;framework.lib;Shcore.lib;%(AdditionalDependencies) + $(VK_SDK_PATH)\Lib;..\x64\Release + + + + + + \ No newline at end of file diff --git a/srgb/srgb.vcxproj.filters b/srgb/srgb.vcxproj.filters new file mode 100644 index 0000000..86ee2cb --- /dev/null +++ b/srgb/srgb.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file