Vulkan-官方示例解读-piplines


前言

piplines:使用将状态信息(光栅化状态、剔除模式等)与着色器一起烘焙到单个对象中的管道状态对象 (pso),使实现更容易优化使用(与 OpenGL 的动态状态机相比)。本例子还演示了管道导数的使用。后面进一步还有统计渲染管线。
在这里插入图片描述
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、piplines.cpp

1.基本变量

class VulkanExample: public VulkanExampleBase
{
public:
	vkglTF::Model scene;

	vks::Buffer uniformBuffer;

	// Same uniform buffer layout as shader
	struct UBOVS {
		glm::mat4 projection;
		glm::mat4 modelView;
		glm::vec4 lightPos = glm::vec4(0.0f, 2.0f, 1.0f, 0.0f);
	} uboVS;

	VkPipelineLayout pipelineLayout;
	VkDescriptorSet descriptorSet;
	VkDescriptorSetLayout descriptorSetLayout;

	struct {
		VkPipeline phong;
		VkPipeline wireframe;
		VkPipeline toon;
	} pipelines;

2.函数

除了构造函数以及析构函数外比较重要的有如下函数:

  • 启用此示例所需的物理设备功能

    	// Enable physical device features required for this example
    	virtual void getEnabledFeatures()
    	{
    		// Fill mode non solid is required for wireframe display
    		if (deviceFeatures.fillModeNonSolid) {
    			enabledFeatures.fillModeNonSolid = VK_TRUE;
    			// Wide lines must be present for line width > 1.0f
    			if (deviceFeatures.wideLines) {
    				enabledFeatures.wideLines = VK_TRUE;
    			}
    		};
    	}
    
    
  • 创建命令缓冲:在这个函数中实现了分屏以及渲染的操作的命令。
    不同的渲染方式使用了同一个pipline中的不同元素,这些元素分别由shader建立。

    	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);
    
    			vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL);
    			scene.bindBuffers(drawCmdBuffers[i]);
    
    			// 渲染左边的 : Solid colored
    			viewport.width = (float)width / 3.0;
    			vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
    			vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.phong);
    			scene.draw(drawCmdBuffers[i]);
    
    			// 渲染中间的 : Toon
    			viewport.x = (float)width / 3.0;
    			vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
    			vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toon);
    			// Line width > 1.0f only if wide lines feature is supported
    			if (deviceFeatures.wideLines) {
    				vkCmdSetLineWidth(drawCmdBuffers[i], 2.0f);
    			}
    			scene.draw(drawCmdBuffers[i]);
    
    			if (deviceFeatures.fillModeNonSolid)
    			{
    				// 渲染右边的 : Wireframe
    				viewport.x = (float)width / 3.0 + (float)width / 3.0;
    				vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
    				vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
    				scene.draw(drawCmdBuffers[i]);
    			}
    
    			drawUI(drawCmdBuffers[i]);
    
    			vkCmdEndRenderPass(drawCmdBuffers[i]);
    
    			VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
    		}
    	}
    
  • 创建渲染管线:给渲染光纤pipelineCI中添加一系列属性数据。将shader写入渲染管线当中。
    创建图形管道状态对象
    我们使用此管道作为其他管道(衍生品)的基础
    管道衍生品可用于共享大部分状态的管道
    根据实现的不同,这可能会提高管道的性能
    切换和更快的创建时间
    注意下面的基础性渲染管线的建立以及派生的渲染管线的使用:在基础管道之后创建的所有管道都将是衍生产品,

    	void preparePipelines()
    	{
    		VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE);
    		VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0);
    		VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
    		VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState);
    		VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL);
    		VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
    		VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT);
    		std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH, };
    		VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables);
    		std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
    
    		VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass);
    		pipelineCI.pInputAssemblyState = &inputAssemblyState;
    		pipelineCI.pRasterizationState = &rasterizationState;
    		pipelineCI.pColorBlendState = &colorBlendState;
    		pipelineCI.pMultisampleState = &multisampleState;
    		pipelineCI.pViewportState = &viewportState;
    		pipelineCI.pDepthStencilState = &depthStencilState;
    		pipelineCI.pDynamicState = &dynamicState;
    		pipelineCI.stageCount = shaderStages.size();
    		pipelineCI.pStages = shaderStages.data();
    		pipelineCI.pVertexInputState  = vkglTF::Vertex::getPipelineVertexInputState({vkglTF::VertexComponent::Position, vkglTF::VertexComponent::Normal, vkglTF::VertexComponent::Color});
    
    		// Create the graphics pipeline state objects
    
    		// We are using this pipeline as the base for the other pipelines (derivatives)
    		// Pipeline derivatives can be used for pipelines that share most of their state
    		// Depending on the implementation this may result in better performance for pipeline
    		// switching and faster creation time
    		pipelineCI.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
    
    		// Textured pipeline
    		// Phong shading pipeline
    		shaderStages[0] = loadShader(getShadersPath() + "pipelines/phong.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
    		shaderStages[1] = loadShader(getShadersPath() + "pipelines/phong.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
    		VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.phong));
    
    		// 在基础管道之后创建的所有管道都将是衍生产品
    		pipelineCI.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
    		// 基础渲染管线是我们的第一个渲染管线
    		pipelineCI.basePipelineHandle = pipelines.phong;
    		//只允许对基本管道使用句柄或索引
    		//当我们使用句柄时,我们必须将索引设置为 -1(请参阅规范的第 9.5 节)
    		pipelineCI.basePipelineIndex = -1;
    
    		// Toon shading pipeline
    		shaderStages[0] = loadShader(getShadersPath() + "pipelines/toon.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
    		shaderStages[1] = loadShader(getShadersPath() + "pipelines/toon.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
    		VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.toon));
    
    		// Pipeline for wire frame rendering
    		// Non solid rendering is not a mandatory Vulkan feature
    		if (deviceFeatures.fillModeNonSolid)
    		{
    			rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
    			shaderStages[0] = loadShader(getShadersPath() + "pipelines/wireframe.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
    			shaderStages[1] = loadShader(getShadersPath() + "pipelines/wireframe.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
    			VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.wireframe));
    		}
    	}
    

