Performing the curvature generation and diffusion at half the resolution

This commit is contained in:
samcake 2016-07-18 03:54:05 -07:00
parent 378f4576fa
commit 5a0ce81516
11 changed files with 223 additions and 58 deletions

View file

@ -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()) {

View file

@ -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,

View file

@ -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

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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)); }
};

View file

@ -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" }