mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 11:13:27 +02:00
Performing the curvature generation and diffusion at half the resolution
This commit is contained in:
parent
378f4576fa
commit
5a0ce81516
11 changed files with 223 additions and 58 deletions
libraries
render-utils/src
DebugDeferredBuffer.cppDebugDeferredBuffer.hRenderDeferredTask.cppSurfaceGeometryPass.cppSurfaceGeometryPass.hdebug_deferred_buffer.slfsurfaceGeometry_makeCurvature.slf
render/src/render
scripts/developer/utilities/render
|
@ -46,7 +46,9 @@ enum Slot {
|
|||
Depth,
|
||||
Lighting,
|
||||
Shadow,
|
||||
Pyramid,
|
||||
LinearDepth,
|
||||
HalfLinearDepth,
|
||||
HalfNormal,
|
||||
Curvature,
|
||||
DiffusedCurvature,
|
||||
Scattering,
|
||||
|
@ -141,16 +143,21 @@ static const std::string DEFAULT_SHADOW_SHADER {
|
|||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_PYRAMID_DEPTH_SHADER {
|
||||
static const std::string DEFAULT_LINEAR_DEPTH_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);"
|
||||
" return vec4(vec3(1.0 - texture(linearDepthMap, uv).x * 0.01), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_LINEAR_DEPTH_2_SHADER{
|
||||
static const std::string DEFAULT_HALF_LINEAR_DEPTH_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
// " return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);"
|
||||
" return vec4(vec3(1.0 - textureLod(pyramidMap, uv, 1).x * 0.01), 1.0);"
|
||||
" return vec4(vec3(1.0 - texture(halfLinearDepthMap, uv).x * 0.01), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_HALF_NORMAL_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(halfNormalMap, uv).xyz), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
|
@ -259,9 +266,11 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
|||
case ShadowMode:
|
||||
return DEFAULT_SHADOW_SHADER;
|
||||
case LinearDepthMode:
|
||||
return DEFAULT_PYRAMID_DEPTH_SHADER;
|
||||
case LinearDepth2Mode:
|
||||
return DEFAULT_LINEAR_DEPTH_2_SHADER;
|
||||
return DEFAULT_LINEAR_DEPTH_SHADER;
|
||||
case HalfLinearDepthMode:
|
||||
return DEFAULT_HALF_LINEAR_DEPTH_SHADER;
|
||||
case HalfNormalMode:
|
||||
return DEFAULT_HALF_NORMAL_SHADER;
|
||||
case CurvatureMode:
|
||||
return DEFAULT_CURVATURE_SHADER;
|
||||
case NormalCurvatureMode:
|
||||
|
@ -325,7 +334,9 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
|||
slotBindings.insert(gpu::Shader::Binding("obscuranceMap", AmbientOcclusion));
|
||||
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
|
||||
slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
|
||||
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
|
||||
slotBindings.insert(gpu::Shader::Binding("linearDepthMap", LinearDepth));
|
||||
slotBindings.insert(gpu::Shader::Binding("halfLinearDepthMap", HalfLinearDepth));
|
||||
slotBindings.insert(gpu::Shader::Binding("halfNormalMap", HalfNormal));
|
||||
slotBindings.insert(gpu::Shader::Binding("curvatureMap", Curvature));
|
||||
slotBindings.insert(gpu::Shader::Binding("diffusedCurvatureMap", DiffusedCurvature));
|
||||
slotBindings.insert(gpu::Shader::Binding("scatteringMap", Scattering));
|
||||
|
@ -364,8 +375,9 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
RenderArgs* args = renderContext->args;
|
||||
|
||||
auto& deferredFramebuffer = inputs.get0();
|
||||
auto& surfaceGeometryFramebuffer = inputs.get1();
|
||||
auto& diffusedCurvatureFramebuffer = inputs.get2();
|
||||
auto& linearDepthTarget = inputs.get1();
|
||||
auto& surfaceGeometryFramebuffer = inputs.get2();
|
||||
auto& diffusedCurvatureFramebuffer = inputs.get3();
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
@ -395,7 +407,10 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
|
||||
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
|
||||
batch.setResourceTexture(Pyramid, surfaceGeometryFramebuffer->getLinearDepthTexture());
|
||||
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
|
||||
batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture());
|
||||
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
|
||||
|
||||
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
|
||||
batch.setResourceTexture(DiffusedCurvature, diffusedCurvatureFramebuffer->getRenderBuffer(0));
|
||||
if (DependencyManager::get<DeferredLightingEffect>()->isAmbientOcclusionEnabled()) {
|
||||
|
|
|
@ -36,7 +36,7 @@ signals:
|
|||
|
||||
class DebugDeferredBuffer {
|
||||
public:
|
||||
using Inputs = render::VaryingSet3<DeferredFramebufferPointer, SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Inputs = render::VaryingSet4<DeferredFramebufferPointer, LinearDepthFramebufferPointer, SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Config = DebugDeferredBufferConfig;
|
||||
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;
|
||||
|
||||
|
@ -64,7 +64,8 @@ protected:
|
|||
LightingMode,
|
||||
ShadowMode,
|
||||
LinearDepthMode,
|
||||
LinearDepth2Mode,
|
||||
HalfLinearDepthMode,
|
||||
HalfNormalMode,
|
||||
CurvatureMode,
|
||||
NormalCurvatureMode,
|
||||
DiffusedCurvatureMode,
|
||||
|
|
|
@ -125,6 +125,8 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
const auto linearDepthPassOutputs = addJob<LinearDepthPass>("LinearDepth", linearDepthPassInputs);
|
||||
const auto linearDepthTarget = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(0);
|
||||
const auto linearDepthTexture = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(2);
|
||||
const auto halfLinearDepthTexture = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(3);
|
||||
const auto halfNormalTexture = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(4);
|
||||
|
||||
|
||||
// Curvature pass
|
||||
|
@ -136,7 +138,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
const auto curvatureRangeTimer = addJob<BeginGPURangeTimer>("BeginCurvatureRangeTimer");
|
||||
|
||||
// TODO: Push this 2 diffusion stages into surfaceGeometryPass as they are working together
|
||||
const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, linearDepthTexture).hasVarying();
|
||||
const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, halfLinearDepthTexture).hasVarying();
|
||||
const auto midCurvatureNormalFramebuffer = addJob<render::BlurGaussianDepthAware>("DiffuseCurvatureMid", diffuseCurvaturePassInputs);
|
||||
const auto lowCurvatureNormalFramebuffer = addJob<render::BlurGaussianDepthAware>("DiffuseCurvatureLow", diffuseCurvaturePassInputs, true); // THis blur pass generates it s render resource
|
||||
|
||||
|
@ -182,7 +184,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
addJob<DebugSubsurfaceScattering>("DebugScattering", deferredLightingInputs);
|
||||
|
||||
// Debugging Deferred buffer job
|
||||
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer));
|
||||
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer));
|
||||
addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers);
|
||||
|
||||
// Scene Octree Debuging job
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
const int DepthLinearPass_FrameTransformSlot = 0;
|
||||
const int DepthLinearPass_DepthMapSlot = 0;
|
||||
const int DepthLinearPass_NormalMapSlot = 1;
|
||||
|
||||
const int SurfaceGeometryPass_FrameTransformSlot = 0;
|
||||
const int SurfaceGeometryPass_ParamsSlot = 1;
|
||||
|
@ -25,6 +26,7 @@ const int SurfaceGeometryPass_DepthMapSlot = 0;
|
|||
const int SurfaceGeometryPass_NormalMapSlot = 1;
|
||||
|
||||
#include "surfaceGeometry_makeLinearDepth_frag.h"
|
||||
#include "surfaceGeometry_downsampleDepthNormal_frag.h"
|
||||
|
||||
#include "surfaceGeometry_makeCurvature_frag.h"
|
||||
|
||||
|
@ -45,6 +47,8 @@ void LinearDepthFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depth
|
|||
auto newFrameSize = glm::ivec2(_primaryDepthTexture->getDimensions());
|
||||
if (_frameSize != newFrameSize) {
|
||||
_frameSize = newFrameSize;
|
||||
_halfFrameSize = newFrameSize >> 1;
|
||||
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +71,21 @@ void LinearDepthFramebuffer::allocate() {
|
|||
// For Linear Depth:
|
||||
_linearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_linearDepthTexture->autoGenerateMips(1);
|
||||
// _linearDepthTexture->autoGenerateMips(1);
|
||||
_linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture);
|
||||
_linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
|
||||
|
||||
// For Downsampling:
|
||||
_halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
|
||||
_halfNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
|
||||
_downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_downsampleFramebuffer->setRenderBuffer(0, _halfLinearDepthTexture);
|
||||
_downsampleFramebuffer->setRenderBuffer(1, _halfNormalTexture);
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer LinearDepthFramebuffer::getLinearDepthFramebuffer() {
|
||||
|
@ -87,6 +102,27 @@ gpu::TexturePointer LinearDepthFramebuffer::getLinearDepthTexture() {
|
|||
return _linearDepthTexture;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer LinearDepthFramebuffer::getDownsampleFramebuffer() {
|
||||
if (!_downsampleFramebuffer) {
|
||||
allocate();
|
||||
}
|
||||
return _downsampleFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer LinearDepthFramebuffer::getHalfLinearDepthTexture() {
|
||||
if (!_halfLinearDepthTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _halfLinearDepthTexture;
|
||||
}
|
||||
|
||||
gpu::TexturePointer LinearDepthFramebuffer::getHalfNormalTexture() {
|
||||
if (!_halfNormalTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _halfNormalTexture;
|
||||
}
|
||||
|
||||
|
||||
LinearDepthPass::LinearDepthPass() {
|
||||
}
|
||||
|
@ -114,13 +150,21 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const
|
|||
auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer();
|
||||
auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture();
|
||||
|
||||
auto downsampleFBO = _linearDepthFramebuffer->getDownsampleFramebuffer();
|
||||
auto halfLinearDepthTexture = _linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||
auto halfNormalTexture = _linearDepthFramebuffer->getHalfNormalTexture();
|
||||
|
||||
outputs.edit0() = _linearDepthFramebuffer;
|
||||
outputs.edit1() = linearDepthFBO;
|
||||
outputs.edit2() = linearDepthTexture;
|
||||
|
||||
outputs.edit3() = halfLinearDepthTexture;
|
||||
outputs.edit4() = halfNormalTexture;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline();
|
||||
auto downsamplePipeline = getDownsamplePipeline();
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
auto halfViewport = depthViewport >> 1;
|
||||
auto furtherDepth = std::numeric_limits<float>::infinity();
|
||||
furtherDepth = args->getViewFrustum().getFarClip() + 10.0;
|
||||
|
||||
|
@ -135,15 +179,21 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const
|
|||
|
||||
batch.setUniformBuffer(DepthLinearPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
|
||||
// Pyramid pass
|
||||
// LinearDepth
|
||||
batch.setFramebuffer(linearDepthFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(furtherDepth, 0.0f, 0.0f, 0.0f));
|
||||
batch.setPipeline(linearDepthPipeline);
|
||||
batch.setResourceTexture(DepthLinearPass_DepthMapSlot, depthBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
// batch.setResourceTexture(DepthLinearPass_DepthMapSlot, nullptr);
|
||||
// batch.generateTextureMips(linearDepthFBO->getRenderBuffer(0));
|
||||
// Downsample
|
||||
batch.setViewportTransform(halfViewport);
|
||||
|
||||
batch.setFramebuffer(downsampleFBO);
|
||||
batch.setResourceTexture(DepthLinearPass_DepthMapSlot, linearDepthTexture);
|
||||
batch.setResourceTexture(DepthLinearPass_NormalMapSlot, normalTexture);
|
||||
batch.setPipeline(downsamplePipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
_gpuTimer.end(batch);
|
||||
});
|
||||
|
@ -180,6 +230,32 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
|
|||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
|
||||
if (!_downsamplePipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_downsampleDepthNormal_frag));
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), DepthLinearPass_DepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DepthLinearPass_NormalMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setColorWriteMask(true, true, true, false);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_downsamplePipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
return _downsamplePipeline;
|
||||
}
|
||||
|
||||
|
||||
//#define USE_STENCIL_TEST
|
||||
|
||||
SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() {
|
||||
}
|
||||
|
@ -280,19 +356,22 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
const auto deferredFramebuffer = inputs.get1();
|
||||
const auto linearDepthFramebuffer = inputs.get2();
|
||||
|
||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||
auto linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||
|
||||
if (!_surfaceGeometryFramebuffer) {
|
||||
_surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>();
|
||||
}
|
||||
_surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture);
|
||||
|
||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
// auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
auto normalTexture = linearDepthFramebuffer->getHalfNormalTexture();
|
||||
|
||||
auto curvatureFBO = _surfaceGeometryFramebuffer->getCurvatureFramebuffer();
|
||||
#ifdef USE_STENCIL_TEST
|
||||
if (curvatureFBO->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) {
|
||||
curvatureFBO->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat());
|
||||
}
|
||||
#endif
|
||||
auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture();
|
||||
|
||||
outputs.edit0() = _surfaceGeometryFramebuffer;
|
||||
|
@ -301,7 +380,8 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
auto curvaturePipeline = getCurvaturePipeline();
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
auto curvatureViewport = depthViewport >> _surfaceGeometryFramebuffer->getResolutionLevel();
|
||||
auto curvatureViewport = depthViewport >> 1;
|
||||
// >> _surfaceGeometryFramebuffer->getResolutionLevel();
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
_gpuTimer.begin(batch);
|
||||
|
@ -318,9 +398,13 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
|
||||
// Curvature pass
|
||||
batch.setFramebuffer(curvatureFBO);
|
||||
|
||||
// We can avoid the clear by drawing the same clear vallue from the makeCUrvature shader. slightly better than adding the clear
|
||||
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
|
||||
// We can avoid the clear by drawing the same clear vallue from the makeCurvature shader. same performances or no worse
|
||||
|
||||
#ifdef USE_STENCIL_TEST
|
||||
// Except if stenciling out
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
#endif
|
||||
|
||||
batch.setPipeline(curvaturePipeline);
|
||||
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture);
|
||||
|
@ -354,9 +438,10 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
|
|||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
#ifdef USE_STENCIL_TEST
|
||||
// Stencil test the curvature pass for objects pixels only, not the background
|
||||
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
|
||||
#endif
|
||||
// Good to go add the brand new pipeline
|
||||
_curvaturePipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ public:
|
|||
gpu::FramebufferPointer getLinearDepthFramebuffer();
|
||||
gpu::TexturePointer getLinearDepthTexture();
|
||||
|
||||
gpu::FramebufferPointer getDownsampleFramebuffer();
|
||||
gpu::TexturePointer getHalfLinearDepthTexture();
|
||||
gpu::TexturePointer getHalfNormalTexture();
|
||||
|
||||
// Update the depth buffer which will drive the allocation of all the other resources according to its size.
|
||||
void updatePrimaryDepth(const gpu::TexturePointer& depthBuffer);
|
||||
gpu::TexturePointer getPrimaryDepthTexture();
|
||||
|
@ -44,8 +48,14 @@ protected:
|
|||
|
||||
gpu::FramebufferPointer _linearDepthFramebuffer;
|
||||
gpu::TexturePointer _linearDepthTexture;
|
||||
|
||||
gpu::FramebufferPointer _downsampleFramebuffer;
|
||||
gpu::TexturePointer _halfLinearDepthTexture;
|
||||
gpu::TexturePointer _halfNormalTexture;
|
||||
|
||||
|
||||
glm::ivec2 _frameSize;
|
||||
glm::ivec2 _halfFrameSize;
|
||||
int _resolutionLevel{ 0 };
|
||||
};
|
||||
|
||||
|
@ -69,7 +79,7 @@ signals:
|
|||
class LinearDepthPass {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<DeferredFrameTransformPointer, DeferredFramebufferPointer>;
|
||||
using Outputs = render::VaryingSet3<LinearDepthFramebufferPointer, gpu::FramebufferPointer, gpu::TexturePointer>;
|
||||
using Outputs = render::VaryingSet5<LinearDepthFramebufferPointer, gpu::FramebufferPointer, gpu::TexturePointer, gpu::TexturePointer, gpu::TexturePointer>;
|
||||
using Config = LinearDepthPassConfig;
|
||||
using JobModel = render::Job::ModelIO<LinearDepthPass, Inputs, Outputs, Config>;
|
||||
|
||||
|
@ -84,9 +94,11 @@ private:
|
|||
LinearDepthFramebufferPointer _linearDepthFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getLinearDepthPipeline();
|
||||
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
|
||||
const gpu::PipelinePointer& getDownsamplePipeline();
|
||||
gpu::PipelinePointer _downsamplePipeline;
|
||||
|
||||
gpu::RangeTimer _gpuTimer;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
<@include DeferredBufferRead.slh@>
|
||||
|
||||
uniform sampler2D pyramidMap;
|
||||
uniform sampler2D linearDepthMap;
|
||||
uniform sampler2D halfLinearDepthMap;
|
||||
uniform sampler2D halfNormalMap;
|
||||
uniform sampler2D occlusionMap;
|
||||
uniform sampler2D occlusionBlurredMap;
|
||||
uniform sampler2D curvatureMap;
|
||||
|
|
|
@ -78,8 +78,10 @@ vec3 getRawNormal(vec2 texcoord) {
|
|||
}
|
||||
|
||||
vec3 getWorldNormal(vec2 texcoord) {
|
||||
// vec3 rawNormal = getRawNormal(texcoord);
|
||||
// return unpackNormal(rawNormal);
|
||||
vec3 rawNormal = getRawNormal(texcoord);
|
||||
return unpackNormal(rawNormal);
|
||||
return normalize((rawNormal - vec3(0.5)) * 2.0);
|
||||
}
|
||||
|
||||
vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) {
|
||||
|
|
|
@ -101,9 +101,9 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
|
|||
_blurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
|
||||
// attach depthStencil if present in source
|
||||
if (sourceFramebuffer->hasDepthStencil()) {
|
||||
_blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
}
|
||||
//if (sourceFramebuffer->hasDepthStencil()) {
|
||||
// _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
//}
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT);
|
||||
auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler));
|
||||
_blurredFramebuffer->setRenderBuffer(0, blurringTarget);
|
||||
|
@ -111,9 +111,9 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
|
|||
// it would be easier to just call resize on the bluredFramebuffer and let it work if needed but the source might loose it's depth buffer when doing so
|
||||
if ((_blurredFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_blurredFramebuffer->getHeight() != sourceFramebuffer->getHeight())) {
|
||||
_blurredFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples());
|
||||
if (sourceFramebuffer->hasDepthStencil()) {
|
||||
_blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
}
|
||||
//if (sourceFramebuffer->hasDepthStencil()) {
|
||||
// _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,18 +128,18 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
|
|||
_outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
|
||||
// attach depthStencil if present in source
|
||||
if (sourceFramebuffer->hasDepthStencil()) {
|
||||
/* if (sourceFramebuffer->hasDepthStencil()) {
|
||||
_outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
}
|
||||
}*/
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT);
|
||||
auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler));
|
||||
_outputFramebuffer->setRenderBuffer(0, blurringTarget);
|
||||
} else {
|
||||
if ((_outputFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_outputFramebuffer->getHeight() != sourceFramebuffer->getHeight())) {
|
||||
_outputFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples());
|
||||
if (sourceFramebuffer->hasDepthStencil()) {
|
||||
/* if (sourceFramebuffer->hasDepthStencil()) {
|
||||
_outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ gpu::PipelinePointer BlurGaussian::getBlurVPipeline() {
|
|||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// Stencil test the curvature pass for objects pixels only, not the background
|
||||
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
// state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
|
||||
_blurVPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ gpu::PipelinePointer BlurGaussian::getBlurHPipeline() {
|
|||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// Stencil test the curvature pass for objects pixels only, not the background
|
||||
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
// state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
|
||||
_blurHPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
@ -336,22 +336,25 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
|
|||
auto blurVPipeline = getBlurVPipeline();
|
||||
auto blurHPipeline = getBlurHPipeline();
|
||||
|
||||
_parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->_context->isStereo());
|
||||
auto sourceViewport = args->_viewport;
|
||||
auto blurViewport = sourceViewport >> 1;
|
||||
|
||||
_parameters->setWidthHeight(blurViewport.z, blurViewport.w, args->_context->isStereo());
|
||||
glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions());
|
||||
_parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, args->_viewport));
|
||||
_parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, blurViewport));
|
||||
_parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]);
|
||||
_parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip());
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setViewportTransform(blurViewport);
|
||||
|
||||
batch.setUniformBuffer(BlurTask_ParamsSlot, _parameters->_parametersBuffer);
|
||||
|
||||
batch.setResourceTexture(BlurTask_DepthSlot, depthTexture);
|
||||
|
||||
batch.setFramebuffer(blurringResources.blurringFramebuffer);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
|
||||
batch.setPipeline(blurVPipeline);
|
||||
batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.sourceTexture);
|
||||
|
@ -359,7 +362,7 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
|
|||
|
||||
batch.setFramebuffer(blurringResources.finalFramebuffer);
|
||||
if (_inOutResources._generateOutputFramebuffer) {
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
}
|
||||
|
||||
batch.setPipeline(blurHPipeline);
|
||||
|
|
|
@ -95,14 +95,22 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
|||
uniform sampler2D sourceMap;
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
#define NUM_HALF_TAPS 4
|
||||
|
||||
const float gaussianDistributionCurveHalf[NUM_HALF_TAPS] = float[](
|
||||
0.383f, 0.242f, 0.061f, 0.006f
|
||||
);
|
||||
const float gaussianDistributionOffsetHalf[NUM_HALF_TAPS] = float[](
|
||||
0.0f, 1.0f, 2.0f, 3.0f
|
||||
);
|
||||
|
||||
vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
||||
texcoord = evalTexcoordTransformed(texcoord);
|
||||
float sampleDepth = texture(depthMap, texcoord).x;
|
||||
vec4 sampleCenter = texture(sourceMap, texcoord);
|
||||
if (sampleDepth >= getPosLinearDepthFar()) {
|
||||
discard;
|
||||
//return sampleCenter;
|
||||
}
|
||||
vec4 sampleCenter = texture(sourceMap, texcoord);
|
||||
|
||||
// Calculate the width scale.
|
||||
float distanceToProjectionWindow = getDepthPerspective();
|
||||
|
@ -117,21 +125,40 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
|
|||
|
||||
// Accumulate the center sample
|
||||
vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter;
|
||||
|
||||
for(int i = 1; i < NUM_TAPS; i++) {
|
||||
|
||||
/* for(int i = 1; i < NUM_TAPS; i++) {
|
||||
// Fetch color and depth for current sample.
|
||||
vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep);
|
||||
float srcDepth = texture(depthMap, sampleCoord).x;
|
||||
vec4 srcSample = texture(sourceMap, sampleCoord);
|
||||
|
||||
|
||||
|
||||
// If the difference in depth is huge, we lerp color back.
|
||||
float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
|
||||
// float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
|
||||
srcSample = mix(srcSample, sampleCenter, s);
|
||||
|
||||
// Accumulate.
|
||||
srcBlurred += gaussianDistributionCurve[i] * srcSample;
|
||||
}
|
||||
*/
|
||||
|
||||
for(int i = 1; i < NUM_HALF_TAPS; i++) {
|
||||
// Fetch color and depth for current sample.
|
||||
vec2 texcoordOffset = (gaussianDistributionOffsetHalf[i] * finalStep);
|
||||
|
||||
float srcDepthN = texture(depthMap, texcoord - texcoordOffset).x;
|
||||
float srcDepthP = texture(depthMap, texcoord + texcoordOffset).x;
|
||||
vec4 srcSampleN = texture(sourceMap, texcoord - texcoordOffset);
|
||||
vec4 srcSampleP = texture(sourceMap, texcoord + texcoordOffset);
|
||||
|
||||
// If the difference in depth is huge, we lerp color back.
|
||||
float sN = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthN - sampleDepth), 0.0, 1.0);
|
||||
float sP = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthP - sampleDepth), 0.0, 1.0);
|
||||
|
||||
srcSampleN = mix(srcSampleN, sampleCenter, sN);
|
||||
srcSampleP = mix(srcSampleP, sampleCenter, sP);
|
||||
|
||||
// Accumulate.
|
||||
srcBlurred += gaussianDistributionCurveHalf[i] * (srcSampleP + srcSampleN);
|
||||
}
|
||||
|
||||
return srcBlurred;
|
||||
|
|
|
@ -206,6 +206,21 @@ public:
|
|||
const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
|
||||
T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
|
||||
|
||||
virtual Varying operator[] (uint8_t index) const {
|
||||
if (index == 4) {
|
||||
return std::get<4>((*this));
|
||||
} else if (index == 3) {
|
||||
return std::get<3>((*this));
|
||||
} else if (index == 2) {
|
||||
return std::get<2>((*this));
|
||||
} else if (index == 1) {
|
||||
return std::get<1>((*this));
|
||||
} else {
|
||||
return std::get<0>((*this));
|
||||
}
|
||||
}
|
||||
virtual uint8_t length() const { return 5; }
|
||||
|
||||
Varying hasVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ Column {
|
|||
ListElement { text: "Lighting"; color: "White" }
|
||||
ListElement { text: "Shadow"; color: "White" }
|
||||
ListElement { text: "Linear Depth"; color: "White" }
|
||||
ListElement { text: "Linear Depth LOD2"; color: "White" }
|
||||
ListElement { text: "Half Linear Depth"; color: "White" }
|
||||
ListElement { text: "Half Normal"; color: "White" }
|
||||
ListElement { text: "Mid Curvature"; color: "White" }
|
||||
ListElement { text: "Mid Normal"; color: "White" }
|
||||
ListElement { text: "Low Curvature"; color: "White" }
|
||||
|
|
Loading…
Reference in a new issue