二、GLSL

1.phone

fargShader:

#version 450

layout (binding = 1) uniform sampler2D samplerColorMap;

layout (location = 0) in vec3 inNormal;
layout (location = 1) in vec3 inColor;
layout (location = 2) in vec3 inViewVec;
layout (location = 3) in vec3 inLightVec;

layout (location = 0) out vec4 outFragColor;

void main() 
{
	// Desaturate color
    vec3 color = vec3(mix(inColor, vec3(dot(vec3(0.2126,0.7152,0.0722), inColor)), 0.65));	

	// High ambient colors because mesh materials are pretty dark
	vec3 ambient = color * vec3(1.0);
	vec3 N = normalize(inNormal);
	vec3 L = normalize(inLightVec);
	vec3 V = normalize(inViewVec);
	vec3 R = reflect(-L, N);
	vec3 diffuse = max(dot(N, L), 0.0) * color;
	vec3 specular = pow(max(dot(R, V), 0.0), 32.0) * vec3(0.35);
	outFragColor = vec4(ambient + diffuse * 1.75 + specular, 1.0);		
}

vertShader:

#version 450

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec3 inColor;

layout (binding = 0) uniform UBO 
{
	mat4 projection;
	mat4 model;
	vec4 lightPos;
} ubo;

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outColor;
layout (location = 2) out vec3 outViewVec;
layout (location = 3) out vec3 outLightVec;

void main() 
{
	outNormal = inNormal;
	outColor = inColor;
	gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
	
	vec4 pos = ubo.model * vec4(inPos, 1.0);
	outNormal = mat3(ubo.model) * inNormal;
	vec3 lPos = mat3(ubo.model) * ubo.lightPos.xyz;
	outLightVec = lPos - pos.xyz;
	outViewVec = -pos.xyz;		
}

2.toon

fragShader

#version 450

layout (binding = 1) uniform sampler2D samplerColorMap;

layout (location = 0) in vec3 inNormal;
layout (location = 1) in vec3 inColor;
layout (location = 2) in vec3 inViewVec;
layout (location = 3) in vec3 inLightVec;

layout (location = 0) out vec4 outFragColor;

void main() 
{
	// Desaturate color
    vec3 color = vec3(mix(inColor, vec3(dot(vec3(0.2126,0.7152,0.0722), inColor)), 0.65));	

	// High ambient colors because mesh materials are pretty dark
	vec3 ambient = color * vec3(1.0);
	vec3 N = normalize(inNormal);
	vec3 L = normalize(inLightVec);
	vec3 V = normalize(inViewVec);
	vec3 R = reflect(-L, N);
	vec3 diffuse = max(dot(N, L), 0.0) * color;
	vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75);
	outFragColor = vec4(ambient + diffuse * 1.75 + specular, 1.0);		
	
	float intensity = dot(N,L);
	float shade = 1.0;
	shade = intensity < 0.5 ? 0.75 : shade;
	shade = intensity < 0.35 ? 0.6 : shade;
	shade = intensity < 0.25 ? 0.5 : shade;
	shade = intensity < 0.1 ? 0.25 : shade;

	outFragColor.rgb = inColor * 3.0 * shade;
}

vertShader

#version 450

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec3 inColor;

layout (binding = 0) uniform UBO 
{
	mat4 projection;
	mat4 model;
	vec4 lightPos;
} ubo;

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outColor;
layout (location = 2) out vec3 outViewVec;
layout (location = 3) out vec3 outLightVec;

void main() 
{
	outNormal = inNormal;
	outColor = inColor;
	gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
	
	vec4 pos = ubo.model * vec4(inPos, 1.0);
	outNormal = mat3(ubo.model) * inNormal;
	vec3 lPos = mat3(ubo.model) * ubo.lightPos.xyz;
	outLightVec = lPos - pos.xyz;
	outViewVec = -pos.xyz;		
}

3.wireframe

fragShader

#version 450

layout (location = 0) in vec3 inColor;

layout (location = 0) out vec4 outFragColor;

void main() 
{
	outFragColor.rgb = inColor * 1.5;
}

vertShader

#version 450

layout (location = 0) in vec4 inPos;
layout (location = 2) in vec3 inColor;

layout (binding = 0) uniform UBO 
{
	mat4 projection;
	mat4 model;
} ubo;

layout (location = 0) out vec3 outColor;

void main() 
{
	outColor = inColor;
	gl_Position = ubo.projection * ubo.model * inPos;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值