mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 18:56:16 +03:00
913 lines
42 KiB
C++
913 lines
42 KiB
C++
#include "../deferred_renderer.h"
|
|
#include "../render_scene.h"
|
|
#include "../renderer.h"
|
|
#include "../scene_textures.h"
|
|
|
|
namespace engine
|
|
{
|
|
struct CloudPush
|
|
{
|
|
uint sdsmShadowDepthIndices[kMaxCascadeNum];
|
|
uint cascadeCount;
|
|
|
|
float kStepNum;
|
|
float mixWeight;
|
|
};
|
|
|
|
static AutoCVarInt32 cVarCloudDownSampleRender("r.cloud.downsample", "Downsample cloud to save performance.", "Render", 1, CVarFlags::ReadAndWrite);
|
|
|
|
struct CloudBlurShadowDepthPush
|
|
{
|
|
vec2 kBlurDirection;
|
|
float kRadius;
|
|
float kSigma;
|
|
float kRadiusLow;
|
|
};
|
|
|
|
struct LensPush
|
|
{
|
|
uint32_t bCloud;
|
|
uint32_t bFog;
|
|
};
|
|
|
|
static AutoCVarInt32 cVarFogRayStep("r.fog.rayStep", "Ray marching step.", "Render", 16, CVarFlags::ReadAndWrite);
|
|
struct FogPush
|
|
{
|
|
uint sdsmShadowDepthIndices[kMaxCascadeNum];
|
|
uint cascadeCount;
|
|
uint kGodRaySteps;
|
|
uint kSkyPass;
|
|
};
|
|
|
|
static AutoCVarInt32 cVarCloudBlurRadius("r.cloud.shadowdepth.blurRadius", "cloud shadow depth blur radius.", "Render",
|
|
8, CVarFlags::ReadAndWrite);
|
|
|
|
static AutoCVarInt32 cVarCloudBlurRadiusLow("r.cloud.shadowdepth.blurLow", "cloud shadow depth blur radius low radius.", "Render",
|
|
2, CVarFlags::ReadAndWrite);
|
|
|
|
static AutoCVarInt32 cVarCloudBlurRadiusLow2("r.cloud.shadowdepth.blurLow2", "cloud shadow depth blur radius low radius.", "Render",
|
|
6, CVarFlags::ReadAndWrite);
|
|
|
|
static AutoCVarFloat cVarCloudBlurMix("r.cloud.shadowdepth.mix", "cloud shadow depth blur mix.", "Render",
|
|
0.125f, CVarFlags::ReadAndWrite);
|
|
|
|
static AutoCVarFloat cVarCloudBlurMixLow("r.cloud.shadowdepth.mixLow", "cloud shadow depth blur mix low.", "Render",
|
|
0.25f, CVarFlags::ReadAndWrite);
|
|
|
|
struct CloudDepthMixPush
|
|
{
|
|
vec2 mixWeight;
|
|
};
|
|
|
|
class CloudPass : public PassInterface
|
|
{
|
|
public:
|
|
ComputePipeResourcesRef fogPipe;
|
|
ComputePipeResourcesRef lensPipe;
|
|
ComputePipeResourcesRef computeCloudPipeline;
|
|
ComputePipeResourcesRef reconstructionPipeline;
|
|
ComputePipeResourcesRef compositeCloudPipeline;
|
|
ComputePipeResourcesRef cloudDepthMixPipeline;
|
|
ComputePipeResourcesRef cloudDepthPipeline;
|
|
ComputePipeResourcesRef cloudBlurDepthPipeline;
|
|
|
|
public:
|
|
virtual void onInit() override
|
|
{
|
|
{
|
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
|
|
getContext()->descriptorFactoryBegin()
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0) // inHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1) // inHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2) // imageHdrSceneColor
|
|
.buildNoInfoPush(setLayout);
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayouts =
|
|
{
|
|
setLayout
|
|
, m_context->getSamplerCache().getCommonDescriptorSetLayout()
|
|
};
|
|
|
|
cloudDepthMixPipeline = createComputePipe("shader/cloud_shadow_depth_mix.glsl",
|
|
sizeof(CloudDepthMixPush), setLayouts);
|
|
}
|
|
|
|
{
|
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
|
|
getContext()->descriptorFactoryBegin()
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0) // imageHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1) // inHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3) // inGBufferA
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4) // inBasicNoise
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,5)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 6) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,7) // Framedata.
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 8) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 9) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 10) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 11) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 12) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 13) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 14) // inDepth
|
|
.buildNoInfoPush(setLayout);
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayouts =
|
|
{
|
|
setLayout
|
|
, m_context->getSamplerCache().getCommonDescriptorSetLayout()
|
|
, getRenderer()->getBlueNoise().spp_1_buffer.setLayouts
|
|
, m_context->getBindlessTextureSetLayout()
|
|
};
|
|
|
|
ShaderVariant shaderVariant("shader/volumetric_fog_raymarching.glsl");
|
|
shaderVariant.setStage(EShaderStage::eComputeShader);
|
|
|
|
{
|
|
auto copyVariant = shaderVariant;
|
|
copyVariant.setMacro(L"COMPUTE_PASS");
|
|
fogPipe = createComputePipe(copyVariant, sizeof(FogPush), setLayouts);
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
|
|
getContext()->descriptorFactoryBegin()
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 5)
|
|
.buildNoInfoPush(setLayout);
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayoutsLens =
|
|
{
|
|
setLayout
|
|
, m_context->getSamplerCache().getCommonDescriptorSetLayout()
|
|
};
|
|
|
|
lensPipe = createComputePipe("shader/lens_visible.glsl", sizeof(LensPush), setLayoutsLens);
|
|
}
|
|
|
|
{
|
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
// Config code.
|
|
getContext()->descriptorFactoryBegin()
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0) // imageHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1) // inHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2) // imageCloudRenderTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3) // inCloudRenderTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 5) // inGBufferA
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 6) // inBasicNoise
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 7) // inDetailNoise
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 8) // inCloudWeather
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 9) // inCloudCurl
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 10) // inTransmittanceLut
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 11) // inFroxelScatter
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 12) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 13) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 14) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 15) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 16) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 17) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 18) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 19) // inCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 20) // inDepth
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 21) // Framedata.
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 22) // inSkylight
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 23)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 24) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 25)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 26)
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 27) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 28) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 29) // imageCloudReconstructionTexture
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 30) // imageCloudReconstructionTexture
|
|
.buildNoInfoPush(setLayout);
|
|
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayouts =
|
|
{
|
|
setLayout
|
|
, m_context->getSamplerCache().getCommonDescriptorSetLayout()
|
|
, getRenderer()->getBlueNoise().spp_1_buffer.setLayouts
|
|
, m_context->getBindlessTextureSetLayout()
|
|
};
|
|
|
|
computeCloudPipeline = createComputePipe("shader/cloud_render_raymarching.glsl", sizeof(CloudPush), setLayouts);
|
|
reconstructionPipeline = createComputePipe("shader/cloud_render_reconstruct.glsl", sizeof(CloudPush), setLayouts);
|
|
compositeCloudPipeline = createComputePipe("shader/cloud_render_composite.glsl", sizeof(CloudPush), setLayouts);
|
|
cloudDepthPipeline = createComputePipe("shader/cloud_shadow_depth.glsl", sizeof(CloudPush), setLayouts);
|
|
}
|
|
|
|
|
|
{
|
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
// Config code.
|
|
getContext()->descriptorFactoryBegin()
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0) // imageHdrSceneColor
|
|
.bindNoInfo(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1) // inHdrSceneColor
|
|
.buildNoInfoPush(setLayout);
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayouts =
|
|
{
|
|
setLayout
|
|
, m_context->getSamplerCache().getCommonDescriptorSetLayout()
|
|
};
|
|
|
|
cloudBlurDepthPipeline = createComputePipe("shader/cloud_shadow_depth_blur.glsl",
|
|
sizeof(CloudBlurShadowDepthPush), setLayouts);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
void engine::updateCloudPass()
|
|
{
|
|
getContext()->getPasses().updatePass<class CloudPass>();
|
|
CVarSystem::get()->setCVar("cmd.clearAllReflectionCapture", true);
|
|
}
|
|
|
|
bool shouldRenderCloud(const PerFrameData& perframe)
|
|
{
|
|
return (perframe.bSkyComponentValid != 0);
|
|
}
|
|
|
|
void DeferredRenderer::renderVolumetricCloudShadowDepth(
|
|
VkCommandBuffer cmd,
|
|
GBufferTextures* inGBuffers,
|
|
RenderScene* scene,
|
|
BufferParameterHandle perFrameGPU,
|
|
AtmosphereTextures& inAtmosphere,
|
|
const PerFrameData& perframe,
|
|
const SkyLightRenderContext& skyContext)
|
|
{
|
|
if (!shouldRenderCloud(perframe))
|
|
{
|
|
m_history.cloudShadowDepthHistory = nullptr;
|
|
return;
|
|
}
|
|
|
|
if (m_history.cloudShadowDepthHistory == nullptr ||
|
|
perframe.frameIndex.x % 4 == 0)
|
|
{
|
|
// Update.
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto* pass = getContext()->getPasses().get<CloudPass>();
|
|
auto* rtPool = &getContext()->getRenderTargetPools();
|
|
|
|
auto sunCloudShadowDepth = rtPool->createPoolImage(
|
|
"sun cloud shadow depth",
|
|
getShadowDepthDimCloud(),
|
|
getShadowDepthDimCloud(),
|
|
VK_FORMAT_R32G32_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
auto& sceneDepthZ = inGBuffers->depthTexture->getImage();
|
|
auto& sceneColorHdr = inGBuffers->hdrSceneColor->getImage();
|
|
auto& gbufferA = inGBuffers->gbufferA->getImage();
|
|
|
|
auto weatherTexture = std::dynamic_pointer_cast<GPUImageAsset>(getContext()->getBuiltinTexture(EBuiltinTextures::cloudWeather));
|
|
auto curlNoiseTexture = std::dynamic_pointer_cast<GPUImageAsset>(getContext()->getBuiltinTexture(EBuiltinTextures::cloudNoise));
|
|
|
|
auto cloudDistanceLit = inAtmosphere.distant;
|
|
|
|
auto pushCommonSet = [&]()
|
|
{
|
|
auto& placeHolder = sceneColorHdr;
|
|
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addUAV(placeHolder)
|
|
.addSRV(placeHolder)
|
|
.addUAV(placeHolder)
|
|
.addSRV(placeHolder)
|
|
.addSRV(sceneDepthZ, RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT))
|
|
.addSRV(gbufferA)
|
|
.addSRV(*getRenderer()->getSharedTextures().cloudBasicNoise, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D)
|
|
.addSRV(*getRenderer()->getSharedTextures().cloudDetailNoise, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D)
|
|
.addSRV(weatherTexture->getSelfImage()) // 8
|
|
.addSRV(curlNoiseTexture->getSelfImage()) // 8
|
|
.addSRV(inAtmosphere.transmittance) // 10
|
|
.addSRV(inAtmosphere.distantGrid, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 11
|
|
.addUAV(placeHolder) // 12
|
|
.addSRV(placeHolder) // 13
|
|
.addUAV(placeHolder) // 14
|
|
.addSRV(placeHolder) // 15
|
|
.addUAV(placeHolder) // 16
|
|
.addSRV(placeHolder) // 17
|
|
.addSRV(placeHolder) // 18
|
|
.addSRV(placeHolder) // 19
|
|
.addSRV(inAtmosphere.skyView) // 20
|
|
.addBuffer(perFrameGPU) // 21
|
|
.addSRV(skyContext.skylightRadiance, buildBasicImageSubresourceCube(), VK_IMAGE_VIEW_TYPE_CUBE)
|
|
.addSRV(cloudDistanceLit)
|
|
.addUAV(sunCloudShadowDepth)
|
|
.addSRV(m_history.cloudShadowDepthHistory ? m_history.cloudShadowDepthHistory->getImage() : getContext()->getBuiltinTextureTranslucent()->getSelfImage())
|
|
.push(pass->cloudDepthPipeline);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
getRenderer()->getBlueNoise().spp_1_buffer.set,
|
|
getContext()->getBindlessTexture().getSet()
|
|
};
|
|
pass->cloudDepthPipeline->bindSet(cmd, additionalSets, 1);
|
|
};
|
|
|
|
cloudDistanceLit->getImage().transitionShaderReadOnly(cmd);
|
|
pushCommonSet();
|
|
{
|
|
sunCloudShadowDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
CloudPush push;
|
|
push.kStepNum = 25;
|
|
|
|
pass->cloudDepthPipeline->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().width, 8),
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().height, 8), 1);
|
|
|
|
sunCloudShadowDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
// Blur x.
|
|
auto sunCloudShadowDepthBlurX = rtPool->createPoolImage(
|
|
"sun cloud shadow depth blurX",
|
|
sunCloudShadowDepth->getImage().getExtent().width,
|
|
sunCloudShadowDepth->getImage().getExtent().height,
|
|
sunCloudShadowDepth->getImage().getFormat(),
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
{
|
|
|
|
|
|
{
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addSRV(sunCloudShadowDepth)
|
|
.addUAV(sunCloudShadowDepthBlurX)
|
|
.push(pass->cloudBlurDepthPipeline);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
};
|
|
pass->cloudBlurDepthPipeline->bindSet(cmd, additionalSets, 1);
|
|
}
|
|
|
|
sunCloudShadowDepthBlurX->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
CloudBlurShadowDepthPush push{};
|
|
push.kBlurDirection = vec2(1.0f, 0.0f);
|
|
push.kRadius = float(cVarCloudBlurRadius.get());
|
|
push.kSigma = 0.2f;
|
|
push.kRadiusLow = math::mix(float(cVarCloudBlurRadiusLow.get()), float(cVarCloudBlurRadiusLow2.get()),
|
|
1.0f - math::clamp(perframe.sunLightInfo.direction.y * 2.0f, 0.0f, 1.0f));
|
|
|
|
pass->cloudBlurDepthPipeline->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(sunCloudShadowDepthBlurX->getImage().getExtent().width, 8),
|
|
getGroupCount(sunCloudShadowDepthBlurX->getImage().getExtent().height, 8), 1);
|
|
|
|
sunCloudShadowDepthBlurX->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
|
|
// Blur Y.
|
|
sunCloudShadowDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
{
|
|
|
|
PushSetBuilder setBuilder2(cmd);
|
|
setBuilder2
|
|
.addSRV(sunCloudShadowDepthBlurX)
|
|
.addUAV(sunCloudShadowDepth)
|
|
.push(pass->cloudBlurDepthPipeline);
|
|
}
|
|
|
|
|
|
push.kBlurDirection = vec2(0.0f, 1.0f);
|
|
pass->cloudBlurDepthPipeline->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().width, 8),
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().height, 8), 1);
|
|
|
|
sunCloudShadowDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
if (m_history.cloudShadowDepthHistory != nullptr)
|
|
{
|
|
sunCloudShadowDepthBlurX->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
m_history.cloudShadowDepthHistory->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
|
|
CloudDepthMixPush push{};
|
|
push.mixWeight = vec2(cVarCloudBlurMix.get(), cVarCloudBlurMixLow.get());
|
|
pass->cloudDepthMixPipeline->bindAndPushConst(cmd, &push);
|
|
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addSRV(sunCloudShadowDepth)
|
|
.addSRV(m_history.cloudShadowDepthHistory)
|
|
.addUAV(sunCloudShadowDepthBlurX)
|
|
.push(pass->cloudDepthMixPipeline);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
};
|
|
pass->cloudDepthMixPipeline->bindSet(cmd, additionalSets, 1);
|
|
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().width, 8),
|
|
getGroupCount(sunCloudShadowDepth->getImage().getExtent().height, 8), 1);
|
|
|
|
sunCloudShadowDepthBlurX->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
|
|
m_history.cloudShadowDepthHistory = sunCloudShadowDepthBlurX;
|
|
}
|
|
else
|
|
{
|
|
m_history.cloudShadowDepthHistory = sunCloudShadowDepth;
|
|
}
|
|
}
|
|
|
|
void DeferredRenderer::renderVolumetricCloud(
|
|
VkCommandBuffer cmd,
|
|
GBufferTextures* inGBuffers,
|
|
RenderScene* scene,
|
|
BufferParameterHandle perFrameGPU,
|
|
AtmosphereTextures& inAtmosphere,
|
|
const PerFrameData& perframe,
|
|
const SkyLightRenderContext& skyContext,
|
|
const SDSMInfos& sunSDSMInfos)
|
|
{
|
|
|
|
auto& sceneDepthZ = inGBuffers->depthTexture->getImage();
|
|
auto& sceneColorHdr = inGBuffers->hdrSceneColor->getImage();
|
|
auto& gbufferA = inGBuffers->gbufferA->getImage();
|
|
|
|
bool bExistCloud = false;
|
|
auto* pass = getContext()->getPasses().get<CloudPass>();
|
|
auto* rtPool = &getContext()->getRenderTargetPools();
|
|
|
|
if (scene->getSkyComponent() == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const bool bDownSample = cVarCloudDownSampleRender.get() != 0;
|
|
int kDownSampleSize = bDownSample ? 4 : 1;
|
|
auto cloudDistanceLit = inAtmosphere.distant;
|
|
|
|
cloudDistanceLit->getImage().transitionShaderReadOnly(cmd);
|
|
|
|
PoolImageSharedRef fogFullImage;
|
|
{
|
|
fogFullImage = rtPool->createPoolImage(
|
|
"fogSkyCompute-Full",
|
|
sceneDepthZ.getExtent().width,
|
|
sceneDepthZ.getExtent().height,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
PoolImageSharedRef fogSkyImage;
|
|
{
|
|
fogSkyImage = rtPool->createPoolImage(
|
|
"fogSkyCompute",
|
|
sceneDepthZ.getExtent().width / 4,
|
|
sceneDepthZ.getExtent().height / 4,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addUAV(sceneColorHdr)
|
|
.addSRV(sceneColorHdr)
|
|
.addSRV(inGBuffers->chessboardHalfDepth)
|
|
.addSRV(inAtmosphere.transmittance) // 10
|
|
.addSRV(inAtmosphere.distantGrid, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 11
|
|
.addBuffer(sunSDSMInfos.cascadeInfoBuffer)
|
|
.addSRV(m_history.cloudShadowDepthHistory)
|
|
.addBuffer(perFrameGPU) // 21
|
|
.addSRV(skyContext.skylightRadiance, buildBasicImageSubresourceCube(), VK_IMAGE_VIEW_TYPE_CUBE)
|
|
.addSRV(cloudDistanceLit)
|
|
.addUAV(fogSkyImage)
|
|
.addSRV(inGBuffers->hzbClosest)
|
|
.addSRV(cloudDistanceLit) // inFog
|
|
.addSRV(cloudDistanceLit) // inFogSky
|
|
.addSRV(inGBuffers->hzbFurthest)
|
|
.push(pass->fogPipe);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
getRenderer()->getBlueNoise().spp_1_buffer.set,
|
|
getContext()->getBindlessTexture().getSet()
|
|
};
|
|
pass->fogPipe->bindSet(cmd, additionalSets, 1);
|
|
|
|
FogPush push{};
|
|
push.kSkyPass = true;
|
|
push.kGodRaySteps = cVarFogRayStep.get();
|
|
push.cascadeCount = perframe.sunLightInfo.cascadeConfig.cascadeCount;
|
|
for (int i = sunSDSMInfos.shadowDepths.size() - 1; i >= 0; i--)
|
|
{
|
|
push.sdsmShadowDepthIndices[i] =
|
|
sunSDSMInfos.shadowDepths[i]->getImage().getOrCreateView(
|
|
RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)).srvBindless;
|
|
}
|
|
|
|
{
|
|
fogSkyImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
pass->fogPipe->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(fogSkyImage->getImage().getExtent().width, 8),
|
|
getGroupCount(fogSkyImage->getImage().getExtent().height, 8), 1);
|
|
fogSkyImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
}
|
|
|
|
PoolImageSharedRef fogImage;
|
|
{
|
|
fogImage = rtPool->createPoolImage(
|
|
"fogCompute",
|
|
sceneDepthZ.getExtent().width / 2,
|
|
sceneDepthZ.getExtent().height / 2,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addUAV(sceneColorHdr)
|
|
.addSRV(sceneColorHdr)
|
|
.addSRV(inGBuffers->chessboardHalfDepth)
|
|
.addSRV(inAtmosphere.transmittance) // 10
|
|
.addSRV(inAtmosphere.distantGrid, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 11
|
|
.addBuffer(sunSDSMInfos.cascadeInfoBuffer)
|
|
.addSRV(m_history.cloudShadowDepthHistory)
|
|
.addBuffer(perFrameGPU) // 21
|
|
.addSRV(skyContext.skylightRadiance, buildBasicImageSubresourceCube(), VK_IMAGE_VIEW_TYPE_CUBE)
|
|
.addSRV(cloudDistanceLit)
|
|
.addUAV(fogImage)
|
|
.addSRV(inGBuffers->hzbClosest)
|
|
.addSRV(cloudDistanceLit) // inFog
|
|
.addSRV(cloudDistanceLit) // inFogSky
|
|
.addSRV(inGBuffers->hzbFurthest)
|
|
.push(pass->fogPipe);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
getRenderer()->getBlueNoise().spp_1_buffer.set,
|
|
getContext()->getBindlessTexture().getSet()
|
|
};
|
|
pass->fogPipe->bindSet(cmd, additionalSets, 1);
|
|
|
|
FogPush push{};
|
|
push.kSkyPass = false;
|
|
push.kGodRaySteps = cVarFogRayStep.get();
|
|
push.cascadeCount = perframe.sunLightInfo.cascadeConfig.cascadeCount;
|
|
for (int i = sunSDSMInfos.shadowDepths.size() - 1; i >= 0; i--)
|
|
{
|
|
push.sdsmShadowDepthIndices[i] =
|
|
sunSDSMInfos.shadowDepths[i]->getImage().getOrCreateView(
|
|
RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)).srvBindless;
|
|
}
|
|
|
|
{
|
|
fogImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
pass->fogPipe->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(fogImage->getImage().getExtent().width, 8),
|
|
getGroupCount(fogImage->getImage().getExtent().height, 8), 1);
|
|
fogImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addUAV(sceneColorHdr)
|
|
.addSRV(sceneColorHdr)
|
|
.addSRV(sceneDepthZ, RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT))
|
|
.addSRV(inAtmosphere.transmittance) // 10
|
|
.addSRV(inAtmosphere.distantGrid, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 11
|
|
.addBuffer(sunSDSMInfos.cascadeInfoBuffer)
|
|
.addSRV(m_history.cloudShadowDepthHistory)
|
|
.addBuffer(perFrameGPU) // 21
|
|
.addSRV(skyContext.skylightRadiance, buildBasicImageSubresourceCube(), VK_IMAGE_VIEW_TYPE_CUBE)
|
|
.addSRV(cloudDistanceLit)
|
|
.addUAV(fogFullImage)
|
|
.addSRV(inGBuffers->hzbClosest)
|
|
.addSRV(fogImage) // inFog
|
|
.addSRV(fogSkyImage) // inFogSky
|
|
.addSRV(inGBuffers->hzbFurthest)
|
|
.push(pass->fogPipe);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
getRenderer()->getBlueNoise().spp_1_buffer.set,
|
|
getContext()->getBindlessTexture().getSet()
|
|
};
|
|
pass->fogPipe->bindSet(cmd, additionalSets, 1);
|
|
|
|
FogPush push{};
|
|
push.kSkyPass = 2;
|
|
push.kGodRaySteps = cVarFogRayStep.get();
|
|
push.cascadeCount = perframe.sunLightInfo.cascadeConfig.cascadeCount;
|
|
for (int i = sunSDSMInfos.shadowDepths.size() - 1; i >= 0; i--)
|
|
{
|
|
push.sdsmShadowDepthIndices[i] =
|
|
sunSDSMInfos.shadowDepths[i]->getImage().getOrCreateView(
|
|
RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)).srvBindless;
|
|
}
|
|
|
|
{
|
|
fogFullImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL);
|
|
pass->fogPipe->bindAndPushConst(cmd, &push);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(fogFullImage->getImage().getExtent().width, 8),
|
|
getGroupCount(fogFullImage->getImage().getExtent().height, 8), 1);
|
|
fogFullImage->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
}
|
|
}
|
|
|
|
|
|
m_gpuTimer.getTimeStamp(cmd, "Volumetric fog");
|
|
}
|
|
|
|
|
|
|
|
auto computeCloud = [&]()
|
|
{
|
|
if (!shouldRenderCloud(m_perframe))
|
|
{
|
|
m_history.cloudReconstruction = nullptr;
|
|
m_history.cloudReconstructionDepth = nullptr;
|
|
return;
|
|
}
|
|
|
|
bExistCloud = true;
|
|
|
|
// Quater resolution evaluate.
|
|
auto computeCloud = rtPool->createPoolImage(
|
|
"CloudCompute",
|
|
sceneDepthZ.getExtent().width / kDownSampleSize,
|
|
sceneDepthZ.getExtent().height / kDownSampleSize,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
|
|
);
|
|
auto computeCloudDepth = rtPool->createPoolImage(
|
|
"CloudComputeDepth",
|
|
sceneDepthZ.getExtent().width / kDownSampleSize,
|
|
sceneDepthZ.getExtent().height / kDownSampleSize,
|
|
VK_FORMAT_R32_SFLOAT,
|
|
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
|
|
);
|
|
|
|
inAtmosphere.transmittance->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
inAtmosphere.skyView->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
inAtmosphere.froxelScatter->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
|
|
|
|
|
|
auto newCloudReconstruction = computeCloud;
|
|
auto newCloudReconstructionDepth = computeCloudDepth;
|
|
|
|
if (bDownSample)
|
|
{
|
|
newCloudReconstruction = rtPool->createPoolImage(
|
|
"NewCloudReconstruction",
|
|
sceneDepthZ.getExtent().width,
|
|
sceneDepthZ.getExtent().height,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
|
|
newCloudReconstructionDepth = rtPool->createPoolImage(
|
|
"NewCloudReconstructionDepth",
|
|
sceneDepthZ.getExtent().width,
|
|
sceneDepthZ.getExtent().height,
|
|
VK_FORMAT_R32_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
}
|
|
|
|
|
|
VkClearColorValue zeroClear =
|
|
{
|
|
.uint32 = {0,0,0,0}
|
|
};
|
|
|
|
auto rangeClear = buildBasicImageSubresource();
|
|
if (!m_history.cloudReconstruction)
|
|
{
|
|
m_history.cloudReconstruction = rtPool->createPoolImage(
|
|
"CloudReconstruction",
|
|
sceneDepthZ.getExtent().width,
|
|
sceneDepthZ.getExtent().height,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
m_history.cloudReconstruction->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
|
|
m_bCameraCut = true;
|
|
|
|
vkCmdClearColorImage(cmd, m_history.cloudReconstruction->getImage().getImage(),
|
|
VK_IMAGE_LAYOUT_GENERAL, &zeroClear, 1, &rangeClear);
|
|
|
|
m_history.cloudReconstruction->getImage().
|
|
transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
|
|
}
|
|
if (!m_history.cloudReconstructionDepth)
|
|
{
|
|
m_history.cloudReconstructionDepth = rtPool->createPoolImage(
|
|
"CloudReconstructionDepth",
|
|
sceneDepthZ.getExtent().width,
|
|
sceneDepthZ.getExtent().height,
|
|
VK_FORMAT_R32_SFLOAT,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
|
m_history.cloudReconstructionDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
m_bCameraCut = true;
|
|
|
|
|
|
vkCmdClearColorImage(cmd, m_history.cloudReconstructionDepth->getImage().getImage(),
|
|
VK_IMAGE_LAYOUT_GENERAL, &zeroClear, 1, &rangeClear);
|
|
|
|
m_history.cloudReconstructionDepth->getImage().
|
|
transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
auto weatherTexture = std::dynamic_pointer_cast<GPUImageAsset>(getContext()->getBuiltinTexture(EBuiltinTextures::cloudWeather));
|
|
auto curlNoiseTexture = std::dynamic_pointer_cast<GPUImageAsset>(getContext()->getBuiltinTexture(EBuiltinTextures::cloudNoise));
|
|
auto curlTexture = std::dynamic_pointer_cast<GPUImageAsset>(getContext()->getBuiltinTexture(EBuiltinTextures::curlNoise));
|
|
|
|
|
|
CloudPush push{};
|
|
push.cascadeCount = perframe.sunLightInfo.cascadeConfig.cascadeCount;
|
|
|
|
for (int i = sunSDSMInfos.shadowDepths.size() - 1; i >= 0; i--)
|
|
{
|
|
push.sdsmShadowDepthIndices[i] =
|
|
sunSDSMInfos.shadowDepths[i]->getImage().getOrCreateView(
|
|
RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)).srvBindless;
|
|
}
|
|
|
|
|
|
auto pushCommonSet = [&]()
|
|
{
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addUAV(sceneColorHdr)
|
|
.addSRV(sceneColorHdr)
|
|
.addUAV(computeCloud)
|
|
.addSRV(computeCloud)
|
|
.addSRV(inGBuffers->hzbFurthest)
|
|
.addSRV(curlTexture->getSelfImage())
|
|
.addSRV(*getRenderer()->getSharedTextures().cloudBasicNoise, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D)
|
|
.addSRV(*getRenderer()->getSharedTextures().cloudDetailNoise, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D)
|
|
.addSRV(weatherTexture->getSelfImage()) // 8
|
|
.addSRV(curlNoiseTexture->getSelfImage()) // 8
|
|
.addSRV(inAtmosphere.transmittance) // 10
|
|
.addSRV(inAtmosphere.froxelScatter, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 11
|
|
.addUAV(newCloudReconstruction) // 12
|
|
.addSRV(newCloudReconstruction) // 13
|
|
.addUAV(computeCloudDepth) // 14
|
|
.addSRV(computeCloudDepth) // 15
|
|
.addUAV(newCloudReconstructionDepth) // 16
|
|
.addSRV(newCloudReconstructionDepth) // 17
|
|
.addSRV(m_history.cloudReconstruction) // 18
|
|
.addSRV(m_history.cloudReconstructionDepth) // 19
|
|
.addSRV(inAtmosphere.distantGrid, buildBasicImageSubresource(), VK_IMAGE_VIEW_TYPE_3D) // 20
|
|
.addBuffer(perFrameGPU) // 21
|
|
.addSRV(skyContext.skylightRadiance, buildBasicImageSubresourceCube(), VK_IMAGE_VIEW_TYPE_CUBE)
|
|
.addSRV(cloudDistanceLit)
|
|
.addUAV(m_history.cloudShadowDepthHistory)
|
|
.addSRV(m_history.cloudShadowDepthHistory)
|
|
.addBuffer(sunSDSMInfos.cascadeInfoBuffer)
|
|
.addSRV(fogFullImage)
|
|
.addSRV(fogFullImage)
|
|
.addSRV(m_history.prevHZBClosest ? m_history.prevHZBClosest : inGBuffers->hzbClosest)
|
|
.addSRV(inGBuffers->hzbClosest)
|
|
.push(pass->computeCloudPipeline);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
getRenderer()->getBlueNoise().spp_1_buffer.set,
|
|
getContext()->getBindlessTexture().getSet()
|
|
};
|
|
pass->computeCloudPipeline->bindSet(cmd, additionalSets, 1);
|
|
};
|
|
|
|
pass->computeCloudPipeline->pushConst(cmd, &push);
|
|
|
|
cloudDistanceLit->getImage().transitionShaderReadOnly(cmd);
|
|
|
|
pushCommonSet();
|
|
{
|
|
computeCloud->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
computeCloudDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
pass->computeCloudPipeline->bind(cmd);
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(computeCloud->getImage().getExtent().width, 8),
|
|
getGroupCount(computeCloud->getImage().getExtent().height, 8), 1);
|
|
|
|
computeCloud->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
computeCloudDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
if(bDownSample)
|
|
{
|
|
newCloudReconstruction->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
newCloudReconstructionDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
pass->reconstructionPipeline->bind(cmd);
|
|
|
|
vkCmdDispatch(cmd,
|
|
getGroupCount(newCloudReconstruction->getImage().getExtent().width, 8),
|
|
getGroupCount(newCloudReconstruction->getImage().getExtent().height, 8), 1);
|
|
|
|
newCloudReconstruction->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
newCloudReconstructionDepth->getImage().transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
}
|
|
|
|
{
|
|
sceneColorHdr.transitionLayout(cmd, VK_IMAGE_LAYOUT_GENERAL, buildBasicImageSubresource());
|
|
|
|
pass->compositeCloudPipeline->bind(cmd);
|
|
vkCmdDispatch(cmd, getGroupCount(sceneColorHdr.getExtent().width, 8), getGroupCount(sceneColorHdr.getExtent().height, 8), 1);
|
|
sceneColorHdr.transitionLayout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, buildBasicImageSubresource());
|
|
|
|
}
|
|
|
|
m_history.cloudReconstruction = newCloudReconstruction;
|
|
m_history.cloudReconstructionDepth = newCloudReconstructionDepth;
|
|
};
|
|
|
|
computeCloud();
|
|
|
|
auto lensSSBO = getContext()->getBufferParameters().getStaticStorage("SSBOLensBuffer", sizeof(float) * 4);
|
|
{
|
|
std::array<VkBufferMemoryBarrier2, 1> beginBufferBarriers
|
|
{
|
|
RHIBufferBarrier(lensSSBO->getBuffer()->getVkBuffer(),
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT,
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT),
|
|
};
|
|
RHIPipelineBarrier(cmd, 0, (uint32_t)beginBufferBarriers.size(), beginBufferBarriers.data(), 0, nullptr);
|
|
|
|
PushSetBuilder setBuilder(cmd);
|
|
setBuilder
|
|
.addBuffer(lensSSBO)
|
|
.addBuffer(perFrameGPU)
|
|
.addSRV(sceneDepthZ, RHIDefaultImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT))
|
|
.addSRV(fogFullImage)
|
|
.addSRV(m_history.cloudReconstruction ? m_history.cloudReconstruction->getImage() : gbufferA)
|
|
.addSRV(inAtmosphere.transmittance)
|
|
.push(pass->lensPipe);
|
|
|
|
std::vector<VkDescriptorSet> additionalSets =
|
|
{
|
|
getContext()->getSamplerCache().getCommonDescriptorSet(),
|
|
};
|
|
pass->lensPipe->bindSet(cmd, additionalSets, 1);
|
|
|
|
|
|
LensPush push{
|
|
.bCloud = bExistCloud ? 1U : 0U,
|
|
.bFog = 1U,
|
|
};
|
|
pass->lensPipe->bindAndPushConst(cmd, &push);
|
|
|
|
vkCmdDispatch(cmd, 1, 1, 1);
|
|
|
|
std::array<VkBufferMemoryBarrier2, 1> endBufferBarriers
|
|
{
|
|
RHIBufferBarrier(lensSSBO->getBuffer()->getVkBuffer(),
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT),
|
|
};
|
|
RHIPipelineBarrier(cmd, 0, (uint32_t)endBufferBarriers.size(), endBufferBarriers.data(), 0, nullptr);
|
|
|
|
inGBuffers->lensBuffer = lensSSBO;
|
|
}
|
|
|
|
|
|
m_gpuTimer.getTimeStamp(cmd, "Volumetric Cloud");
|
|
}
|
|
} |