Triangle in render texture

This commit is contained in:
antopilo
2024-12-07 21:48:59 -05:00
parent cd2e603733
commit 29130dde7f
15 changed files with 554 additions and 21 deletions

View File

@@ -0,0 +1,164 @@
#include "PipelineBuilder.h"
#include "src/Core/Logger.h"
#include "src/Rendering/Vulkan/VulkanInit.h"
using namespace Nuake;
void PipelineBuilder::Clear()
{
InputAssembly = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
Rasterizer = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
ColorBlendAttachment = {};
Multisampling = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
PipelineLayout = {};
DepthStencil = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
RenderInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO };
ShaderStages.clear();
}
VkPipeline PipelineBuilder::BuildPipeline(VkDevice device)
{
// make viewport state from our stored viewport and scissor.
// at the moment we wont support multiple viewports or scissors
VkPipelineViewportStateCreateInfo viewportState = {};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.pNext = nullptr;
viewportState.viewportCount = 1;
viewportState.scissorCount = 1;
// setup dummy color blending. We arent using transparent objects yet
// the blending is just "no blend", but we do write to the color attachment
VkPipelineColorBlendStateCreateInfo colorBlending = {};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.pNext = nullptr;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &ColorBlendAttachment;
// completely clear VertexInputStateCreateInfo, as we have no need for it
VkPipelineVertexInputStateCreateInfo _vertexInputInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
// build the actual pipeline
// we now use all of the info structs we have been writing into into this one
// to create the pipeline
VkGraphicsPipelineCreateInfo pipelineInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
// connect the renderInfo to the pNext extension mechanism
pipelineInfo.pNext = &RenderInfo;
pipelineInfo.stageCount = (uint32_t)ShaderStages.size();
pipelineInfo.pStages = ShaderStages.data();
pipelineInfo.pVertexInputState = &_vertexInputInfo;
pipelineInfo.pInputAssemblyState = &InputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &Rasterizer;
pipelineInfo.pMultisampleState = &Multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDepthStencilState = &DepthStencil;
pipelineInfo.layout = PipelineLayout;
VkDynamicState state[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo dynamicInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
dynamicInfo.pDynamicStates = &state[0];
dynamicInfo.dynamicStateCount = 2;
pipelineInfo.pDynamicState = &dynamicInfo;
// its easy to error out on create graphics pipeline, so we handle it a bit
// better than the common VK_CHECK case
VkPipeline newPipeline;
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &newPipeline) != VK_SUCCESS)
{
Logger::Log("Failed to create graphics pipeline", "vulkan", CRITICAL);
return VK_NULL_HANDLE; // failed to create graphics pipeline
}
return newPipeline;
}
void PipelineBuilder::SetShaders(VkShaderModule vert, VkShaderModule frag)
{
ShaderStages.clear();
ShaderStages.push_back(VulkanInit::PipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, vert));
ShaderStages.push_back(VulkanInit::PipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, frag));
}
void PipelineBuilder::SetInputTopology(VkPrimitiveTopology topology)
{
InputAssembly.topology = topology;
// we are not going to use primitive restart on the entire tutorial so leave
// it on false
InputAssembly.primitiveRestartEnable = VK_FALSE;
}
void PipelineBuilder::SetPolygonMode(VkPolygonMode polygonMode)
{
Rasterizer.polygonMode = polygonMode;
Rasterizer.lineWidth = 1.f;
}
void PipelineBuilder::SetCullMode(VkCullModeFlags cullMode, VkFrontFace frontFace)
{
Rasterizer.cullMode = cullMode;
Rasterizer.frontFace = frontFace;
}
void PipelineBuilder::SetMultiSamplingNone()
{
Multisampling.sampleShadingEnable = VK_FALSE;
// multisampling defaulted to no multisampling (1 sample per pixel)
Multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
Multisampling.minSampleShading = 1.0f;
Multisampling.pSampleMask = nullptr;
// no alpha to coverage either
Multisampling.alphaToCoverageEnable = VK_FALSE;
Multisampling.alphaToOneEnable = VK_FALSE;
}
void PipelineBuilder::DisableBlending()
{
// default write mask
ColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
// no blending
ColorBlendAttachment.blendEnable = VK_FALSE;
}
void PipelineBuilder::SetColorAttachment(VkFormat format)
{
ColorAttachmentformat = format;
// connect the format to the renderInfo structure
RenderInfo.colorAttachmentCount = 1;
RenderInfo.pColorAttachmentFormats = &ColorAttachmentformat;
}
void PipelineBuilder::SetDepthFormat(VkFormat depthFormat)
{
RenderInfo.depthAttachmentFormat = depthFormat;
}
void PipelineBuilder::DisableDepthTest()
{
DepthStencil.depthTestEnable = VK_FALSE;
DepthStencil.depthWriteEnable = VK_FALSE;
DepthStencil.depthCompareOp = VK_COMPARE_OP_NEVER;
DepthStencil.depthBoundsTestEnable = VK_FALSE;
DepthStencil.stencilTestEnable = VK_FALSE;
DepthStencil.front = {};
DepthStencil.back = {};
DepthStencil.minDepthBounds = 0.f;
DepthStencil.maxDepthBounds = 1.f;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <volk/volk.h>
#include <vector>
namespace Nuake
{
class PipelineBuilder
{
public:
std::vector<VkPipelineShaderStageCreateInfo> ShaderStages;
VkPipelineInputAssemblyStateCreateInfo InputAssembly;
VkPipelineRasterizationStateCreateInfo Rasterizer;
VkPipelineColorBlendAttachmentState ColorBlendAttachment;
VkPipelineMultisampleStateCreateInfo Multisampling;
VkPipelineLayout PipelineLayout;
VkPipelineDepthStencilStateCreateInfo DepthStencil;
VkPipelineRenderingCreateInfo RenderInfo;
VkFormat ColorAttachmentformat;
PipelineBuilder() { Clear(); }
~PipelineBuilder() = default;
void Clear();
VkPipeline BuildPipeline(VkDevice device);
void SetShaders(VkShaderModule vert, VkShaderModule frag);
void SetInputTopology(VkPrimitiveTopology topology);
void SetPolygonMode(VkPolygonMode polygonMode);
void SetCullMode(VkCullModeFlags cullMode, VkFrontFace frontFace);
void SetMultiSamplingNone();
void DisableBlending();
void SetColorAttachment(VkFormat format);
void SetDepthFormat(VkFormat depthFormat);
void DisableDepthTest();
};
}

View File

@@ -0,0 +1,33 @@
#include "VulkanAllocatedBuffer.h"
#include "VulkanAllocator.h"
#include "VulkanCheck.h"
#include "VulkanRenderer.h"
using namespace Nuake;
#include "vk_mem_alloc.h"
AllocatedBuffer::AllocatedBuffer(size_t inSize, VkBufferUsageFlags inFlags, VmaMemoryUsage inUsage)
{
// allocate buffer
VkBufferCreateInfo bufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.pNext = nullptr;
bufferInfo.size = inSize;
bufferInfo.usage = inFlags;
VmaAllocationCreateInfo vmaallocInfo = {};
vmaallocInfo.usage = inUsage;
vmaallocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
// allocate the buffer
VK_CALL(vmaCreateBuffer(VulkanAllocator::Get().GetAllocator(), &bufferInfo, &vmaallocInfo, &Buffer, &Allocation,
&Info));
}
AllocatedBuffer::~AllocatedBuffer()
{
// TODO: deletion of buffer
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include "src/Core/Maths.h"
#include <volk/volk.h>
#include <vk_mem_alloc.h>
namespace Nuake
{
class AllocatedBuffer
{
private:
VkBuffer Buffer;
VmaAllocation Allocation;
VmaAllocationInfo Info;
public:
AllocatedBuffer(size_t size, VkBufferUsageFlags flags, VmaMemoryUsage usage);
~AllocatedBuffer();
};
struct GPUMeshBuffers
{
AllocatedBuffer indexBuffer;
AllocatedBuffer vertexBuffer;
VkDeviceAddress vertexBufferAddress;
};
// push constants for our mesh object draws
struct GPUDrawPushConstants
{
glm::mat4 worldMatrix;
VkDeviceAddress vertexBuffer;
};
}

View File

@@ -10,6 +10,7 @@
using namespace Nuake;
#include "vk_mem_alloc.h"
VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize) :
Format(inFormat),
@@ -48,6 +49,11 @@ VulkanImage::VulkanImage(void* inData, ImageFormat inFormat, Vector2 inSize)
}
VulkanImage::~VulkanImage()
{
// TODO: deletion of image
}
VkDescriptorSet& VulkanImage::GetImGuiDescriptorSet()
{
if (!ImGuiDescriptorSetGenerated)

View File

@@ -42,11 +42,12 @@ namespace Nuake
public:
VulkanImage(ImageFormat format, Vector2 size);
VulkanImage(void* data, ImageFormat format, Vector2 size);
~VulkanImage() = default;
~VulkanImage();
Vector2 GetSize() const { return Vector2(Extent.x, Extent.y); }
VkImageView& GetImageView() { return ImageView; }
VkImage& GetImage() { return Image; }
VkDescriptorSet& GetImGuiDescriptorSet();
ImageFormat GetFormat() const { return Format; }
};
}

