geometry shader
This commit is contained in:
parent
b7c25fc41f
commit
1ae766c648
@ -46,6 +46,7 @@ namespace collada::scene {
|
||||
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
||||
// +3: linear sampler, shadow sampled image, scene sampled image (array)
|
||||
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3;
|
||||
static constexpr int shaderVariantCount = 3;
|
||||
|
||||
// externally initialized, opaque handle
|
||||
VkInstance instance;
|
||||
|
||||
@ -169,6 +169,57 @@ float4 PSMain(VSOutput input) : SV_TARGET
|
||||
return float4(diffuseSpecular * shadowIntensity + emissionColor.xyz, 1.0);
|
||||
}
|
||||
|
||||
struct VSGeometryOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 Normal : Normal;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VSGeometryOutput VSGeometryMain(VSInput input)
|
||||
{
|
||||
VSGeometryOutput output = (VSGeometryOutput)0;
|
||||
output.Position = float4(input.Position, 1.0);
|
||||
output.Normal = input.Normal;
|
||||
return output;
|
||||
}
|
||||
|
||||
struct GSGeometryOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 Color : Color;
|
||||
};
|
||||
|
||||
[shader("geometry")]
|
||||
[maxvertexcount(6)]
|
||||
void GSGeometryMain(triangle VSGeometryOutput input[3], inout LineStream<GSGeometryOutput> outputStream)
|
||||
{
|
||||
float normalLength = 2.0;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float3 position = input[i].Position.xyz;
|
||||
float3 normal = input[i].Normal;
|
||||
float3 positionNormal = position + normal * normalLength;
|
||||
|
||||
GSGeometryOutput output = (GSGeometryOutput)0;
|
||||
output.Position = getProjection(Scene.Projection, getView(Scene.View, position));
|
||||
output.Color = float3(1, 0, 0);
|
||||
outputStream.Append(output);
|
||||
|
||||
output.Position = getProjection(Scene.Projection, getView(Scene.View, positionNormal));
|
||||
output.Color = float3(0, 1, 0);
|
||||
outputStream.Append(output);
|
||||
|
||||
outputStream.RestartStrip();
|
||||
}
|
||||
}
|
||||
|
||||
[shader("pixel")]
|
||||
float4 PSGeometryMain(GSGeometryOutput input) : SV_TARGET
|
||||
{
|
||||
return float4(input.Color, 1.0);
|
||||
}
|
||||
|
||||
[shader("vertex")]
|
||||
VSShadowOutput VSShadowMain(VSInput input)
|
||||
{
|
||||
|
||||
@ -327,13 +327,13 @@ namespace collada::scene {
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT
|
||||
},
|
||||
{
|
||||
.binding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT
|
||||
}
|
||||
};
|
||||
|
||||
@ -655,7 +655,7 @@ namespace collada::scene {
|
||||
{
|
||||
VkPushConstantRange pushConstantRanges[1]{
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT,
|
||||
.offset = 0,
|
||||
.size = (sizeof (PushConstant))
|
||||
}
|
||||
@ -690,6 +690,27 @@ namespace collada::scene {
|
||||
}
|
||||
};
|
||||
|
||||
VkPipelineShaderStageCreateInfo geometryShaderStages[3]{
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = shaderModule,
|
||||
.pName = "VSGeometryMain"
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_GEOMETRY_BIT,
|
||||
.module = shaderModule,
|
||||
.pName = "GSGeometryMain"
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = shaderModule,
|
||||
.pName = "PSGeometryMain"
|
||||
}
|
||||
};
|
||||
|
||||
VkPipelineShaderStageCreateInfo shadowShaderStages[2]{
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
@ -788,13 +809,12 @@ namespace collada::scene {
|
||||
vertexInputStates,
|
||||
vertexBindingDescriptions);
|
||||
|
||||
// piplineCount must match destroy_all
|
||||
int pipelineCount = descriptor->inputs_list_count * 2;
|
||||
int pipelineCount = descriptor->inputs_list_count * shaderVariantCount;
|
||||
VkGraphicsPipelineCreateInfo * pipelineCreateInfos = NewM<VkGraphicsPipelineCreateInfo>(pipelineCount);
|
||||
|
||||
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
||||
// shadow
|
||||
pipelineCreateInfos[i * 2 + 0] = {
|
||||
pipelineCreateInfos[i * shaderVariantCount + 0] = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = &shadowRenderingCreateInfo,
|
||||
.stageCount = 2,
|
||||
@ -811,7 +831,7 @@ namespace collada::scene {
|
||||
};
|
||||
|
||||
// non-shadow
|
||||
pipelineCreateInfos[i * 2 + 1] = {
|
||||
pipelineCreateInfos[i * shaderVariantCount + 1] = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = &renderingCreateInfo,
|
||||
.stageCount = 2,
|
||||
@ -826,6 +846,23 @@ namespace collada::scene {
|
||||
.pDynamicState = &dynamicState,
|
||||
.layout = pipelineLayout
|
||||
};
|
||||
|
||||
// geometry
|
||||
pipelineCreateInfos[i * shaderVariantCount + 2] = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = &renderingCreateInfo,
|
||||
.stageCount = 3,
|
||||
.pStages = geometryShaderStages,
|
||||
.pVertexInputState = &vertexInputStates[i],
|
||||
.pInputAssemblyState = &inputAssemblyState,
|
||||
.pViewportState = &viewportState,
|
||||
.pRasterizationState = &rasterizationState,
|
||||
.pMultisampleState = &multisampleState,
|
||||
.pDepthStencilState = &depthStencilState,
|
||||
.pColorBlendState = &colorBlendState,
|
||||
.pDynamicState = &dynamicState,
|
||||
.layout = pipelineLayout
|
||||
};
|
||||
};
|
||||
|
||||
pipelines = NewM<VkPipeline>(pipelineCount);
|
||||
@ -860,13 +897,13 @@ namespace collada::scene {
|
||||
}
|
||||
types::triangles const& triangles = mesh.triangles[instance_material.element_index];
|
||||
|
||||
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT };
|
||||
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT };
|
||||
constexpr uint32_t offset{ (offsetof (PushConstant, materialIndex)) };
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout, stageFlags, offset, (sizeof (uint32_t)), &materialIndex);
|
||||
|
||||
VkDeviceSize vertexOffset{ (VkDeviceSize)mesh.vertex_buffer_offset };
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndex.buffer, &vertexOffset);
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[triangles.inputs_index * 2 + pipelineIndex]);
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[triangles.inputs_index * shaderVariantCount + pipelineIndex]);
|
||||
|
||||
uint32_t indexCount = triangles.count * 3;
|
||||
vkCmdDrawIndexed(commandBuffer, indexCount, 1, triangles.index_offset, 0, 0);
|
||||
@ -935,7 +972,7 @@ namespace collada::scene {
|
||||
types::node const & node,
|
||||
instance_types::node const & node_instance)
|
||||
{
|
||||
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT };
|
||||
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT };
|
||||
constexpr uint32_t offset{ (offsetof (PushConstant, nodeIndex)) };
|
||||
vkCmdPushConstants(commandBuffer, pipelineLayout, stageFlags, offset, (sizeof (uint32_t)), &node_index);
|
||||
|
||||
@ -983,8 +1020,7 @@ namespace collada::scene {
|
||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts[1], nullptr);
|
||||
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||
// pipelineCount must match create_pipelines
|
||||
int pipelineCount = descriptor->inputs_list_count * 2;
|
||||
int pipelineCount = descriptor->inputs_list_count * shaderVariantCount;
|
||||
for (int i = 0; i < pipelineCount; i++) {
|
||||
vkDestroyPipeline(device, pipelines[i], nullptr);
|
||||
}
|
||||
|
||||
20
src/main.cpp
20
src/main.cpp
@ -154,6 +154,19 @@ void createDepth(VkDeviceSize nonCoherentAtomSize,
|
||||
VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, imageView));
|
||||
}
|
||||
|
||||
void createCubeDepth(VkDeviceSize nonCoherentAtomSize,
|
||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags usage,
|
||||
VkImage * image,
|
||||
VkDeviceMemory * memory,
|
||||
VkImageView * imageView)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat,
|
||||
VkFormat depthFormat,
|
||||
VkDeviceSize nonCoherentAtomSize,
|
||||
@ -402,7 +415,8 @@ int main()
|
||||
.dynamicRendering = true,
|
||||
};
|
||||
VkPhysicalDeviceFeatures enabledFeatures{
|
||||
.samplerAnisotropy = VK_TRUE
|
||||
.geometryShader = true,
|
||||
.samplerAnisotropy = true,
|
||||
};
|
||||
constexpr uint32_t enabledExtensionCount = 1;
|
||||
char const * enabledExtensionNames[enabledExtensionCount]{ VK_KHR_SWAPCHAIN_EXTENSION_NAME };
|
||||
@ -867,7 +881,7 @@ int main()
|
||||
|
||||
VkViewport viewport{
|
||||
.x = 0,
|
||||
.y = 0,//static_cast<float>(windowSize.y),
|
||||
.y = 0,
|
||||
.width = static_cast<float>(windowSize.x),
|
||||
.height = static_cast<float>(windowSize.y),
|
||||
.minDepth = 0.0f,
|
||||
@ -882,6 +896,8 @@ int main()
|
||||
collada_state.vulkan.excludeMaterialIndex = -1;
|
||||
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
||||
collada_state.draw();
|
||||
collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
||||
collada_state.draw();
|
||||
|
||||
vkCmdEndRendering(commandBuffer);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user