Vulkan Samples 阅读 -- Compute Shader(三)Cloth Simulation & Cull And LOD

Cloth Simulation

prepare

  • queueFamilyIndices.graphics != queueFamilyIndices.compute
    • 区分图形管线与计算管线
  • loadAssets:加球模型与布料纹理
  • prepareStorageBuffers
    • std::vector: 布料分为两类. 一类覆盖在球上, 一类为下垂的布料
    • createBuffer: stagingBuffer
    • createBuffer: storageBuffers: 输入
    • createBuffer: createBuffer:输出
    • Copy from staging buffer
      • createCommandBuffer
      • vkCmdCopyBuffer: 输入
      • vkCmdCopyBuffer:输出
    • addGraphicsToComputeBarriers: 这里将Barrier单独封装一个方法
      • vkCmdPipelineBarrier
    • flushCommandBuffer
    • destroy
    • std::vector<uint32_t> indices: 准备网格的ibo
    • createBuffer: stagingBuffer
    • createBuffer: indexBuffer
    • Copy from staging buffer
      • createCommandBuffer
      • vkCmdCopyBuffer
      • flushCommandBuffer
    • stagingBuffer.destroy()
  • prepareUniformBuffers
    • createBuffer: Compute shader uniform buffer block
    • updateComputeUBO: 准备布料仿真所需的参数
    • createBuffer: 图形管线的uniform
    • updateGraphicsUBO: 图形管线使用的参数
  • setupDescriptorPool
    • 这里多设置了一个池: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
    • vkCreateDescriptorPool
  • setupLayoutsAndDescriptors
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
    • vkAllocateDescriptorSets
    • vkUpdateDescriptorSets
  • preparePipelines
    • Rendering pipeline
      • vkCreateGraphicsPipelines: 布料显示
      • vkCreateGraphicsPipelines: 球模型显示
  • prepareCompute
    • vkGetDeviceQueue
    • vkCreateDescriptorSetLayout
    • pushConstantRange
    • vkCreatePipelineLayout
    • vkAllocateDescriptorSets
    • vkUpdateDescriptorSets
    • Create pipeline
      • vkCreateComputePipelines
      • vkCreateCommandPool
      • vkAllocateCommandBuffers
      • vkCreateSemaphore: ready
      • vkCreateSemaphore: complete
      • buildComputeCommandBuffer
        • loop 2
          • vkBeginCommandBuffer
          • addGraphicsToComputeBarriers
          • vkCmdBindPipeline
          • vkCmdPushConstants
          • loop Dispatch the compute job: 执行64次
            • vkCmdBindDescriptorSets
            • vkCmdPushConstants
            • vkCmdDispatch: 这里分配工作组
            • addComputeToComputeBarriers
            • addComputeToGraphicsBarriers
            • vkEndCommandBuffer
  • buildCommandBuffers
    • loop
      • vkBeginCommandBuffer
      • addComputeToGraphicsBarriers
      • vkCmdBeginRenderPass
      • vkCmdSetViewport
      • vkCmdSetScissor
      • Render sphere
        • vkCmdBindPipeline
        • vkCmdBindDescriptorSets
        • draw
      • Render cloth
        • vkCmdBindPipeline
        • vkCmdBindDescriptorSets
        • vkCmdBindIndexBuffer
        • vkCmdBindVertexBuffers
        • vkCmdDrawIndexed
        • drawUI
        • vkCmdEndRenderPass
        • addGraphicsToComputeBarriers
      • vkEndCommandBuffer

render

  • draw
    • vkQueueSubmit
    • prepareFrame
    • vkQueueSubmit
    • submitFrame

shader

  • CS
    • layout(std430, binding = 0) buffer ParticleIn
    • layout(std430, binding = 1) buffer ParticleOut
      • 注意std430布局的使用
    • layout (binding = 2) uniform UBO
    • layout (push_constant) uniform PushConsts
    • main
      • 获取索引
        • uvec3 id = gl_GlobalInvocationID;
        • uint index = id.y * params.particleCount.x + id.x;
      • 这里布料仿真分三个阶段
        • 计算受力方向和力
        • 力的作用下布料顶点的偏移
        • 和球模型的碰撞检测
        • 更新布料模型的法线
        • 输出布料数据
  • VS: 正常渲染
  • FS: 正常渲染

