mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-21 20:08:40 +03:00
Started shading pass
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#define GLM_FORCE_ROW_MAJOR
|
||||
|
||||
#include <glm/ext/vector_float4.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace Nuake
|
||||
|
||||
|
||||
public:
|
||||
float Near = 400.0f;
|
||||
float Far = 0.001f;
|
||||
float Near = 200.0f;
|
||||
float Far = 0.01f;
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
|
||||
Vector3 Direction = Vector3(0, 0, 1);
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Nuake {
|
||||
inline Matrix4 GetCascadeViewProjection(const int i) { return m_CascadeViewProjections[i]; }
|
||||
private:
|
||||
static const int CSM_SPLIT_AMOUNT = 4;
|
||||
const float CSM_NEAR_CLIP = 0.001f;
|
||||
const float CSM_NEAR_CLIP = 0.1f;
|
||||
const float CSM_FAR_CLIP = 400.0f;
|
||||
const float CSM_CLIP_RANGE = CSM_FAR_CLIP - CSM_NEAR_CLIP;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ void DescriptorLayoutBuilder::AddBinding(uint32_t binding, VkDescriptorType type
|
||||
newbind.binding = binding;
|
||||
newbind.descriptorCount = count;
|
||||
newbind.descriptorType = type;
|
||||
|
||||
Bindings.push_back(newbind);
|
||||
}
|
||||
|
||||
@@ -31,6 +30,7 @@ VkDescriptorSetLayout DescriptorLayoutBuilder::Build(VkDevice device, VkShaderSt
|
||||
info.pBindings = Bindings.data();
|
||||
info.bindingCount = (uint32_t)Bindings.size();
|
||||
info.flags = flags;
|
||||
|
||||
|
||||
VkDescriptorSetLayout set;
|
||||
VK_CALL(vkCreateDescriptorSetLayout(device, &info, nullptr, &set));
|
||||
|
||||
@@ -43,6 +43,8 @@ void RenderPass::ClearAttachments(PassRenderContext& ctx)
|
||||
auto& gpuResources = GPUResources::Get();
|
||||
gpuResources.AddTexture(newAttachment);
|
||||
|
||||
VulkanUtil::TransitionImage(ctx.commandBuffer, newAttachment->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// TODO: Queue deletion of old textures
|
||||
}
|
||||
|
||||
@@ -53,6 +55,8 @@ void RenderPass::ClearAttachments(PassRenderContext& ctx)
|
||||
|
||||
auto& gpuResources = GPUResources::Get();
|
||||
gpuResources.AddTexture(newDepthAttachment);
|
||||
|
||||
VulkanUtil::TransitionImage(ctx.commandBuffer, newDepthAttachment->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, true);
|
||||
}
|
||||
|
||||
// Clear all color attachments
|
||||
@@ -114,17 +118,19 @@ void RenderPass::Render(PassRenderContext& ctx)
|
||||
VkRenderingAttachmentInfo attachmentInfo = VulkanInit::AttachmentInfo(attachment.Image->GetImageView(), nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
renderAttachmentInfos.push_back(attachmentInfo);
|
||||
}
|
||||
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachmentInfo = {};
|
||||
if (DepthAttachment.Image)
|
||||
{
|
||||
depthAttachmentInfo = VulkanInit::DepthAttachmentInfo(DepthAttachment.Image->GetImageView(), VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VkRenderingInfo renderInfo = VulkanInit::RenderingInfo(ctx.resolution, renderAttachmentInfos, !DepthAttachment.Image ? nullptr : &depthAttachmentInfo);
|
||||
renderInfo.colorAttachmentCount = std::size(renderAttachmentInfos);
|
||||
renderInfo.pColorAttachments = renderAttachmentInfos.data();
|
||||
|
||||
|
||||
|
||||
// Begin render!
|
||||
vkCmdBeginRendering(ctx.commandBuffer, &renderInfo);
|
||||
{
|
||||
@@ -243,7 +249,6 @@ void RenderPass::Build()
|
||||
bufferRange.offset = 0;
|
||||
bufferRange.size = PushConstantSize;
|
||||
bufferRange.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
|
||||
pushRange = 1;
|
||||
}
|
||||
|
||||
@@ -280,8 +285,12 @@ void RenderPass::Build()
|
||||
}
|
||||
|
||||
// Set depth attachment, for now we assume every pass has a depth attachment
|
||||
pipelineBuilder.SetDepthFormat(static_cast<VkFormat>(DepthAttachment.Format));
|
||||
pipelineBuilder.EnableDepthTest(true, VK_COMPARE_OP_GREATER_OR_EQUAL);
|
||||
if (HasDepthTest)
|
||||
{
|
||||
pipelineBuilder.SetDepthFormat(static_cast<VkFormat>(DepthAttachment.Format));
|
||||
pipelineBuilder.EnableDepthTest(true, VK_COMPARE_OP_GREATER_OR_EQUAL);
|
||||
}
|
||||
|
||||
Pipeline = pipelineBuilder.BuildPipeline(VkRenderer::Get().GetDevice());
|
||||
}
|
||||
|
||||
@@ -372,67 +381,66 @@ void RenderPipeline::Execute(PassRenderContext& ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<TextureAttachment> transitionedInputs;
|
||||
for (auto& pass : RenderPasses)
|
||||
{
|
||||
for (auto& input : pass.GetInputAttachments())
|
||||
{
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
|
||||
// Handle old and new layouts based on attachment type
|
||||
barrier.oldLayout = input.Format != ImageFormat::D32F ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
// Access masks for color or depth-stencil attachments
|
||||
if (input.Format != ImageFormat::D32F) {
|
||||
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
else {
|
||||
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
// Include stencil aspect if applicable
|
||||
//if (input.HasStencilComponent()) {
|
||||
// barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
//}
|
||||
}
|
||||
|
||||
// Destination access mask is always for shaders reading
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
// No queue family ownership transfer in this case
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
|
||||
// Set the image and subresource range
|
||||
barrier.image = input.Image->GetImage();
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
// Choose appropriate source pipeline stage for color or depth-stencil
|
||||
VkPipelineStageFlags srcStage = (input.Format != ImageFormat::D32F)
|
||||
? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
: (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||
|
||||
// Insert the pipeline barrier
|
||||
vkCmdPipelineBarrier(
|
||||
ctx.commandBuffer,
|
||||
srcStage, // Source stage
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // Destination stage
|
||||
0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier
|
||||
);
|
||||
//for (auto& input : pass.GetInputAttachments())
|
||||
//{
|
||||
// VkImageMemoryBarrier barrier{};
|
||||
// barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
//
|
||||
// // Handle old and new layouts based on attachment type
|
||||
// barrier.oldLayout = input.Format != ImageFormat::D32F ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
// barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
//
|
||||
// // Access masks for color or depth-stencil attachments
|
||||
// if (input.Format != ImageFormat::D32F) {
|
||||
// barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
// barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
// }
|
||||
// else {
|
||||
// barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
// barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
//
|
||||
// // Include stencil aspect if applicable
|
||||
// //if (input.HasStencilComponent()) {
|
||||
// // barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
// //}
|
||||
// }
|
||||
//
|
||||
// // Destination access mask is always for shaders reading
|
||||
// barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
//
|
||||
// // No queue family ownership transfer in this case
|
||||
// barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
// barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
//
|
||||
// // Set the image and subresource range
|
||||
// barrier.image = input.Image->GetImage();
|
||||
// barrier.subresourceRange.baseMipLevel = 0;
|
||||
// barrier.subresourceRange.levelCount = 1;
|
||||
// barrier.subresourceRange.baseArrayLayer = 0;
|
||||
// barrier.subresourceRange.layerCount = 1;
|
||||
//
|
||||
// // Choose appropriate source pipeline stage for color or depth-stencil
|
||||
// VkPipelineStageFlags srcStage = (input.Format != ImageFormat::D32F)
|
||||
// ? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
// : (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||
//
|
||||
// // Insert the pipeline barrier
|
||||
// vkCmdPipelineBarrier(
|
||||
// ctx.commandBuffer,
|
||||
// srcStage, // Source stage
|
||||
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // Destination stage
|
||||
// 0,
|
||||
// 0, nullptr,
|
||||
// 0, nullptr,
|
||||
// 1, &barrier
|
||||
// );
|
||||
|
||||
transitionedInputs.push_back(input);
|
||||
}
|
||||
// transitionedInputs.push_back(input);
|
||||
//}
|
||||
|
||||
pass.ClearAttachments(ctx);
|
||||
pass.TransitionAttachments(ctx);
|
||||
@@ -443,6 +451,7 @@ void RenderPipeline::Execute(PassRenderContext& ctx)
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (auto& transitionedOutputs : transitionedInputs)
|
||||
{
|
||||
if (transitionedOutputs.Format == ImageFormat::D32F)
|
||||
@@ -454,5 +463,6 @@ void RenderPipeline::Execute(PassRenderContext& ctx)
|
||||
VulkanUtil::TransitionImage(ctx.commandBuffer, transitionedOutputs.Image->GetImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Nuake
|
||||
{
|
||||
private:
|
||||
std::string Name;
|
||||
bool HasDepthTest = true;
|
||||
Ref<VulkanShader> VertShader;
|
||||
Ref<VulkanShader> FragShader;
|
||||
|
||||
@@ -77,6 +78,7 @@ namespace Nuake
|
||||
void Render(PassRenderContext& ctx);
|
||||
|
||||
public:
|
||||
void SetDepthTest(bool enabled) { HasDepthTest = enabled; }
|
||||
std::string GetName() const { return Name; }
|
||||
TextureAttachment& AddAttachment(const std::string& name, ImageFormat format, ImageUsage usage = ImageUsage::Default);
|
||||
TextureAttachment& GetAttachment(const std::string& name);
|
||||
|
||||
@@ -211,18 +211,15 @@ void PipelineBuilder::EnableBlendingAdditive()
|
||||
|
||||
void PipelineBuilder::EnableBlendingAlphaBlend(size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState colorBlend = {};
|
||||
colorBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
colorBlend.blendEnable = VK_TRUE;
|
||||
colorBlend.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
colorBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
colorBlend.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
colorBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
colorBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
colorBlend.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
VkPipelineColorBlendAttachmentState colorBlend = {};
|
||||
colorBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
colorBlend.blendEnable = VK_TRUE;
|
||||
colorBlend.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
colorBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
colorBlend.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
colorBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
colorBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
colorBlend.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
|
||||
ColorBlendAttachment.push_back(colorBlend);
|
||||
}
|
||||
ColorBlendAttachment.push_back(colorBlend);
|
||||
}
|
||||
@@ -12,12 +12,12 @@ namespace Nuake
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo InputAssembly;
|
||||
VkPipelineRasterizationStateCreateInfo Rasterizer;
|
||||
std::vector<VkPipelineColorBlendAttachmentState> ColorBlendAttachment;
|
||||
std::vector<VkPipelineColorBlendAttachmentState> ColorBlendAttachment = std::vector<VkPipelineColorBlendAttachmentState>();
|
||||
VkPipelineMultisampleStateCreateInfo Multisampling;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkPipelineDepthStencilStateCreateInfo DepthStencil;
|
||||
VkPipelineRenderingCreateInfo RenderInfo;
|
||||
std::vector<VkFormat> ColorAttachmentformats;
|
||||
std::vector<VkFormat> ColorAttachmentformats = std::vector<VkFormat>();
|
||||
|
||||
|
||||
PipelineBuilder() { Clear(); }
|
||||
|
||||
@@ -235,7 +235,7 @@ VkPipelineShaderStageCreateInfo VulkanInit::PipelineShaderStageCreateInfo(VkShad
|
||||
}
|
||||
|
||||
// This is a helper to transtion images between readable, writable layouts.
|
||||
void VulkanUtil::TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
|
||||
void VulkanUtil::TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout, bool isDepth)
|
||||
{
|
||||
VkImageMemoryBarrier2 imageBarrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
|
||||
imageBarrier.pNext = nullptr;
|
||||
@@ -247,7 +247,7 @@ void VulkanUtil::TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayo
|
||||
imageBarrier.oldLayout = currentLayout;
|
||||
imageBarrier.newLayout = newLayout;
|
||||
|
||||
VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL || isDepth) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
imageBarrier.subresourceRange = VulkanInit::ImageSubResourceRange(aspectMask);
|
||||
imageBarrier.image = image;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Nuake
|
||||
VulkanUtil() = delete;
|
||||
~VulkanUtil() = delete;
|
||||
|
||||
static void TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout);
|
||||
static void TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout, bool isDepth = false);
|
||||
static void CopyImageToImage(VkCommandBuffer cmd, VkImage source, VkImage destination, Vector2 srcSize, Vector2 dstSize);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -136,8 +136,8 @@ void VkRenderer::Initialize()
|
||||
|
||||
InitDescriptors();
|
||||
|
||||
InitPipeline();
|
||||
InitTrianglePipeline();
|
||||
//InitPipeline();
|
||||
//InitTrianglePipeline();
|
||||
|
||||
InitImgui();
|
||||
|
||||
@@ -204,13 +204,14 @@ void VkRenderer::SelectGPU()
|
||||
VkPhysicalDeviceVulkan13Features features{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES };
|
||||
features.dynamicRendering = true;
|
||||
features.synchronization2 = true;
|
||||
|
||||
VkPhysicalDeviceVulkan12Features features12{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
|
||||
features12.bufferDeviceAddress = true;
|
||||
features12.descriptorIndexing = true;
|
||||
features12.runtimeDescriptorArray = true;
|
||||
|
||||
std::vector<const char*> requiredExtensions = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME };
|
||||
|
||||
|
||||
vkb::PhysicalDeviceSelector selector{ VkbInstance };
|
||||
vkb::PhysicalDevice physicalDevice = selector
|
||||
.set_minimum_version(1, 3)
|
||||
@@ -359,7 +360,7 @@ void VkRenderer::InitDescriptors()
|
||||
{
|
||||
DescriptorLayoutBuilder builder;
|
||||
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
CameraBufferDescriptorLayout = builder.Build(Device, VK_SHADER_STAGE_VERTEX_BIT);
|
||||
CameraBufferDescriptorLayout = builder.Build(Device, VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||
}
|
||||
|
||||
// Triangle vertex buffer layout
|
||||
@@ -727,7 +728,9 @@ void VkRenderer::InitImgui()
|
||||
|
||||
void VkRenderer::BeginScene(const Matrix4& view, const Matrix4& projection)
|
||||
{
|
||||
CameraData newData = { view, projection };
|
||||
Matrix4 proj = projection;
|
||||
//proj[1][1] *= -1.0f;
|
||||
CameraData newData = { view, projection, glm::inverse(view), glm::inverse(proj)};
|
||||
//UploadCameraData(newData);
|
||||
SceneRenderer->UpdateCameraData(newData);
|
||||
}
|
||||
@@ -769,8 +772,8 @@ bool VkRenderer::Draw()
|
||||
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// Execute compute shader that writes to the image
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, Pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, PipelineLayout, 0, 1, &DrawImageDescriptors, 0, nullptr);
|
||||
//vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, Pipeline);
|
||||
//vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, PipelineLayout, 0, 1, &DrawImageDescriptors, 0, nullptr);
|
||||
|
||||
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
//vkCmdDispatch(cmd, std::ceil(DrawExtent.width / 16.0), std::ceil(DrawExtent.height / 16.0), 1);
|
||||
|
||||
@@ -119,6 +119,8 @@ namespace Nuake
|
||||
{
|
||||
Matrix4 View;
|
||||
Matrix4 Projection;
|
||||
Matrix4 InvView;
|
||||
Matrix4 InvProjection;
|
||||
};
|
||||
|
||||
// Renderer configuration
|
||||
@@ -257,7 +259,7 @@ namespace Nuake
|
||||
void ImmediateSubmit(std::function<void(VkCommandBuffer cmd)>&& function);
|
||||
|
||||
void UploadCameraData(const CameraData& data);
|
||||
|
||||
auto& GetRenderPipeline() { return this->SceneRenderer->GetRenderPipeline(); }
|
||||
VkDescriptorSet GetViewportDescriptor() const { return DrawImageDescriptors; }
|
||||
Ref<VulkanImage> GetDrawImage() const { return DrawImage; }
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ void GPUResources::CreateBindlessLayout()
|
||||
{
|
||||
DescriptorLayoutBuilder builder;
|
||||
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
CameraDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT);
|
||||
CameraDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -216,7 +216,12 @@ std::vector<VkDescriptorSetLayout> GPUResources::GetBindlessLayout()
|
||||
return layouts;
|
||||
}
|
||||
|
||||
uint32_t GPUResources::GetBindlessTextureID(const UUID & id)
|
||||
uint32_t GPUResources::GetBindlessTextureID(const UUID& id)
|
||||
{
|
||||
return 0;
|
||||
if (BindlessTextureMapping.find(id) == BindlessTextureMapping.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BindlessTextureMapping[id];
|
||||
}
|
||||
|
||||
@@ -44,14 +44,16 @@ void VkSceneRenderer::Init()
|
||||
MeshMaterialMapping.clear();
|
||||
|
||||
std::vector<Vertex> quadVertices = {
|
||||
{{-1.0f, -1.0f, 0.0f }, 0.0f, {}, 0.0f },
|
||||
{{ 1.0f, -1.0f, 0.0f }, 1.0f, {}, 0.0f },
|
||||
{{ 1.0f, 1.0f, 0.0f }, 1.0f, {}, 1.0f },
|
||||
{{-1.0f, 1.0f, 0.0f }, 0.0f, {}, 1.0f }
|
||||
{ Vector3(-1.0f, 1.0f, 1.0f), 0.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
|
||||
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
|
||||
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
|
||||
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
|
||||
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
|
||||
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) }
|
||||
};
|
||||
|
||||
std::vector<uint32_t> quadIndices = {
|
||||
0, 1, 2, 2, 3, 0
|
||||
5, 4, 3, 2, 1, 0
|
||||
};
|
||||
|
||||
quadMesh = CreateRef<VkMesh>(quadVertices, quadIndices);
|
||||
@@ -87,6 +89,7 @@ void VkSceneRenderer::BeginScene(RenderContext inContext)
|
||||
GBufferPipeline.Execute(passCtx);
|
||||
}
|
||||
ModelPushConstant modelPushConstant{};
|
||||
ShadingPushConstant shadingPushConstant;
|
||||
|
||||
void VkSceneRenderer::EndScene()
|
||||
{
|
||||
@@ -94,10 +97,13 @@ void VkSceneRenderer::EndScene()
|
||||
auto& cmd = Context.CommandBuffer;
|
||||
|
||||
auto& albedo = GBufferPipeline.GetRenderPass("GBuffer").GetAttachment("Albedo");
|
||||
auto& normal = GBufferPipeline.GetRenderPass("GBuffer").GetAttachment("Normal");
|
||||
VulkanUtil::TransitionImage(cmd, albedo.Image->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
VulkanUtil::TransitionImage(cmd, normal.Image->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
VulkanUtil::TransitionImage(cmd, vk.DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VulkanUtil::CopyImageToImage(cmd, albedo.Image->GetImage(), vk.GetDrawImage()->GetImage(), albedo.Image->GetSize(), vk.DrawImage->GetSize());
|
||||
VulkanUtil::CopyImageToImage(cmd, normal.Image->GetImage(), vk.GetDrawImage()->GetImage(), albedo.Image->GetSize(), vk.DrawImage->GetSize());
|
||||
VulkanUtil::TransitionImage(cmd, vk.DrawImage->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||
VulkanUtil::TransitionImage(cmd, normal.Image->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||
VulkanUtil::TransitionImage(cmd, albedo.Image->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
|
||||
@@ -106,6 +112,8 @@ void VkSceneRenderer::CreateBuffers()
|
||||
CameraData camData{};
|
||||
camData.View = Matrix4(1.0f);
|
||||
camData.Projection = Matrix4(1.0f);
|
||||
camData.InvView = Matrix4(1.0f);
|
||||
camData.InvProjection = Matrix4(1.0f);
|
||||
|
||||
// init camera buffer
|
||||
GPUResources& resources = GPUResources::Get();
|
||||
@@ -149,7 +157,7 @@ void VkSceneRenderer::CreateDescriptors()
|
||||
{
|
||||
DescriptorLayoutBuilder builder;
|
||||
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
CameraBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT);
|
||||
CameraBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -241,7 +249,6 @@ void VkSceneRenderer::CreateDescriptors()
|
||||
void VkSceneRenderer::CreatePipelines()
|
||||
{
|
||||
GBufferPipeline = RenderPipeline();
|
||||
|
||||
auto& gBufferPass = GBufferPipeline.AddPass("GBuffer");
|
||||
gBufferPass.SetShaders(Shaders["basic_vert"], Shaders["basic_frag"]);
|
||||
gBufferPass.AddAttachment("Albedo", ImageFormat::RGBA8);
|
||||
@@ -249,7 +256,6 @@ void VkSceneRenderer::CreatePipelines()
|
||||
gBufferPass.AddAttachment("Material", ImageFormat::RGBA8);
|
||||
gBufferPass.AddAttachment("Depth", ImageFormat::D32F, ImageUsage::Depth);
|
||||
gBufferPass.SetPushConstant<ModelPushConstant>(modelPushConstant);
|
||||
|
||||
gBufferPass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
std::vector<VkDescriptorSet> descriptors2 = { CameraBufferDescriptors, ModelBufferDescriptor };
|
||||
vkCmdBindDescriptorSets(
|
||||
@@ -287,9 +293,7 @@ void VkSceneRenderer::CreatePipelines()
|
||||
);
|
||||
|
||||
vkCmdBindDescriptorSets(ctx.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, &SamplerDescriptor, 0, nullptr);
|
||||
|
||||
});
|
||||
|
||||
gBufferPass.SetRender([&](PassRenderContext& ctx){
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
auto& scene = ctx.scene;
|
||||
@@ -349,14 +353,16 @@ void VkSceneRenderer::CreatePipelines()
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
auto& shadingPass = GBufferPipeline.AddPass("Shading");
|
||||
shadingPass.SetShaders(Shaders["shading_vert"], Shaders["shading_frag"]);
|
||||
shadingPass.SetPushConstant<ModelPushConstant>(modelPushConstant);
|
||||
shadingPass.AddAttachment("Output", ImageFormat::RGBA16F);
|
||||
shadingPass.AddAttachment("DepthShading", ImageFormat::D32F, ImageUsage::Depth);
|
||||
shadingPass.AddInput("Albedo"); // We need to sync those
|
||||
|
||||
|
||||
shadingPass.SetPushConstant<ShadingPushConstant>(shadingPushConstant);
|
||||
shadingPass.AddAttachment("Output", ImageFormat::RGBA8);
|
||||
shadingPass.SetDepthTest(false);
|
||||
shadingPass.AddInput("Albedo");
|
||||
shadingPass.AddInput("Normal");
|
||||
//shadingPass.AddInput("Depth");
|
||||
shadingPass.AddInput("Material");
|
||||
shadingPass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
std::vector<VkDescriptorSet> descriptors2 = { CameraBufferDescriptors, ModelBufferDescriptor };
|
||||
vkCmdBindDescriptorSets(
|
||||
@@ -395,19 +401,22 @@ void VkSceneRenderer::CreatePipelines()
|
||||
nullptr // dynamicOffsets
|
||||
);
|
||||
|
||||
auto& gpu = GPUResources::Get();
|
||||
auto& gbufferPass = GBufferPipeline.GetRenderPass("GBuffer");
|
||||
shadingPushConstant.AlbedoTextureID = gpu.GetBindlessTextureID(gbufferPass.GetAttachment("Albedo").Image->GetID());
|
||||
shadingPushConstant.DepthTextureID = gpu.GetBindlessTextureID(gbufferPass.GetDepthAttachment().Image->GetID());
|
||||
shadingPushConstant.NormalTextureID = gpu.GetBindlessTextureID(gbufferPass.GetAttachment("Normal").Image->GetID());
|
||||
shadingPushConstant.MaterialTextureID = gpu.GetBindlessTextureID(gbufferPass.GetAttachment("Material").Image->GetID());
|
||||
|
||||
});
|
||||
shadingPass.SetRender([](PassRenderContext& ctx) {
|
||||
|
||||
modelPushConstant.Index = 0;
|
||||
modelPushConstant.MaterialIndex = 0;
|
||||
|
||||
vkCmdPushConstants(
|
||||
ctx.commandBuffer,
|
||||
ctx.renderPass->PipelineLayout,
|
||||
VK_SHADER_STAGE_ALL_GRAPHICS, // Stage matching the pipeline layout
|
||||
0, // Offset
|
||||
sizeof(ModelPushConstant), // Size of the push constant
|
||||
&modelPushConstant // Pointer to the value
|
||||
sizeof(ShadingPushConstant), // Size of the push constant
|
||||
&shadingPushConstant // Pointer to the value
|
||||
);
|
||||
|
||||
auto descSet = quadMesh->GetDescriptorSet();
|
||||
@@ -425,7 +434,7 @@ void VkSceneRenderer::CreatePipelines()
|
||||
vkCmdBindIndexBuffer(ctx.commandBuffer, quadMesh->GetIndexBuffer()->GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(ctx.commandBuffer, quadMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t), 1, 0, 0, 0);
|
||||
});
|
||||
|
||||
*/
|
||||
GBufferPipeline.Build();
|
||||
}
|
||||
|
||||
@@ -439,7 +448,8 @@ void VkSceneRenderer::UpdateCameraData(const CameraData& data)
|
||||
CameraData adjustedData = data;
|
||||
adjustedData.View = data.View;
|
||||
adjustedData.Projection = data.Projection;
|
||||
|
||||
adjustedData.InvView = data.InvView;
|
||||
adjustedData.InvProjection = data.InvProjection;
|
||||
void* mappedData;
|
||||
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().CameraStagingBuffer->GetAllocation()), &mappedData);
|
||||
memcpy(mappedData, &adjustedData, sizeof(CameraData));
|
||||
|
||||
@@ -25,6 +25,14 @@ namespace Nuake
|
||||
char padding[120]; // 124 bytes to reach 128 bytes
|
||||
};
|
||||
|
||||
struct ShadingPushConstant
|
||||
{
|
||||
int AlbedoTextureID;
|
||||
int DepthTextureID;
|
||||
int NormalTextureID;
|
||||
int MaterialTextureID;
|
||||
};
|
||||
|
||||
struct ModelData
|
||||
{
|
||||
std::array<Matrix4, 3000> Data;
|
||||
@@ -111,6 +119,8 @@ namespace Nuake
|
||||
void BeginScene(RenderContext inContext);
|
||||
void EndScene();
|
||||
|
||||
RenderPipeline& GetRenderPipeline() { return GBufferPipeline; }
|
||||
|
||||
private:
|
||||
void LoadShaders();
|
||||
void CreateBuffers();
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
struct Camera
|
||||
{
|
||||
float4x4 view;
|
||||
float4x4 proj;
|
||||
float4x4 invView;
|
||||
float4x4 invProj;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<Camera> camera : register(t0);
|
||||
|
||||
[[vk::binding(0, 3)]]
|
||||
SamplerState mySampler : register(s0); // Sampler binding at slot s0
|
||||
|
||||
@@ -20,29 +30,149 @@ StructuredBuffer<Material> material;
|
||||
Texture2D textures[]; // Array de 500 textures
|
||||
|
||||
struct PSInput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
float4x4 InvProj : TEXCOORD1;
|
||||
float4x4 InvView : TEXCOORD2;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct ModelPushConstant
|
||||
struct ShadingPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int AlbedoInputTextureId;
|
||||
int DepthInputTextureId;
|
||||
int NormalInputTextureId;
|
||||
int MaterialInputTextureId;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
ShadingPushConstant pushConstants;
|
||||
|
||||
float3 WorldPosFromDepth(float depth, float2 uv, float4x4 invProj, float4x4 invView)
|
||||
{
|
||||
float z = depth;
|
||||
float4 clipSpacePosition = float4(uv.x * 2.0 - 1.0, (uv.y * 2.0 - 1.0), z, 1.0f);
|
||||
float4 viewSpacePosition = mul(invProj, clipSpacePosition);
|
||||
viewSpacePosition /= viewSpacePosition.w;
|
||||
|
||||
float4 worldSpacePosition = mul(invView, viewSpacePosition);
|
||||
return worldSpacePosition.xyz;
|
||||
}
|
||||
|
||||
float LinearizeDepth(float depth, float nearPlane, float farPlane, bool reverseDepth)
|
||||
{
|
||||
if (reverseDepth)
|
||||
{
|
||||
// Reverse depth (near plane = 1.0, far plane = 0.0)
|
||||
return nearPlane * farPlane / lerp(farPlane, nearPlane, depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard depth (near plane = 0.0, far plane = 1.0)
|
||||
return (2.0 * nearPlane * farPlane) / (farPlane + nearPlane - depth * (farPlane - nearPlane));
|
||||
}
|
||||
}
|
||||
|
||||
const float PI = 3.141592653589793f;
|
||||
float DistributionGGX(float3 N, float3 H, float a)
|
||||
{
|
||||
float a2 = a * a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH * NdotH;
|
||||
|
||||
float nom = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float k)
|
||||
{
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float GeometrySmith(float3 N, float3 V, float3 L, float k)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx1 = GeometrySchlickGGX(NdotV, k);
|
||||
float ggx2 = GeometrySchlickGGX(NdotL, k);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float3 fresnelSchlick(float cosTheta, float3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
|
||||
}
|
||||
|
||||
float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
||||
{
|
||||
float roughnessTerm = 1.0f - roughness;
|
||||
return F0 + (max(float3(roughnessTerm, roughnessTerm, roughnessTerm), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
Camera camData = camera[0];
|
||||
int depthTexture = pushConstants.DepthInputTextureId;
|
||||
float depth = textures[depthTexture].Sample(mySampler, input.UV).r;
|
||||
|
||||
output.oColor0 = float4(1, 0, 0, 1);
|
||||
float3 worldPosition = WorldPosFromDepth(depth, input.UV, camData.invProj, camData.invView);
|
||||
|
||||
int albedoTextureId = pushConstants.AlbedoInputTextureId;
|
||||
float3 albedo = textures[albedoTextureId].Sample(mySampler, input.UV).xyz;
|
||||
float3 normal = textures[pushConstants.NormalInputTextureId].Sample(mySampler, input.UV).rgb;
|
||||
|
||||
output.oColor0 = float4(normal, 1);
|
||||
return output;
|
||||
|
||||
float4 materialSample = textures[pushConstants.MaterialInputTextureId].Sample(mySampler, input.UV);
|
||||
float metallic = materialSample.r;
|
||||
float ao = materialSample.g;
|
||||
float roughness = materialSample.b;
|
||||
|
||||
float3 eyePosition = camData.view[3].xyz;
|
||||
float3 N = normal;
|
||||
float3 V = normalize(eyePosition - worldPosition);
|
||||
float3 R = reflect(-V, N);
|
||||
float3 F0 = float3(0.04, 0.04, 0.04);
|
||||
F0 = lerp(F0, albedo, metallic);
|
||||
|
||||
float3 Lo = float3(0.0, 0.0, 0.0);
|
||||
|
||||
// Directional light
|
||||
float3 dir = normalize(float3(0.1, -1.0, 0.1f));
|
||||
float attenuation = 1.0f;
|
||||
|
||||
float3 L = dir;
|
||||
float3 radiance = float3(1, 1, 1) * attenuation;
|
||||
float3 H = normalize(V + L);
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
float3 nominator = NDF * G * F;
|
||||
float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; // 0.001 to prevent divide by zero.
|
||||
float3 specular = nominator / denominator;
|
||||
|
||||
float3 kS = F;
|
||||
float3 kD = float3(1.0, 1.0, 1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
|
||||
|
||||
float3 ambient = (albedo) * ao * 0.5f;
|
||||
float3 color = (ambient) + Lo;
|
||||
|
||||
output.oColor0 = float4(ambient, 1);
|
||||
return output;
|
||||
}
|
||||
@@ -2,6 +2,8 @@ struct Camera
|
||||
{
|
||||
float4x4 view;
|
||||
float4x4 proj;
|
||||
float4x4 invView;
|
||||
float4x4 invProj;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<Camera> camera : register(t0);
|
||||
@@ -26,73 +28,32 @@ struct Vertex
|
||||
[[vk::binding(0, 2)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
struct ModelPushConstant
|
||||
struct ShadingPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int AlbedoInputTextureId;
|
||||
int DepthInputTextureId;
|
||||
int NormalInputTextureId;
|
||||
int MaterialInputTextureId;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
ShadingPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
float4x4 InvProj : TEXCOORD1;
|
||||
float4x4 InvView : TEXCOORD2;
|
||||
};
|
||||
|
||||
float4x4 inverse(float4x4 m) {
|
||||
float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0];
|
||||
float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1];
|
||||
float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2];
|
||||
float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3];
|
||||
|
||||
float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44;
|
||||
float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44;
|
||||
float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44;
|
||||
float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
|
||||
|
||||
float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
|
||||
float idet = 1.0f / det;
|
||||
|
||||
float4x4 ret;
|
||||
|
||||
ret[0][0] = t11 * idet;
|
||||
ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet;
|
||||
ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet;
|
||||
ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet;
|
||||
|
||||
ret[1][0] = t12 * idet;
|
||||
ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet;
|
||||
ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet;
|
||||
ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet;
|
||||
|
||||
ret[2][0] = t13 * idet;
|
||||
ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet;
|
||||
ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet;
|
||||
ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet;
|
||||
|
||||
ret[3][0] = t14 * idet;
|
||||
ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet;
|
||||
ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet;
|
||||
ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Camera camData = camera[0];
|
||||
output.InvProj = inverse(camData.proj);
|
||||
output.InvView = inverse(camData.view);
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -1,3 +1,13 @@
|
||||
struct Camera
|
||||
{
|
||||
float4x4 view;
|
||||
float4x4 proj;
|
||||
float4x4 invView;
|
||||
float4x4 invProj;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<Camera> camera : register(t0);
|
||||
|
||||
[[vk::binding(0, 3)]]
|
||||
SamplerState mySampler : register(s0); // Sampler binding at slot s0
|
||||
|
||||
@@ -63,7 +73,7 @@ PSOutput main(PSInput input)
|
||||
|
||||
normal = mul(input.TBN, normal);
|
||||
normal = normal / 2.0f + 0.5f;
|
||||
output.oNormal = float4(normal, 1.0f);
|
||||
output.oNormal = float4(float3(1, 0, 0), 1.0f);
|
||||
|
||||
// MATERIAL
|
||||
|
||||
@@ -82,7 +92,7 @@ PSOutput main(PSInput input)
|
||||
albedoColor.xyz = albedoSample.xyz;
|
||||
}
|
||||
output.oColor0 = albedoColor;
|
||||
|
||||
output.oColor0 = float4(normal, 1.0);
|
||||
// MATERIAL PROPERTIES
|
||||
float metalnessValue = inMaterial.metalnessValue;
|
||||
if(inMaterial.hasMetalness == 1)
|
||||
|
||||
@@ -2,6 +2,8 @@ struct Camera
|
||||
{
|
||||
float4x4 view;
|
||||
float4x4 proj;
|
||||
float4x4 invView;
|
||||
float4x4 invProj;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<Camera> camera : register(t0);
|
||||
@@ -65,6 +67,6 @@ VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
float3 T = normalize(mul((float3x3)modelData.model, normalize(v.tangent.xyz)));
|
||||
float3 B = normalize(mul((float3x3)modelData.model, normalize(v.bitangent.xyz)));
|
||||
float3 N = normalize(mul((float3x3)modelData.model, normalize(v.normal)).xyz);
|
||||
output.TBN = transpose(float3x3(T, B, N));
|
||||
output.TBN = float3x3(T, B, N);
|
||||
return output;
|
||||
}
|
||||
Reference in New Issue
Block a user