|
@@ -20,8 +20,6 @@ Volumetric::~Volumetric()
|
|
|
|
|
|
|
|
Error Volumetric::init(const ConfigSet& config)
|
|
Error Volumetric::init(const ConfigSet& config)
|
|
|
{
|
|
{
|
|
|
- ANKI_LOGI("Initializing volumetric pass");
|
|
|
|
|
-
|
|
|
|
|
Error err = initInternal(config);
|
|
Error err = initInternal(config);
|
|
|
if(err)
|
|
if(err)
|
|
|
{
|
|
{
|
|
@@ -33,15 +31,17 @@ Error Volumetric::init(const ConfigSet& config)
|
|
|
|
|
|
|
|
Error Volumetric::initInternal(const ConfigSet& config)
|
|
Error Volumetric::initInternal(const ConfigSet& config)
|
|
|
{
|
|
{
|
|
|
- U width = m_r->getWidth() / VOLUMETRIC_FRACTION;
|
|
|
|
|
- U height = m_r->getHeight() / VOLUMETRIC_FRACTION;
|
|
|
|
|
|
|
+ m_width = m_r->getWidth() / VOLUMETRIC_FRACTION;
|
|
|
|
|
+ m_height = m_r->getHeight() / VOLUMETRIC_FRACTION;
|
|
|
|
|
+
|
|
|
|
|
+ ANKI_LOGI("Initializing volumetric pass. Size %ux%u", m_width, m_height);
|
|
|
|
|
|
|
|
// Misc
|
|
// Misc
|
|
|
ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_noiseTex));
|
|
ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_noiseTex));
|
|
|
|
|
|
|
|
// Create RTs
|
|
// Create RTs
|
|
|
- m_r->createRenderTarget(width,
|
|
|
|
|
- height,
|
|
|
|
|
|
|
+ m_r->createRenderTarget(m_width,
|
|
|
|
|
+ m_height,
|
|
|
IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
|
|
IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
|
|
|
TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE | TextureUsageBit::CLEAR,
|
|
TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE | TextureUsageBit::CLEAR,
|
|
|
SamplingFilter::LINEAR,
|
|
SamplingFilter::LINEAR,
|
|
@@ -50,28 +50,68 @@ Error Volumetric::initInternal(const ConfigSet& config)
|
|
|
|
|
|
|
|
m_r->clearRenderTarget(m_rt, ClearValue(), TextureUsageBit::SAMPLED_FRAGMENT);
|
|
m_r->clearRenderTarget(m_rt, ClearValue(), TextureUsageBit::SAMPLED_FRAGMENT);
|
|
|
|
|
|
|
|
- // Create shaders
|
|
|
|
|
|
|
+ m_r->createRenderTarget(m_width,
|
|
|
|
|
+ m_height,
|
|
|
|
|
+ IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
|
|
|
|
|
+ TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
|
|
|
|
|
+ SamplingFilter::LINEAR,
|
|
|
|
|
+ 1,
|
|
|
|
|
+ m_hRt);
|
|
|
|
|
+
|
|
|
|
|
+ // Create FBs
|
|
|
|
|
+ FramebufferInitInfo fbInit;
|
|
|
|
|
+ fbInit.m_colorAttachmentCount = 1;
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_texture = m_rt;
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
|
|
|
|
|
+ m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
|
|
|
|
|
+
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_texture = m_rt;
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
|
|
|
|
|
+ m_vFb = getGrManager().newInstance<Framebuffer>(fbInit);
|
|
|
|
|
+
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_texture = m_hRt;
|
|
|
|
|
+ fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
|
|
|
|
|
+ m_hFb = getGrManager().newInstance<Framebuffer>(fbInit);
|
|
|
|
|
+
|
|
|
|
|
+ // Create shaders and progs
|
|
|
ANKI_CHECK(m_r->createShaderf("shaders/Volumetric.frag.glsl",
|
|
ANKI_CHECK(m_r->createShaderf("shaders/Volumetric.frag.glsl",
|
|
|
m_frag,
|
|
m_frag,
|
|
|
"#define FB_SIZE uvec2(%uu, %uu)\n"
|
|
"#define FB_SIZE uvec2(%uu, %uu)\n"
|
|
|
"#define CLUSTER_COUNT uvec3(%uu, %uu, %uu)\n"
|
|
"#define CLUSTER_COUNT uvec3(%uu, %uu, %uu)\n"
|
|
|
"#define NOISE_MAP_SIZE %u\n",
|
|
"#define NOISE_MAP_SIZE %u\n",
|
|
|
- width,
|
|
|
|
|
- height,
|
|
|
|
|
|
|
+ m_width,
|
|
|
|
|
+ m_height,
|
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountX(),
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountX(),
|
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountY(),
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountY(),
|
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountZ(),
|
|
m_r->getIs().getLightBin().getClusterer().getClusterCountZ(),
|
|
|
m_noiseTex->getWidth()));
|
|
m_noiseTex->getWidth()));
|
|
|
|
|
|
|
|
- // Create prog
|
|
|
|
|
m_r->createDrawQuadShaderProgram(m_frag->getGrShader(), m_prog);
|
|
m_r->createDrawQuadShaderProgram(m_frag->getGrShader(), m_prog);
|
|
|
|
|
|
|
|
- // Create FBs
|
|
|
|
|
- FramebufferInitInfo fbInit;
|
|
|
|
|
- fbInit.m_colorAttachmentCount = 1;
|
|
|
|
|
- fbInit.m_colorAttachments[0].m_texture = m_rt;
|
|
|
|
|
- fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
|
|
|
|
|
- m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
|
|
|
|
|
|
|
+ // const char* shader = "shaders/DepthAwareBlurGeneric.frag.glsl";
|
|
|
|
|
+ // const char* shader = "shaders/GaussianBlurGeneric.frag.glsl";
|
|
|
|
|
+ const char* shader = "shaders/LumaAwareBlurGeneric.frag.glsl";
|
|
|
|
|
+ ANKI_CHECK(m_r->createShaderf(shader,
|
|
|
|
|
+ m_hFrag,
|
|
|
|
|
+ "#define HPASS\n"
|
|
|
|
|
+ "#define COL_RGB\n"
|
|
|
|
|
+ "#define TEXTURE_SIZE vec2(%f, %f)\n"
|
|
|
|
|
+ "#define KERNEL_SIZE 11\n",
|
|
|
|
|
+ F32(m_width),
|
|
|
|
|
+ F32(m_height)));
|
|
|
|
|
+
|
|
|
|
|
+ m_r->createDrawQuadShaderProgram(m_hFrag->getGrShader(), m_hProg);
|
|
|
|
|
+
|
|
|
|
|
+ ANKI_CHECK(m_r->createShaderf(shader,
|
|
|
|
|
+ m_vFrag,
|
|
|
|
|
+ "#define VPASS\n"
|
|
|
|
|
+ "#define COL_RGB\n"
|
|
|
|
|
+ "#define TEXTURE_SIZE vec2(%f, %f)\n"
|
|
|
|
|
+ "#define KERNEL_SIZE 11\n",
|
|
|
|
|
+ F32(m_width),
|
|
|
|
|
+ F32(m_height)));
|
|
|
|
|
+
|
|
|
|
|
+ m_r->createDrawQuadShaderProgram(m_vFrag->getGrShader(), m_vProg);
|
|
|
|
|
|
|
|
return ErrorCode::NONE;
|
|
return ErrorCode::NONE;
|
|
|
}
|
|
}
|
|
@@ -79,7 +119,7 @@ Error Volumetric::initInternal(const ConfigSet& config)
|
|
|
void Volumetric::setPreRunBarriers(RenderingContext& ctx)
|
|
void Volumetric::setPreRunBarriers(RenderingContext& ctx)
|
|
|
{
|
|
{
|
|
|
ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
|
|
ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
|
|
|
- TextureUsageBit::NONE,
|
|
|
|
|
|
|
+ TextureUsageBit::SAMPLED_FRAGMENT,
|
|
|
TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
|
|
TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
|
|
|
TextureSurfaceInfo(0, 0, 0, 0));
|
|
TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
}
|
|
}
|
|
@@ -87,7 +127,7 @@ void Volumetric::setPreRunBarriers(RenderingContext& ctx)
|
|
|
void Volumetric::setPostRunBarriers(RenderingContext& ctx)
|
|
void Volumetric::setPostRunBarriers(RenderingContext& ctx)
|
|
|
{
|
|
{
|
|
|
ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
|
|
ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
|
|
|
- TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
|
|
|
|
|
|
|
+ TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
|
|
|
TextureUsageBit::SAMPLED_FRAGMENT,
|
|
TextureUsageBit::SAMPLED_FRAGMENT,
|
|
|
TextureSurfaceInfo(0, 0, 0, 0));
|
|
TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
}
|
|
}
|
|
@@ -97,8 +137,10 @@ void Volumetric::run(RenderingContext& ctx)
|
|
|
CommandBufferPtr& cmdb = ctx.m_commandBuffer;
|
|
CommandBufferPtr& cmdb = ctx.m_commandBuffer;
|
|
|
const Frustum& frc = ctx.m_frustumComponent->getFrustum();
|
|
const Frustum& frc = ctx.m_frustumComponent->getFrustum();
|
|
|
|
|
|
|
|
- // pass
|
|
|
|
|
- cmdb->setViewport(0, 0, m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION);
|
|
|
|
|
|
|
+ //
|
|
|
|
|
+ // Main pass
|
|
|
|
|
+ //
|
|
|
|
|
+ cmdb->setViewport(0, 0, m_width, m_height);
|
|
|
cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
|
|
cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
|
|
cmdb->bindTexture(0, 0, m_r->getDepthDownscale().m_qd.m_depthRt);
|
|
cmdb->bindTexture(0, 0, m_r->getDepthDownscale().m_qd.m_depthRt);
|
|
@@ -113,7 +155,7 @@ void Volumetric::run(RenderingContext& ctx)
|
|
|
Vec4* uniforms = allocateAndBindUniforms<Vec4*>(sizeof(Vec4) * 2, cmdb, 0, 3);
|
|
Vec4* uniforms = allocateAndBindUniforms<Vec4*>(sizeof(Vec4) * 2, cmdb, 0, 3);
|
|
|
computeLinearizeDepthOptimal(frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y());
|
|
computeLinearizeDepthOptimal(frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y());
|
|
|
|
|
|
|
|
- F32 texelOffset = (1.0 / m_noiseTex->getWidth()) * 1.0;
|
|
|
|
|
|
|
+ F32 texelOffset = 1.0 / m_noiseTex->getWidth();
|
|
|
uniforms[0].z() = m_r->getFrameCount() * texelOffset;
|
|
uniforms[0].z() = m_r->getFrameCount() * texelOffset;
|
|
|
uniforms[0].w() = m_r->getFrameCount() & (m_noiseTex->getLayerCount() - 1);
|
|
uniforms[0].w() = m_r->getFrameCount() & (m_noiseTex->getLayerCount() - 1);
|
|
|
|
|
|
|
@@ -130,6 +172,46 @@ void Volumetric::run(RenderingContext& ctx)
|
|
|
|
|
|
|
|
// Restore state
|
|
// Restore state
|
|
|
cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
|
|
cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->setTextureSurfaceBarrier(m_rt,
|
|
|
|
|
+ TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
|
|
|
|
|
+ TextureUsageBit::SAMPLED_FRAGMENT,
|
|
|
|
|
+ TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
|
|
+ cmdb->setTextureSurfaceBarrier(
|
|
|
|
|
+ m_hRt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
|
|
+
|
|
|
|
|
+ //
|
|
|
|
|
+ // H Blur pass
|
|
|
|
|
+ //
|
|
|
|
|
+ Vec4* buniforms = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
|
|
|
|
|
+ computeLinearizeDepthOptimal(frc.getNear(), frc.getFar(), buniforms[0].x(), buniforms[0].y());
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->bindTexture(0, 0, m_rt);
|
|
|
|
|
+ cmdb->bindTexture(0, 1, m_r->getDepthDownscale().m_qd.m_depthRt);
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->bindShaderProgram(m_hProg);
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->beginRenderPass(m_hFb);
|
|
|
|
|
+ m_r->drawQuad(cmdb);
|
|
|
|
|
+ cmdb->endRenderPass();
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->setTextureSurfaceBarrier(m_rt,
|
|
|
|
|
+ TextureUsageBit::SAMPLED_FRAGMENT,
|
|
|
|
|
+ TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
|
|
|
|
|
+ TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
|
|
+ cmdb->setTextureSurfaceBarrier(m_hRt,
|
|
|
|
|
+ TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
|
|
|
|
|
+ TextureUsageBit::SAMPLED_FRAGMENT,
|
|
|
|
|
+ TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
|
|
+
|
|
|
|
|
+ //
|
|
|
|
|
+ // V Blur pass
|
|
|
|
|
+ //
|
|
|
|
|
+ cmdb->bindTexture(0, 0, m_hRt);
|
|
|
|
|
+ cmdb->bindShaderProgram(m_vProg);
|
|
|
|
|
+ cmdb->beginRenderPass(m_vFb);
|
|
|
|
|
+ m_r->drawQuad(cmdb);
|
|
|
|
|
+ cmdb->endRenderPass();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // end namespace anki
|
|
} // end namespace anki
|