mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 11:53:34 +02:00
Carrefully improving the curvature generation performances
This commit is contained in:
parent
744474982d
commit
9332f82d54
12 changed files with 321 additions and 105 deletions
libraries
render-utils/src
DebugDeferredBuffer.cppDebugDeferredBuffer.hDeferredTransform.slhRenderDeferredTask.cppSurfaceGeometryPass.cppSurfaceGeometryPass.hsurfaceGeometry_makeCurvature.slf
render/src/render
scripts/developer/utilities/render
|
@ -144,7 +144,13 @@ static const std::string DEFAULT_SHADOW_SHADER {
|
|||
static const std::string DEFAULT_PYRAMID_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, 3).x * 0.01), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_LINEAR_DEPTH_2_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);"
|
||||
" }"
|
||||
};
|
||||
|
||||
|
@ -252,8 +258,10 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
|||
return DEFAULT_LIGHTING_SHADER;
|
||||
case ShadowMode:
|
||||
return DEFAULT_SHADOW_SHADER;
|
||||
case PyramidDepthMode:
|
||||
case LinearDepthMode:
|
||||
return DEFAULT_PYRAMID_DEPTH_SHADER;
|
||||
case LinearDepth2Mode:
|
||||
return DEFAULT_LINEAR_DEPTH_2_SHADER;
|
||||
case CurvatureMode:
|
||||
return DEFAULT_CURVATURE_SHADER;
|
||||
case NormalCurvatureMode:
|
||||
|
|
|
@ -63,7 +63,8 @@ protected:
|
|||
ScatteringMode,
|
||||
LightingMode,
|
||||
ShadowMode,
|
||||
PyramidDepthMode,
|
||||
LinearDepthMode,
|
||||
LinearDepth2Mode,
|
||||
CurvatureMode,
|
||||
NormalCurvatureMode,
|
||||
DiffusedCurvatureMode,
|
||||
|
|
|
@ -61,6 +61,11 @@ float getProjectionNear() {
|
|||
return planeD / planeC;
|
||||
}
|
||||
|
||||
// positive far distance of the projection
|
||||
float getPosLinearDepthFar() {
|
||||
return -frameTransform._depthInfo.z;
|
||||
}
|
||||
|
||||
mat4 getViewInverse() {
|
||||
return frameTransform._viewInverse;
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
const auto fullFrameRangeTimer = addJob<BeginGPURangeTimer>("BeginRangeTimer");
|
||||
const auto opaqueRangeTimer = addJob<BeginGPURangeTimer>("BeginOpaqueRangeTimer");
|
||||
|
||||
const auto prepareDeferredInputs = SurfaceGeometryPass::Inputs(primaryFramebuffer, lightingModel).hasVarying();
|
||||
const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).hasVarying();
|
||||
const auto prepareDeferredOutputs = addJob<PrepareDeferred>("PrepareDeferred", prepareDeferredInputs);
|
||||
const auto deferredFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(0);
|
||||
const auto lightingFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(1);
|
||||
|
@ -117,15 +117,23 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
|
||||
addJob<EndGPURangeTimer>("OpaqueRangeTimer", opaqueRangeTimer);
|
||||
|
||||
const auto curvatureRangeTimer = addJob<BeginGPURangeTimer>("BeginCurvatureRangeTimer");
|
||||
|
||||
// Opaque all rendered, generate surface geometry buffers
|
||||
const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying();
|
||||
// Opaque all rendered
|
||||
|
||||
// Linear Depth Pass
|
||||
const auto linearDepthPassInputs = LinearDepthPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying();
|
||||
const auto linearDepthPassOutputs = addJob<LinearDepthPass>("LinearDepth", linearDepthPassInputs);
|
||||
const auto linearDepthTarget = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(0);
|
||||
const auto linearDepthTexture = linearDepthPassOutputs.getN<LinearDepthPass::Outputs>(2);
|
||||
|
||||
|
||||
// Curvature pass
|
||||
const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying();
|
||||
const auto surfaceGeometryPassOutputs = addJob<SurfaceGeometryPass>("SurfaceGeometry", surfaceGeometryPassInputs);
|
||||
const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(0);
|
||||
const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(1);
|
||||
const auto linearDepthTexture = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(2);
|
||||
|
||||
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();
|
||||
|
|
|
@ -10,10 +10,15 @@
|
|||
//
|
||||
#include "SurfaceGeometryPass.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
|
||||
|
||||
const int DepthLinearPass_FrameTransformSlot = 0;
|
||||
const int DepthLinearPass_DepthMapSlot = 0;
|
||||
|
||||
const int SurfaceGeometryPass_FrameTransformSlot = 0;
|
||||
const int SurfaceGeometryPass_ParamsSlot = 1;
|
||||
const int SurfaceGeometryPass_DepthMapSlot = 0;
|
||||
|
@ -25,11 +30,11 @@ const int SurfaceGeometryPass_NormalMapSlot = 1;
|
|||
|
||||
|
||||
|
||||
SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() {
|
||||
LinearDepthFramebuffer::LinearDepthFramebuffer() {
|
||||
}
|
||||
|
||||
|
||||
void SurfaceGeometryFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depthBuffer) {
|
||||
void LinearDepthFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depthBuffer) {
|
||||
//If the depth buffer or size changed, we need to delete our FBOs
|
||||
bool reset = false;
|
||||
if ((_primaryDepthTexture != depthBuffer)) {
|
||||
|
@ -49,42 +54,173 @@ void SurfaceGeometryFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& d
|
|||
}
|
||||
}
|
||||
|
||||
void SurfaceGeometryFramebuffer::clear() {
|
||||
void LinearDepthFramebuffer::clear() {
|
||||
_linearDepthFramebuffer.reset();
|
||||
_linearDepthTexture.reset();
|
||||
}
|
||||
|
||||
void LinearDepthFramebuffer::allocate() {
|
||||
|
||||
auto width = _frameSize.x;
|
||||
auto height = _frameSize.y;
|
||||
|
||||
// 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);
|
||||
_linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture);
|
||||
_linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer LinearDepthFramebuffer::getLinearDepthFramebuffer() {
|
||||
if (!_linearDepthFramebuffer) {
|
||||
allocate();
|
||||
}
|
||||
return _linearDepthFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer LinearDepthFramebuffer::getLinearDepthTexture() {
|
||||
if (!_linearDepthTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _linearDepthTexture;
|
||||
}
|
||||
|
||||
|
||||
LinearDepthPass::LinearDepthPass() {
|
||||
}
|
||||
|
||||
void LinearDepthPass::configure(const Config& config) {
|
||||
}
|
||||
|
||||
void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
const auto frameTransform = inputs.get0();
|
||||
const auto deferredFramebuffer = inputs.get1();
|
||||
|
||||
if (!_linearDepthFramebuffer) {
|
||||
_linearDepthFramebuffer = std::make_shared<LinearDepthFramebuffer>();
|
||||
}
|
||||
_linearDepthFramebuffer->updatePrimaryDepth(deferredFramebuffer->getPrimaryDepthTexture());
|
||||
|
||||
auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture();
|
||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
|
||||
auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer();
|
||||
auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture();
|
||||
|
||||
outputs.edit0() = _linearDepthFramebuffer;
|
||||
outputs.edit1() = linearDepthFBO;
|
||||
outputs.edit2() = linearDepthTexture;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline();
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
auto furtherDepth = std::numeric_limits<float>::infinity();
|
||||
furtherDepth = args->getViewFrustum().getFarClip() + 10.0;
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
_gpuTimer.begin(batch);
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.setViewportTransform(depthViewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.setViewTransform(Transform());
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_linearDepthFramebuffer->getDepthFrameSize(), depthViewport));
|
||||
|
||||
batch.setUniformBuffer(DepthLinearPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
|
||||
// Pyramid pass
|
||||
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));
|
||||
|
||||
_gpuTimer.end(batch);
|
||||
});
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
config->gpuTime = _gpuTimer.getAverage();
|
||||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
|
||||
if (!_linearDepthPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_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("depthMap"), DepthLinearPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
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->setColorWriteMask(true, false, false, false);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_linearDepthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
return _linearDepthPipeline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() {
|
||||
}
|
||||
|
||||
void SurfaceGeometryFramebuffer::updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer) {
|
||||
//If the depth buffer or size changed, we need to delete our FBOs
|
||||
bool reset = false;
|
||||
if ((_linearDepthTexture != linearDepthBuffer)) {
|
||||
_linearDepthTexture = linearDepthBuffer;
|
||||
reset = true;
|
||||
}
|
||||
if (_linearDepthTexture) {
|
||||
auto newFrameSize = glm::ivec2(_linearDepthTexture->getDimensions());
|
||||
if (_frameSize != newFrameSize) {
|
||||
_frameSize = newFrameSize;
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceGeometryFramebuffer::clear() {
|
||||
_curvatureFramebuffer.reset();
|
||||
_curvatureTexture.reset();
|
||||
}
|
||||
|
||||
gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() {
|
||||
return _linearDepthTexture;
|
||||
}
|
||||
|
||||
void SurfaceGeometryFramebuffer::allocate() {
|
||||
|
||||
auto width = _frameSize.x;
|
||||
auto height = _frameSize.y;
|
||||
|
||||
// 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)));
|
||||
_linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture);
|
||||
_linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
|
||||
|
||||
_curvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width >> getResolutionLevel(), height >> getResolutionLevel(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture);
|
||||
// _curvatureFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer SurfaceGeometryFramebuffer::getLinearDepthFramebuffer() {
|
||||
if (!_linearDepthFramebuffer) {
|
||||
allocate();
|
||||
}
|
||||
return _linearDepthFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() {
|
||||
if (!_linearDepthTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _linearDepthTexture;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer SurfaceGeometryFramebuffer::getCurvatureFramebuffer() {
|
||||
|
@ -108,7 +244,6 @@ void SurfaceGeometryFramebuffer::setResolutionLevel(int resolutionLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SurfaceGeometryPass::SurfaceGeometryPass() {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
|
@ -135,7 +270,7 @@ void SurfaceGeometryPass::configure(const Config& config) {
|
|||
}
|
||||
|
||||
|
||||
void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& curvatureAndDepth) {
|
||||
void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
|
@ -143,31 +278,28 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
|
||||
const auto frameTransform = inputs.get0();
|
||||
const auto deferredFramebuffer = inputs.get1();
|
||||
const auto linearDepthFramebuffer = inputs.get2();
|
||||
|
||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||
|
||||
if (!_surfaceGeometryFramebuffer) {
|
||||
_surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>();
|
||||
}
|
||||
_surfaceGeometryFramebuffer->updatePrimaryDepth(deferredFramebuffer->getPrimaryDepthTexture());
|
||||
_surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture);
|
||||
|
||||
auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture();
|
||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
|
||||
auto linearDepthFBO = _surfaceGeometryFramebuffer->getLinearDepthFramebuffer();
|
||||
auto linearDepthTexture = _surfaceGeometryFramebuffer->getLinearDepthTexture();
|
||||
auto curvatureFBO = _surfaceGeometryFramebuffer->getCurvatureFramebuffer();
|
||||
auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture();
|
||||
if (curvatureFBO->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) {
|
||||
curvatureFBO->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat());
|
||||
}
|
||||
auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture();
|
||||
|
||||
curvatureAndDepth.edit0() = _surfaceGeometryFramebuffer;
|
||||
curvatureAndDepth.edit1() = curvatureFBO;
|
||||
curvatureAndDepth.edit2() = linearDepthTexture;
|
||||
outputs.edit0() = _surfaceGeometryFramebuffer;
|
||||
outputs.edit1() = curvatureFBO;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline();
|
||||
auto curvaturePipeline = getCurvaturePipeline();
|
||||
|
||||
// gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
// _gpuTimer.begin(batch);
|
||||
// });
|
||||
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
auto curvatureViewport = depthViewport >> _surfaceGeometryFramebuffer->getResolutionLevel();
|
||||
|
||||
|
@ -175,70 +307,34 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
_gpuTimer.begin(batch);
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.setViewportTransform(depthViewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.setViewTransform(Transform());
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getDepthFrameSize(), depthViewport));
|
||||
|
||||
batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer);
|
||||
|
||||
// Pyramid pass
|
||||
batch.setFramebuffer(linearDepthFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f));
|
||||
batch.setPipeline(linearDepthPipeline);
|
||||
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, depthBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
batch.setViewportTransform(curvatureViewport);
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getCurvatureFrameSize(), curvatureViewport));
|
||||
|
||||
batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer);
|
||||
|
||||
// Curvature pass
|
||||
batch.setFramebuffer(curvatureFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
|
||||
|
||||
batch.setPipeline(curvaturePipeline);
|
||||
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture);
|
||||
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, normalTexture);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr);
|
||||
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr);
|
||||
|
||||
_gpuTimer.end(batch);
|
||||
});
|
||||
|
||||
// gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
// _gpuTimer.end(batch);
|
||||
// });
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
config->gpuTime = _gpuTimer.getAverage();
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& SurfaceGeometryPass::getLinearDepthPipeline() {
|
||||
if (!_linearDepthPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_frag));
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), SurfaceGeometryPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
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->setColorWriteMask(true, false, false, false);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_linearDepthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
return _linearDepthPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
|
||||
if (!_curvaturePipeline) {
|
||||
|
|
|
@ -19,23 +19,19 @@
|
|||
#include "DeferredFramebuffer.h"
|
||||
|
||||
|
||||
// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth and curvature generated
|
||||
// from a z buffer and a normal buffer
|
||||
class SurfaceGeometryFramebuffer {
|
||||
// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth
|
||||
// from a z buffer
|
||||
class LinearDepthFramebuffer {
|
||||
public:
|
||||
SurfaceGeometryFramebuffer();
|
||||
LinearDepthFramebuffer();
|
||||
|
||||
gpu::FramebufferPointer getLinearDepthFramebuffer();
|
||||
gpu::TexturePointer getLinearDepthTexture();
|
||||
|
||||
gpu::FramebufferPointer getCurvatureFramebuffer();
|
||||
gpu::TexturePointer getCurvatureTexture();
|
||||
|
||||
// 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();
|
||||
const glm::ivec2& getDepthFrameSize() const { return _frameSize; }
|
||||
glm::ivec2 getCurvatureFrameSize() const { return _frameSize >> _resolutionLevel; }
|
||||
|
||||
void setResolutionLevel(int level);
|
||||
int getResolutionLevel() const { return _resolutionLevel; }
|
||||
|
@ -48,6 +44,76 @@ protected:
|
|||
|
||||
gpu::FramebufferPointer _linearDepthFramebuffer;
|
||||
gpu::TexturePointer _linearDepthTexture;
|
||||
|
||||
glm::ivec2 _frameSize;
|
||||
int _resolutionLevel{ 0 };
|
||||
};
|
||||
|
||||
using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
|
||||
|
||||
|
||||
class LinearDepthPassConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double gpuTime READ getGpuTime)
|
||||
public:
|
||||
LinearDepthPassConfig() : render::Job::Config(true) {}
|
||||
|
||||
double getGpuTime() { return gpuTime; }
|
||||
|
||||
double gpuTime{ 0.0 };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class LinearDepthPass {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<DeferredFrameTransformPointer, DeferredFramebufferPointer>;
|
||||
using Outputs = render::VaryingSet3<LinearDepthFramebufferPointer, gpu::FramebufferPointer, gpu::TexturePointer>;
|
||||
using Config = LinearDepthPassConfig;
|
||||
using JobModel = render::Job::ModelIO<LinearDepthPass, Inputs, Outputs, Config>;
|
||||
|
||||
LinearDepthPass();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
|
||||
private:
|
||||
typedef gpu::BufferView UniformBufferView;
|
||||
|
||||
LinearDepthFramebufferPointer _linearDepthFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getLinearDepthPipeline();
|
||||
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
|
||||
gpu::RangeTimer _gpuTimer;
|
||||
};
|
||||
|
||||
|
||||
// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth and curvature generated
|
||||
// from a z buffer and a normal buffer
|
||||
class SurfaceGeometryFramebuffer {
|
||||
public:
|
||||
SurfaceGeometryFramebuffer();
|
||||
|
||||
gpu::FramebufferPointer getCurvatureFramebuffer();
|
||||
gpu::TexturePointer getCurvatureTexture();
|
||||
|
||||
// Update the source framebuffer size which will drive the allocation of all the other resources.
|
||||
void updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
|
||||
gpu::TexturePointer getLinearDepthTexture();
|
||||
const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
|
||||
glm::ivec2 getCurvatureFrameSize() const { return _frameSize >> _resolutionLevel; }
|
||||
|
||||
void setResolutionLevel(int level);
|
||||
int getResolutionLevel() const { return _resolutionLevel; }
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
void allocate();
|
||||
|
||||
gpu::TexturePointer _linearDepthTexture;
|
||||
|
||||
gpu::FramebufferPointer _curvatureFramebuffer;
|
||||
gpu::TexturePointer _curvatureTexture;
|
||||
|
@ -83,15 +149,15 @@ signals:
|
|||
|
||||
class SurfaceGeometryPass {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<DeferredFrameTransformPointer, DeferredFramebufferPointer>;
|
||||
using Outputs = render::VaryingSet3<SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer, gpu::TexturePointer>;
|
||||
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
|
||||
using Outputs = render::VaryingSet2<SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Config = SurfaceGeometryPassConfig;
|
||||
using JobModel = render::Job::ModelIO<SurfaceGeometryPass, Inputs, Outputs, Config>;
|
||||
|
||||
SurfaceGeometryPass();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& curvatureAndDepth);
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
|
||||
float getCurvatureDepthThreshold() const { return _parametersBuffer.get<Parameters>().curvatureInfo.x; }
|
||||
float getCurvatureBasisScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.y; }
|
||||
|
@ -114,10 +180,8 @@ private:
|
|||
|
||||
SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getLinearDepthPipeline();
|
||||
const gpu::PipelinePointer& getCurvaturePipeline();
|
||||
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
gpu::PipelinePointer _curvaturePipeline;
|
||||
|
||||
|
||||
|
|
|
@ -109,6 +109,11 @@ void main(void) {
|
|||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEye(framePixelPos);
|
||||
if (Zeye <= -getPosLinearDepthFar()) {
|
||||
// outFragColor = vec4(0.0);
|
||||
// return;
|
||||
discard;
|
||||
}
|
||||
|
||||
float nearPlaneScale = 0.5 * getProjectionNear();
|
||||
|
||||
|
|
|
@ -78,6 +78,14 @@ void BlurParams::setDepthThreshold(float threshold) {
|
|||
}
|
||||
}
|
||||
|
||||
void BlurParams::setLinearDepthPosFar(float farPosDepth) {
|
||||
auto linearDepthInfo = _parametersBuffer.get<Params>().linearDepthInfo;
|
||||
if (farPosDepth != linearDepthInfo.x) {
|
||||
_parametersBuffer.edit<Params>().linearDepthInfo.x = farPosDepth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlurInOutResource::BlurInOutResource(bool generateOutputFramebuffer) :
|
||||
_generateOutputFramebuffer(generateOutputFramebuffer)
|
||||
{
|
||||
|
@ -220,6 +228,7 @@ void BlurGaussian::run(const SceneContextPointer& sceneContext, const RenderCont
|
|||
_parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->_context->isStereo());
|
||||
glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions());
|
||||
_parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, args->_viewport));
|
||||
_parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip());
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
void setDepthPerspective(float oneOverTan2FOV);
|
||||
void setDepthThreshold(float threshold);
|
||||
|
||||
void setLinearDepthPosFar(float farPosDepth);
|
||||
|
||||
// Class describing the uniform buffer with all the parameters common to the blur shaders
|
||||
class Params {
|
||||
public:
|
||||
|
@ -47,6 +49,9 @@ public:
|
|||
// stereo info if blurring a stereo render
|
||||
glm::vec4 stereoInfo{ 0.0f };
|
||||
|
||||
// LinearDepth info is { f }
|
||||
glm::vec4 linearDepthInfo{ 0.0f };
|
||||
|
||||
Params() {}
|
||||
};
|
||||
gpu::BufferView _parametersBuffer;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct BlurParameters {
|
|||
vec4 filterInfo;
|
||||
vec4 depthInfo;
|
||||
vec4 stereoInfo;
|
||||
vec4 linearDepthInfo;
|
||||
};
|
||||
|
||||
uniform blurParamsBuffer {
|
||||
|
@ -54,6 +55,10 @@ float getDepthPerspective() {
|
|||
return parameters.depthInfo.w;
|
||||
}
|
||||
|
||||
float getPosLinearDepthFar() {
|
||||
return parameters.linearDepthInfo.x;
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
|
@ -92,8 +97,12 @@ uniform sampler2D depthMap;
|
|||
|
||||
vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
||||
texcoord = evalTexcoordTransformed(texcoord);
|
||||
float sampleDepth = texture(depthMap, texcoord).x;
|
||||
float sampleDepth = -texture(depthMap, texcoord).x;
|
||||
vec4 sampleCenter = texture(sourceMap, texcoord);
|
||||
if (sampleDepth <= getPosLinearDepthFar()) {
|
||||
discard;
|
||||
//return sampleCenter;
|
||||
}
|
||||
|
||||
// Calculate the width scale.
|
||||
float distanceToProjectionWindow = getDepthPerspective();
|
||||
|
|
|
@ -151,6 +151,7 @@ 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: "Mid Curvature"; color: "White" }
|
||||
ListElement { text: "Mid Normal"; color: "White" }
|
||||
ListElement { text: "Low Curvature"; color: "White" }
|
||||
|
|
|
@ -41,9 +41,14 @@ Item {
|
|||
object: Render.getConfig("OpaqueRangeTimer"),
|
||||
prop: "gpuTime",
|
||||
label: "Opaque",
|
||||
color: "#0000FF"
|
||||
color: "#FFFFFF"
|
||||
},
|
||||
{
|
||||
object: Render.getConfig("LinearDepth"),
|
||||
prop: "gpuTime",
|
||||
label: "LinearDepth",
|
||||
color: "#00FF00"
|
||||
},{
|
||||
object: Render.getConfig("SurfaceGeometry"),
|
||||
prop: "gpuTime",
|
||||
label: "SurfaceGeometry",
|
||||
|
|
Loading…
Reference in a new issue