小结

   布料仿真主要还是注意Barrier的使用, 布料模拟有基础, 这里可以忽略.

Cull And LOD

prepare

  • loadAssets:加载资源
  • prepareBuffers
    • objectCount =64^3
    • std::vector instanceData(objectCount)
    • std::vector indirectCommands;
      • 存储index offsets
      • 存储instance count
      • 初始化instanceCount = 1
      • firstInstance = index
        • index为Object idx
      • createBuffer: stagingBuffer
      • createBuffer: storagebuffer
      • copyBuffer
      • stagingBuffer.destroy()
    • InstanceData
      • createBuffer: storagebuffer: 用于CS写入结果
        • indirectDrawCountBuffer
      • instanceData: 初始化数据的顶点和缩放属性
      • createBuffer: instanceData: stagingBuffer
      • createBuffer: storagebuffer
      • copyBuffer
      • stagingBuffer.destroy();
    • std::vector LODLevels;
      • createBuffer: stagingBuffer
      • createBuffer: storagebuffer
      • copyBuffer
      • destroy
    • createBuffer: Scene uniform buffer
    • updateUniformBuffer
  • setupDescriptorSetLayout
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
  • preparePipelines
    - vkCreateGraphicsPipelines
  • setupDescriptorPool
    • vkCreateDescriptorPool
  • setupDescriptorSet
    • vkAllocateDescriptorSets
    • writeDescriptorSet
    • vkUpdateDescriptorSets
  • prepareCompute
    • vkGetDeviceQueue
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
    • vkAllocateDescriptorSets
    • writeDescriptorSet
      • 共4个
    • vkUpdateDescriptorSets
    • vkCreateComputePipelines
    • vkCreateCommandPool
    • vkAllocateCommandBuffers
    • vkCreateFence
    • vkCreateSemaphore
    • buildComputeCommandBuffer
      • vkBeginCommandBuffer
      • vkCmdPipelineBarrier
      • vkCmdBindPipeline
      • vkCmdBindDescriptorSets
      • vkCmdDispatch: objectCount/16
      • vkCmdPipelineBarrier
      • vkEndCommandBuffer
  • buildCommandBuffers
    • loop
      • vkBeginCommandBuffer
      • addComputeToGraphicsBarriers
      • vkCmdBeginRenderPass
      • vkCmdSetViewport
      • vkCmdSetScissor
      • vkCmdBindPipeline
      • vkCmdBindVertexBuffers: 模型
      • vkCmdBindVertexBuffers: instanceBuffer
      • vkCmdBindIndexBuffer
      • vkCmdDrawIndexedIndirect
      • drawUI
      • vkCmdEndRenderPass
      • vkEndCommandBuffer

render

  • draw
    • prepareFrame
    • vkWaitForFences
    • vkResetFences
    • vkQueueSubmit
    • prepareFrame
    • memcpy(&indirectStats, indirectDrawCountBuffer.mapped, sizeof(indirectStats))
      • Get draw count from compute
  • updateUniformBuffer

shader

  • CS
    • layout (binding = 0, std140) buffer Instances
      • 实例属性, pos和scale
    • layout (binding = 1, std430) writeonly buffer IndirectDraws
      • 注意std430布局的使用
    • layout (binding = 2) uniform UBO
    • layout (binding = 3) buffer UBOOut
    • layout (binding = 4) readonly buffer LODs
    • uint idx = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x;
      • 获取全局idx
    • atomicExchange: atomicExchange(uboOut.drawCount, 0);
      • 读取并修改被封装的值
    • vec4 pos = vec4(instances[idx].pos.xyz, 1.0);
      • 获取当前实例的位置信息
    • atomicAdd(uboOut.drawCount, 1)
      • atomicAdd函数是先赋值后进行加法计算的
      • i++
    • distance
      • 距离函数
  • VS:
    • vec4 pos = vec4((inPos.xyz * instanceScale) + instancePos, 1.0);
    • 根据实例属性设置顶点位置
  • FS: 正常渲染即可

小结

   本节代码没有看太懂, 但是核心讲的是如何将CS计算的结果写回内存中. 可以回来复习.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值