View File

@@ -90,7 +90,7 @@ VkCommandBufferSubmitInfo VulkanInit::CommandBufferSubmitInfo(VkCommandBuffer cm
return info;
}
VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo * cmd, VkSemaphoreSubmitInfo * signalSemaphoreInfo, VkSemaphoreSubmitInfo * waitSemaphoreInfo)
VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo * signalSemaphoreInfo, VkSemaphoreSubmitInfo * waitSemaphoreInfo)
{
VkSubmitInfo2 info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
@@ -102,7 +102,7 @@ VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo * cmd, VkSemaphor
info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1;
info.pSignalSemaphoreInfos = signalSemaphoreInfo;
info.commandBufferInfoCount = 1;
info.commandBufferInfoCount = cmd == nullptr ? 0 : 1;
info.pCommandBufferInfos = cmd;
return info;
@@ -186,6 +186,34 @@ VkRenderingInfo VulkanInit::RenderingInfo(VkExtent2D renderExtent, VkRenderingAt
return renderInfo;
}
VkPipelineLayoutCreateInfo VulkanInit::PipelineLayoutCreateInfo()
{
VkPipelineLayoutCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
info.pNext = nullptr;
// empty defaults
info.flags = 0;
info.setLayoutCount = 0;
info.pSetLayouts = nullptr;
info.pushConstantRangeCount = 0;
info.pPushConstantRanges = nullptr;
return info;
}
VkPipelineShaderStageCreateInfo VulkanInit::PipelineShaderStageCreateInfo(VkShaderStageFlagBits flags, VkShaderModule shader)
{
VkPipelineShaderStageCreateInfo info{};
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
info.pNext = nullptr;
// shader stage
info.stage = flags;
info.module = shader;
info.pName = "main";
return info;
}
// This is a helper to transtion images between readable, writable layouts.
void VulkanUtil::TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
{

View File

@@ -26,6 +26,9 @@ namespace Nuake
static VkRenderingAttachmentInfo AttachmentInfo(VkImageView view, VkClearValue* clear, VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
static VkRenderingInfo RenderingInfo(VkExtent2D renderExtent, VkRenderingAttachmentInfo * colorAttachment, VkRenderingAttachmentInfo * depthAttachment);
static VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo();
static VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(VkShaderStageFlagBits flags, VkShaderModule shader);
};
class VulkanUtil

View File

@@ -17,6 +17,7 @@
#include "VulkanAllocator.h"
#include "VulkanCheck.h"
#include "PipelineBuilder.h"
using namespace Nuake;
@@ -70,9 +71,13 @@ void VkRenderer::Initialize()
InitDescriptors();
BackgroundShader = ShaderCompiler::Get().CompileShader("../Resources/Shaders/Vulkan/background.comp");
ShaderCompiler& shaderCompiler = ShaderCompiler::Get();
TriangleVertShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.vert");
BackgroundShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/background.comp");
TriangleFragShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.frag");
InitPipeline();
InitTrianglePipeline();
InitImgui();
@@ -306,7 +311,6 @@ void VkRenderer::UpdateDescriptorSets()
drawImageWrite.pImageInfo = &imgInfo;
vkUpdateDescriptorSets(Device, 1, &drawImageWrite, 0, nullptr);
}
void VkRenderer::InitPipeline()
@@ -345,6 +349,82 @@ void VkRenderer::InitBackgroundPipeline()
});
}
void VkRenderer::InitTrianglePipeline()
{
VkPipelineLayoutCreateInfo pipeline_layout_info = VulkanInit::PipelineLayoutCreateInfo();
VK_CALL(vkCreatePipelineLayout(Device, &pipeline_layout_info, nullptr, &TrianglePipelineLayout));
PipelineBuilder pipelineBuilder;
//use the triangle layout we created
pipelineBuilder.PipelineLayout = TrianglePipelineLayout;
//connecting the vertex and pixel shaders to the pipeline
pipelineBuilder.SetShaders(TriangleVertShader->GetModule(), TriangleFragShader->GetModule());
//it will draw triangles
pipelineBuilder.SetInputTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
//filled triangles
pipelineBuilder.SetPolygonMode(VK_POLYGON_MODE_FILL);
//no backface culling
pipelineBuilder.SetCullMode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE);
//no multisampling
pipelineBuilder.SetMultiSamplingNone();
//no blending
pipelineBuilder.DisableBlending();
//no depth testing
pipelineBuilder.DisableDepthTest();
//connect the image format we will draw into, from draw image
pipelineBuilder.SetColorAttachment(static_cast<VkFormat>(DrawImage->GetFormat()));
pipelineBuilder.SetDepthFormat(VK_FORMAT_UNDEFINED);
//finally build the pipeline
TrianglePipeline = pipelineBuilder.BuildPipeline(Device);
//clean structures
//vkDestroyShaderModule(Device, Triangl, nullptr);
//vkDestroyShaderModule(Device, TriangleVertexShader, nullptr);
MainDeletionQueue.push_function([&]() {
vkDestroyPipelineLayout(Device, TrianglePipelineLayout, nullptr);
vkDestroyPipeline(Device, TrianglePipeline, nullptr);
});
}
void VkRenderer::DrawGeometry(VkCommandBuffer cmd)
{
//begin a render pass connected to our draw image
VkRenderingAttachmentInfo colorAttachment = VulkanInit::AttachmentInfo(DrawImage->GetImageView(), nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkRenderingInfo renderInfo = VulkanInit::RenderingInfo(DrawExtent, &colorAttachment, nullptr);
vkCmdBeginRendering(cmd, &renderInfo);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, TrianglePipeline);
//set dynamic viewport and scissor
VkViewport viewport = {};
viewport.x = 0;
viewport.y = 0;
viewport.width = DrawExtent.width;
viewport.height = DrawExtent.height;
viewport.minDepth = 0.f;
viewport.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &viewport);
VkRect2D scissor = {};
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = DrawExtent.width;
scissor.extent.height = DrawExtent.height;
vkCmdSetScissor(cmd, 0, 1, &scissor);
//launch a draw command to draw 3 vertices
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRendering(cmd);
}
void VkRenderer::InitImgui()
{
// 1: create descriptor pool for IMGUI
@@ -514,20 +594,16 @@ void VkRenderer::Draw()
{
VK_CALL(vkWaitForFences(Device, 1, &GetCurrentFrame().RenderFence, true, 1000000000));
//GetCurrentFrame().LocalDeletionQueue.flush();
if (SurfaceSize != Window::Get()->GetSize())
{
RecreateSwapchain();
return;
}
//request image from the swapchain
uint32_t swapchainImageIndex;
VkResult result = vkAcquireNextImageKHR(Device, Swapchain, 1000000000, GetCurrentFrame().SwapchainSemaphore, nullptr, &swapchainImageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR || SurfaceSize != Window::Get()->GetSize())
{
RecreateSwapchain();
//DestroySwapchain();
//CreateSwapchain(Window::Get()->GetSize());
return;
}
VK_CALL(vkResetFences(Device, 1, &GetCurrentFrame().RenderFence));
@@ -541,9 +617,12 @@ void VkRenderer::Draw()
DrawExtent.width = DrawImage->GetSize().x;
DrawExtent.height = DrawImage->GetSize().y;
VkCommandBufferSubmitInfo cmdinfo;
// Create commands
VK_CALL(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
{
// Transfer rendering image to general layout
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
@@ -558,14 +637,13 @@ void VkRenderer::Draw()
//VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
DrawGeometry(cmd);
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
{
}
//draw imgui into the swapchain image
DrawImgui(cmd, SwapchainImageViews[swapchainImageIndex]);
// set swapchain image layout to Attachment Optimal so we can draw it
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
@@ -577,7 +655,7 @@ void VkRenderer::Draw()
}
VK_CALL(vkEndCommandBuffer(cmd));
VkCommandBufferSubmitInfo cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
// Wait for both semaphore of swapchain and the texture of the frame.
VkSemaphoreSubmitInfo waitInfo = VulkanInit::SemaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, GetCurrentFrame().SwapchainSemaphore);

View File

@@ -161,8 +161,12 @@ namespace Nuake
VkPipeline Pipeline;
VkPipelineLayout PipelineLayout;
Ref<VulkanShader> BackgroundShader;
VkPipelineLayout TrianglePipelineLayout;
VkPipeline TrianglePipeline;
Ref<VulkanShader> BackgroundShader;
Ref<VulkanShader> TriangleVertShader;
Ref<VulkanShader> TriangleFragShader;
// Imgui
VkFence ImguiFence;
VkCommandBuffer ImguiCommandBuffer;
@@ -200,6 +204,8 @@ namespace Nuake
void UpdateDescriptorSets();
void InitPipeline();
void InitBackgroundPipeline();
void InitTrianglePipeline();
void DrawGeometry(VkCommandBuffer cmd);
void InitImgui();
void Draw();

View File

@@ -0,0 +1,32 @@
#pragma once
#include <src/Core/Maths.h>
#include "src/Rendering/Vulkan/VulkanAllocatedBuffer.h"
namespace Nuake
{
struct Vertex
{
Vector3 position;
float uv_x;
Vector3 normal;
float uv_y;
Vector4 color;
};
// holds the resources needed for a mesh
struct GPUMeshBuffers
{
AllocatedBuffer indexBuffer;
AllocatedBuffer vertexBuffer;
VkDeviceAddress vertexBufferAddress;
};
// push constants for our mesh object draws
struct GPUDrawPushConstants
{
Matrix4 worldMatrix;
VkDeviceAddress vertexBuffer;
};
}

View File

@@ -0,0 +1,28 @@
struct VSInput
{
[[vk::location(0)]] float3 Position : POSITION0;
[[vk::location(1)]] float3 Color : COLOR0;
};
struct UBO
{
float4x4 projectionMatrix;
float4x4 modelMatrix;
float4x4 viewMatrix;
};
cbuffer ubo : register(b0, space0) { UBO ubo; }
struct VSOutput
{
float4 Pos : SV_POSITION;
[[vk::location(0)]] float3 Color : COLOR0;
};
VSOutput main(VSInput input, uint VertexIndex : SV_VertexID)
{
VSOutput output = (VSOutput)0;
output.Color = input.Color * float(VertexIndex);
output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Position.xyz, 1.0))));
return output;
}

