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: 球模型显示
- Rendering pipeline
- 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
- loop 2
- buildCommandBuffers
- loop
- vkBeginCommandBuffer
- addComputeToGraphicsBarriers
- vkCmdBeginRenderPass
- vkCmdSetViewport
- vkCmdSetScissor
- Render sphere
- vkCmdBindPipeline
- vkCmdBindDescriptorSets
- draw
- Render cloth
- vkCmdBindPipeline
- vkCmdBindDescriptorSets
- vkCmdBindIndexBuffer
- vkCmdBindVertexBuffers
- vkCmdDrawIndexed
- drawUI
- vkCmdEndRenderPass
- addGraphicsToComputeBarriers
- vkEndCommandBuffer
- loop
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();
- createBuffer: storagebuffer: 用于CS写入结果
- 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
- loop
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
- 距离函数
- layout (binding = 0, std140) buffer Instances
- VS:
- vec4 pos = vec4((inPos.xyz * instanceScale) + instancePos, 1.0);
- 根据实例属性设置顶点位置
- FS: 正常渲染即可
小结
本节代码没有看太懂, 但是核心讲的是如何将CS计算的结果写回内存中. 可以回来复习.