前言
使用推送常量(存储在命令缓冲区中的小块统一数据)将数据传递给着色器,而无需统一缓冲区。
使用推送常量,可以将一小段静态数据传递给着色器,该着色器存储在命令缓冲区统计信息中
这非常适合传递例如静态每个对象的数据或参数,而无需描述符集
该示例使用这些参数来推送不同的静态参数来呈现多个对象
一、CPP文件
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、使用步骤
1.类和变量
代码如下(示例):
class VulkanExample : public VulkanExampleBase
{
public:
vkglTF::Model model;
// Color and position data for each sphere is uploaded using push constants
struct SpherePushConstantData {
glm::vec4 color;
glm::vec4 position;
};
std::array<SpherePushConstantData, 16> spheres;
vks::Buffer uniformBuffer;
struct UBOMatrices {
glm::mat4 projection;
glm::mat4 model;
glm::mat4 view;
} uboMatrices;
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
VkDescriptorSet descriptorSet;
VkDescriptorSetLayout descriptorSetLayout;
2.函数
设置球形物体函数:
void setupSpheres()
{
// Setup random colors and fixed positions for every spheres in the scene
for (uint32_t i = 0; i < spheres.size(); i++) {
spheres[i].color = glm::vec4(rnd(), rnd(), rnd(), 1.0f);
const float rad = glm::radians(i * 360.0f / static_cast<uint32_t>(spheres.size()));
spheres[i].position = glm::vec4(glm::vec3(sin(rad), cos(rad), 0.0f) * 3.5f, 1.0f);
}
}
void buildCommandBuffers()
void buildCommandBuffers()
{
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
VkClearValue clearValues[2];
clearValues[0].color = defaultClearColor;
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo();
renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = 2;
renderPassBeginInfo.pClearValues = clearValues;
for (int32_t i = 0; i < drawCmdBuffers.size(); ++i)
{
// Set target frame buffer
renderPassBeginInfo.framebuffer = frameBuffers[i];
VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0);
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
// [POI] Render the spheres passing color and position via push constants
uint32_t spherecount = static_cast<uint32_t>(spheres.size());
for (uint32_t j = 0; j < spherecount; j++) {
// [POI] Pass static sphere data as push constants
vkCmdPushConstants(
drawCmdBuffers[i],
pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT,
0,
sizeof(SpherePushConstantData),
&spheres[j]);
model.draw(drawCmdBuffers[i]);
}
drawUI(drawCmdBuffers[i]);
vkCmdEndRenderPass(drawCmdBuffers[i]);
VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
}
}
void setupDescriptorSetLayout()
void setupDescriptorSetLayout()
{
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
// Binding 0 : Vertex shader uniform buffer
vks::initializers::descriptorSetLayoutBinding(
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT,
0),
};
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
// Define the push constant range used by the pipeline layout
// Note that the spec only requires a minimum of 128 bytes, so for passing larger blocks of data you'd use UBOs or SSBOs
VkPushConstantRange pushConstantRange{};
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
pushConstantRange.offset = 0;
pushConstantRange.size = sizeof(SpherePushConstantData);
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
}
shader文件
1.vert
#version 450
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec3 inColor;
#define lightCount 6
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
mat4 view;
} ubo;
layout(push_constant) uniform PushConsts {
vec4 color;
vec4 position;
} pushConsts;
layout (location = 0) out vec3 outColor;
void main()
{
outColor = inColor * pushConsts.color.rgb;
vec3 locPos = vec3(ubo.model * vec4(inPos, 1.0));
vec3 worldPos = locPos + pushConsts.position.xyz;
gl_Position = ubo.projection * ubo.view * vec4(worldPos, 1.0);
}
2.frag
#version 450
layout (location = 0) in vec3 inColor;
layout (location = 0) out vec4 outFragColor;
void main()
{
outFragColor.rgb = inColor;
}
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。