View File

@@ -0,0 +1,9 @@
struct PSInput {
float3 Color : TEXCOORD0;
};
float4 main(PSInput input) : SV_Target
{
// Return color with alpha = 1.0f
return float4(input.Color, 1.0f);
}

View File

@@ -0,0 +1,30 @@
// HLSL version for Shader Model 6.1
struct VSOutput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
};
VSOutput main(uint vertexIndex : SV_VertexID)
{
VSOutput output;
// Constant array of positions for the triangle
float3 positions[3] = {
float3(1.0f, 1.0f, 0.0f),
float3(-1.0f, 1.0f, 0.0f),
float3(0.0f, -1.0f, 0.0f)
};
// Constant array of colors for the triangle
float3 colors[3] = {
float3(1.0f, 0.0f, 0.0f), // red
float3(0.0f, 1.0f, 0.0f), // green
float3(0.0f, 0.0f, 1.0f) // blue
};
// Output the position of each vertex
output.Position = float4(positions[vertexIndex], 1.0f);
output.Color = colors[vertexIndex];
return output;
}

View File

@@ -0,0 +1,39 @@
struct Vertex
{
float3 position;
float uv_x;
float3 normal;
float uv_y;
float4 color;
};
// Define the structured buffer for vertices
StructuredBuffer<Vertex> vertexBuffer : register(t0); // Binding of vertex buffer (example: t0)
// Define push constants block
cbuffer PushConstants : register(b0) { // Push constants binding (example: b0)
float4x4 render_matrix; // Matrix for rendering
uint64_t vertexBufferAddress; // Buffer reference address (Vulkan-specific handling required)
};
// Outputs
struct VSOutput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
float2 UV : TEXCOORD1;
};
// Main vertex shader
VSOutput main(uint vertexIndex : SV_VertexID) {
VSOutput output;
// Load vertex data from the buffer
Vertex v = vertexBuffer[vertexIndex];
// Transform and output vertex data
output.Position = mul(render_matrix, float4(v.position, 1.0f));
output.Color = v.color.xyz;
output.UV = float2(v.uv_x, v.uv_y);
return output;
}