Skip to content
Snippets Groups Projects
Verified Commit c15bd821 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Adjust demos and add cube mapping demo

parent 66de1a84
Branches
No related tags found
No related merge requests found
add_subdirectory(CubeMapping)
add_subdirectory(InstancingDemo)
add_subdirectory(NormalMapping)
CubeMapping
\ No newline at end of file
cmake_minimum_required(VERSION 3.16)
project(CubeMapping)
# setting c++ standard for the project
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# adding source files to the project
add_project(CubeMapping src/main.cpp)
# including headers of dependencies and the VkCV framework
target_include_directories(CubeMapping SYSTEM BEFORE PRIVATE ${vkcv_includes})
# linking with libraries from all dependencies and the VkCV framework
target_link_libraries(CubeMapping ${vkcv_libraries})
#version 450
//incoming data
layout(location = 0) in vec3 passPosition;
layout(location = 1) in vec3 passNormal;
layout(location = 2) in vec2 passUVCoord;
layout(location = 3) in vec3 passReflectionNormal;
layout(set=0, binding=0) uniform matrixBuffer {
mat4 viewMatrix;
mat4 projectionMatrix;
};
struct Material {
vec3 diffuse;
float reflectionStrength;
vec3 specular;
float shininess;
};
layout(set=0, binding=1) uniform materialBuffer {
Material mat;
};
struct Light {
vec4 pos; // pos.w = 0 (dir light), pos.w = 1 (point light)
vec3 col;
float spot_exponent;
vec3 spot_direction;
float spot_cutoff; // no spotlight if cutoff = 0
};
layout(set=0, binding=2) uniform lightBuffer {
Light light;
vec3 lightAmbient;
};
layout(set=0, binding=3) uniform textureCube cubeMapTexture;
layout(set=0, binding=4) uniform sampler cubeMapSampler;
layout(location = 0) out vec4 fragmentColor;
void main() {
///////////////////////////////////////////////////////
///////////////// Cube Map Reflection /////////////////
///////////////////////////////////////////////////////
vec3 pos = normalize(passPosition);
vec3 normal = normalize(passReflectionNormal);
vec3 reflected = reflect(pos, normal);
reflected = vec3(inverse(viewMatrix) * vec4(reflected, 0.0));
vec3 inNormal = normalize(passNormal);
//Diffuse
vec3 lightVector;
vec3 light_camcoord = (viewMatrix * light.pos).xyz;
if (light.pos.w > 0.001f)
lightVector = normalize(light_camcoord - passPosition);
else
lightVector = normalize(light_camcoord);
float cos_phi = max(dot(inNormal, lightVector), 0.0f);
// Specular
vec3 eye = normalize(-passPosition);
vec3 reflection = normalize(reflect(-lightVector, inNormal));
float cos_psi_n = pow(max(dot(reflection, eye), 0.0f), mat.shininess);
//Spotlight
float spot = 1.0;
if (light.spot_cutoff >= 0.001f) {
float cos_phi_spot = max(dot(-lightVector, mat3(viewMatrix) * light.spot_direction), 0.0f);
if (cos_phi_spot >= cos(light.spot_cutoff)) {
spot = pow(cos_phi_spot, light.spot_exponent);
} else {
spot = 0.0f;
}
}
//Color
vec3 diffuse_color = mat.diffuse;
//All together
fragmentColor.rgb = diffuse_color * lightAmbient;
fragmentColor.rgb += spot * diffuse_color * cos_phi * light.col;
fragmentColor.rgb += spot * mat.specular * cos_psi_n * light.col;
fragmentColor *= (1.0 - mat.reflectionStrength);
fragmentColor += texture(samplerCube(cubeMapTexture, cubeMapSampler), reflected) * mat.reflectionStrength;
fragmentColor.a = 1.0;
}
#version 450
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv;
layout(set=0, binding=0) uniform matrixBuffer {
mat4 viewMatrix;
mat4 projectionMatrix;
};
layout( push_constant ) uniform constants {
mat4 modelMatrix;
};
layout(location = 0) out vec3 passPosition;
layout(location = 1) out vec3 passNormal;
layout(location = 2) out vec2 passUVCoord;
layout(location = 3) out vec3 passReflectionNormal;
void main() {
passPosition = (viewMatrix * modelMatrix * vec4(position, 1)).xyz;
passNormal = vec3(transpose(inverse(viewMatrix * modelMatrix)) * vec4(normal, 0));
passUVCoord = uv;
passReflectionNormal = vec3(viewMatrix * modelMatrix * vec4(normal, 0));
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1);
}
#version 450
//incoming data
layout(location = 0) in vec3 passTexCoord;
layout(set=0, binding=1) uniform textureCube cubeMapTexture;
layout(set=0, binding=2) uniform sampler cubeMapSampler;
layout(location = 0) out vec4 fragmentColor;
void main() {
fragmentColor = texture(samplerCube(cubeMapTexture, cubeMapSampler), passTexCoord);
}
#version 450
layout(location = 0) in vec3 position;
layout(set=0, binding=0) uniform matrixBuffer {
mat4 viewMatrix;
mat4 projectionMatrix;
};
layout(location = 0) out vec3 passTexCoord;
void main() {
passTexCoord = position;
mat4 vM = mat4(mat3(viewMatrix));
// Set Pos to xyww instead of xyzw, so that z will always be 1 (furthest from camera)
gl_Position = (projectionMatrix * vM * vec4(position, 1)).xyww;
}
#include <iostream>
#include <vkcv/Buffer.hpp>
#include <vkcv/Core.hpp>
#include <vkcv/DescriptorWrites.hpp>
#include <vkcv/Image.hpp>
#include <vkcv/Pass.hpp>
#include <vkcv/Sampler.hpp>
#include <vkcv/Window.hpp>
#include <vkcv/asset/asset_loader.hpp>
#include <vkcv/camera/CameraManager.hpp>
#include <vkcv/geometry/Cuboid.hpp>
#include <vkcv/geometry/Sphere.hpp>
#include <vkcv/geometry/Teapot.hpp>
#include <vkcv/gui/GUI.hpp>
#include <vkcv/shader/GLSLCompiler.hpp>
struct Material {
glm::vec3 diffuse;
float reflectionStrength;
glm::vec3 specular;
float shininess;
};
struct Light {
glm::vec4 pos; // pos.w = 0 (dir light), pos.w = 1 (point light)
glm::vec3 col;
float spot_exponent;
glm::vec3 spot_direction;
float spot_cutoff; // no spotlight if cutoff = 0
};
struct LightProps {
Light light;
glm::vec3 lightAmbient;
};
struct FogParams {
glm::vec3 col; // Fog color
float density; // For exp and exp2 equation
float start; // This is only for linear fog
float end; // This is only for linear fog
int mode; // 1 = linear, 2 = exp, 3 = exp2
};
struct TextureProps {
int useColorTexture;
};
int main(int argc, const char** argv) {
const std::string applicationName = "Cube Mapping";
vkcv::Core core = vkcv::Core::create(
applicationName,
VK_MAKE_VERSION(0, 0, 1),
{ vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eTransfer },
{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }
);
vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 800, true);
vkcv::Window& window = core.getWindow(windowHandle);
vkcv::camera::CameraManager cameraManager (window);
auto camHandle = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
cameraManager.getCamera(camHandle).setNearFar(0.1f, 10.0f);
vkcv::shader::GLSLCompiler compiler;
vkcv::ShaderProgram cubeMappingShaderProgram, skyBoxShaderProgram;
compiler.compileProgram(
cubeMappingShaderProgram,
{
{ vkcv::ShaderStage::VERTEX, "shaders/CubeMapReflection.vert" },
{ vkcv::ShaderStage::FRAGMENT, "shaders/CubeMapReflection.frag" }
},
nullptr
);
compiler.compileProgram(
skyBoxShaderProgram,
{
{ vkcv::ShaderStage::VERTEX, "shaders/SkyBox.vert" },
{ vkcv::ShaderStage::FRAGMENT, "shaders/SkyBox.frag" }
},
nullptr
);
vkcv::PassHandle renderPass = core.createPass(vkcv::PassConfig(
{
vkcv::AttachmentDescription(
core.getSwapchainFormat(window.getSwapchain()),
vkcv::AttachmentOperation::CLEAR,
vkcv::AttachmentOperation::STORE,
vk::ClearValue(vk::ClearColorValue(std::array<float, 4>{
1.0f, 1.0f, 1.0f, 1.0f
}))
),
vkcv::AttachmentDescription(
vk::Format::eD32Sfloat,
vkcv::AttachmentOperation::CLEAR,
vkcv::AttachmentOperation::STORE
)
}
));
vkcv::PassHandle skyRenderPass = vkcv::passSwapchain(core, window.getSwapchain(), {
vk::Format::eUndefined, vk::Format::eD32Sfloat
}, false);
const vkcv::VertexLayout vertexLayoutCubeMapping {
vkcv::createVertexBindings(cubeMappingShaderProgram.getVertexAttachments())
};
const vkcv::VertexLayout vertexLayoutSykBox {
vkcv::createVertexBindings(skyBoxShaderProgram.getVertexAttachments())
};
const vkcv::DescriptorBindings descriptorBindings = (
cubeMappingShaderProgram.getReflectedDescriptors().at(0)
);
auto descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings);
auto descriptorSetSphere = core.createDescriptorSet(descriptorSetLayout);
auto descriptorSetTeapot = core.createDescriptorSet(descriptorSetLayout);
const vkcv::DescriptorBindings& descriptorBindingsSkyBox = (
skyBoxShaderProgram.getReflectedDescriptors().at(0)
);
auto descriptorSetLayoutSkyBox = core.createDescriptorSetLayout(descriptorBindingsSkyBox);
auto descriptorSetSkyBox = core.createDescriptorSet(descriptorSetLayoutSkyBox);
vkcv::GraphicsPipelineHandle cubeMappingPipeline = core.createGraphicsPipeline(
vkcv::GraphicsPipelineConfig(
cubeMappingShaderProgram,
renderPass,
vertexLayoutCubeMapping,
{ descriptorSetLayout }
)
);
vkcv::GraphicsPipelineHandle skyBoxPipeline = core.createGraphicsPipeline(
vkcv::GraphicsPipelineConfig(
skyBoxShaderProgram,
skyRenderPass,
vertexLayoutSykBox,
{ descriptorSetLayoutSkyBox }
)
);
auto matrixBuffer = vkcv::buffer<glm::mat4>(
core,
vkcv::BufferType::UNIFORM,
2,
vkcv::BufferMemoryType::HOST_VISIBLE
);
auto matBlueBuffer = vkcv::buffer<Material>(
core,
vkcv::BufferType::UNIFORM,
1
);
Material mat_blue;
mat_blue.diffuse = glm::vec3(0.0f, 0.0f, 1.0f);
mat_blue.reflectionStrength = 0.7f;
mat_blue.specular = glm::vec3(1.0f);
mat_blue.shininess = 100.0f;
matBlueBuffer.fill(&mat_blue, 1);
auto matRedBuffer = vkcv::buffer<Material>(
core,
vkcv::BufferType::UNIFORM,
1
);
Material mat_red;
mat_red.diffuse = glm::vec3(1.0f, 0.0f, 0.0f);
mat_red.reflectionStrength = 0.7f;
mat_red.specular = glm::vec3(1.0f);
mat_red.shininess = 100.0f;
matRedBuffer.fill(&mat_red, 1);
auto lightBuffer = vkcv::buffer<LightProps>(
core,
vkcv::BufferType::UNIFORM,
1
);
LightProps lightProps;
lightProps.light.pos = glm::vec4(0.0f, 1.0f, -10.0f, 1.0f);
lightProps.light.col = glm::vec3(0.75f);
lightProps.light.spot_exponent = 1.0f;
lightProps.light.spot_direction = glm::vec3(0.0f);
lightProps.light.spot_cutoff = 0.0f;
lightProps.lightAmbient = glm::vec3(0.2f);
lightBuffer.fill(&lightProps, 1);
vkcv::asset::Texture negx = vkcv::asset::loadTexture("../../resources/cubeMap/negx.jpg");
vkcv::asset::Texture negy = vkcv::asset::loadTexture("../../resources/cubeMap/negy.jpg");
vkcv::asset::Texture negz = vkcv::asset::loadTexture("../../resources/cubeMap/negz.jpg");
vkcv::asset::Texture posx = vkcv::asset::loadTexture("../../resources/cubeMap/posx.jpg");
vkcv::asset::Texture posy = vkcv::asset::loadTexture("../../resources/cubeMap/posy.jpg");
vkcv::asset::Texture posz = vkcv::asset::loadTexture("../../resources/cubeMap/posz.jpg");
vkcv::ImageConfig cubemapConfig (negx.w, negx.h);
cubemapConfig.setCubeMapImage(true);
vkcv::Image cubemapImage = vkcv::image(core, vk::Format::eR8G8B8A8Srgb, cubemapConfig);
cubemapImage.fillLayer(0, posx.data.data());
cubemapImage.fillLayer(1, negx.data.data());
cubemapImage.fillLayer(2, posy.data.data());
cubemapImage.fillLayer(3, negy.data.data());
cubemapImage.fillLayer(4, posz.data.data());
cubemapImage.fillLayer(5, negz.data.data());
vkcv::SamplerHandle sampler = vkcv::samplerLinear(core);
{
vkcv::DescriptorWrites writes;
writes.writeUniformBuffer(0, matrixBuffer.getHandle());
writes.writeUniformBuffer(1, matRedBuffer.getHandle());
writes.writeUniformBuffer(2, lightBuffer.getHandle());
writes.writeSampledImage(3, cubemapImage.getHandle());
writes.writeSampler(4, sampler);
core.writeDescriptorSet(descriptorSetSphere, writes);
}
{
vkcv::DescriptorWrites writes;
writes.writeUniformBuffer(0, matrixBuffer.getHandle());
writes.writeUniformBuffer(1, matBlueBuffer.getHandle());
writes.writeUniformBuffer(2, lightBuffer.getHandle());
writes.writeSampledImage(3, cubemapImage.getHandle());
writes.writeSampler(4, sampler);
core.writeDescriptorSet(descriptorSetTeapot, writes);
}
{
vkcv::DescriptorWrites writes;
writes.writeUniformBuffer(0, matrixBuffer.getHandle());
writes.writeSampledImage(1, cubemapImage.getHandle());
writes.writeSampler(2, sampler);
core.writeDescriptorSet(descriptorSetSkyBox, writes);
}
vkcv::gui::GUI gui (core, windowHandle);
bool adjustedReflectionStrength = false;
bool renderSkyBox = true;
vkcv::geometry::Cuboid cube (glm::vec3(0.0f), 1.0f);
vkcv::geometry::Sphere sphere (glm::vec3(0.0f), 0.3f);
vkcv::geometry::Teapot teapot (glm::vec3(0.0f), 1.0f);
sphere.setResolution(20);
vkcv::InstanceDrawcall drawcallSphere (sphere.generateVertexData(core));
drawcallSphere.useDescriptorSet(0, descriptorSetSphere);
vkcv::InstanceDrawcall drawcallTeapot (teapot.generateVertexData(core));
drawcallTeapot.useDescriptorSet(0, descriptorSetTeapot);
vkcv::InstanceDrawcall drawcallSkyBox (cube.generateVertexData(core));
drawcallSkyBox.useDescriptorSet(0, descriptorSetSkyBox);
const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
vkcv::ImageHandle depthBuffer;
glm::mat4* mvp = matrixBuffer.map();
core.run([&](const vkcv::WindowHandle &windowHandle,
double t,
double dt,
uint32_t swapchainWidth,
uint32_t swapchainHeight
) {
if ((!depthBuffer) ||
(swapchainWidth != core.getImageWidth(depthBuffer)) ||
(swapchainHeight != core.getImageHeight(depthBuffer))) {
depthBuffer = core.createImage(
vk::Format::eD32Sfloat,
vkcv::ImageConfig(
swapchainWidth,
swapchainHeight
)
);
}
if (adjustedReflectionStrength) {
matBlueBuffer.fill(&mat_blue, 1);
matRedBuffer.fill(&mat_red, 1);
adjustedReflectionStrength = false;
}
cameraManager.update(dt);
const glm::mat4 teapotMat = glm::rotate(
glm::identity<glm::mat4>(),
glm::radians(30.0f) * static_cast<float>(t),
glm::vec3(0, 1, 0)
);
const glm::mat4 sphereMat = teapotMat * glm::rotate(
glm::translate(glm::mat4(1.0f), glm::vec3(3, 0, 0)),
glm::radians(90.0f) * static_cast<float>(t),
glm::vec3(1, 1, 1)
);
mvp[0] = cameraManager.getActiveCamera().getView();
mvp[1] = cameraManager.getActiveCamera().getProjection();
auto pushConstants = vkcv::pushConstants<glm::mat4>();
pushConstants.appendDrawcall(teapotMat);
pushConstants.appendDrawcall(sphereMat);
auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
core.prepareImageForSampling(cmdStream, cubemapImage.getHandle());
core.recordDrawcallsToCmdStream(
cmdStream,
cubeMappingPipeline,
pushConstants,
{
drawcallTeapot,
drawcallSphere
},
{
swapchainInput,
depthBuffer
},
windowHandle
);
if (renderSkyBox) {
core.recordDrawcallsToCmdStream(
cmdStream,
skyBoxPipeline,
vkcv::PushConstants(0),
{ drawcallSkyBox },
{
swapchainInput,
depthBuffer
},
windowHandle
);
}
core.prepareSwapchainImageForPresent(cmdStream);
core.submitCommandStream(cmdStream);
gui.beginGUI();
float reflectionStrength = mat_red.reflectionStrength;
ImGui::Begin("Settings");
ImGui::SliderFloat("Reflection strength", &reflectionStrength, 0.0f, 1.0f);
ImGui::Checkbox("Render sky box", &renderSkyBox);
ImGui::End();
if (reflectionStrength != mat_red.reflectionStrength) {
mat_blue.reflectionStrength = reflectionStrength;
mat_red.reflectionStrength = reflectionStrength;
adjustedReflectionStrength = true;
}
gui.endGUI();
});
matrixBuffer.unmap();
return 0;
}
......@@ -152,8 +152,10 @@ int main(int argc, const char** argv) {
(swapchainHeight != core.getImageHeight(depthBuffer))) {
depthBuffer = core.createImage(
vk::Format::eD32Sfloat,
swapchainWidth,
swapchainHeight
vkcv::ImageConfig(
swapchainWidth,
swapchainHeight
)
);
}
......
......@@ -261,8 +261,10 @@ int main(int argc, const char** argv) {
(swapchainHeight != core.getImageHeight(depthBuffer))) {
depthBuffer = core.createImage(
vk::Format::eD32Sfloat,
swapchainWidth,
swapchainHeight
vkcv::ImageConfig(
swapchainWidth,
swapchainHeight
)
);
}
......
Subproject commit 21562cea94ff11677477431f8d958c0d6577a415
Subproject commit 68955e55e1406d28006fa5696f11d10c987b8530
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment