mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
Revolutionizing ao
This commit is contained in:
parent
4f04dbc926
commit
afb1ebf42e
12 changed files with 221 additions and 190 deletions
|
@ -33,6 +33,91 @@
|
|||
#include "ssao_makeHorizontalBlur_frag.h"
|
||||
#include "ssao_makeVerticalBlur_frag.h"
|
||||
|
||||
|
||||
AmbientOcclusionFramebuffer::AmbientOcclusionFramebuffer() {
|
||||
}
|
||||
|
||||
void AmbientOcclusionFramebuffer::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 AmbientOcclusionFramebuffer::clear() {
|
||||
_occlusionFramebuffer.reset();
|
||||
_occlusionTexture.reset();
|
||||
_occlusionBlurredFramebuffer.reset();
|
||||
_occlusionBlurredTexture.reset();
|
||||
}
|
||||
|
||||
gpu::TexturePointer AmbientOcclusionFramebuffer::getLinearDepthTexture() {
|
||||
return _linearDepthTexture;
|
||||
}
|
||||
|
||||
void AmbientOcclusionFramebuffer::allocate() {
|
||||
|
||||
auto width = _frameSize.x;
|
||||
auto height = _frameSize.y;
|
||||
|
||||
_occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
||||
|
||||
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() {
|
||||
if (!_occlusionFramebuffer) {
|
||||
allocate();
|
||||
}
|
||||
return _occlusionFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionTexture() {
|
||||
if (!_occlusionTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _occlusionTexture;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionBlurredFramebuffer() {
|
||||
if (!_occlusionBlurredFramebuffer) {
|
||||
allocate();
|
||||
}
|
||||
return _occlusionBlurredFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionBlurredTexture() {
|
||||
if (!_occlusionBlurredTexture) {
|
||||
allocate();
|
||||
}
|
||||
return _occlusionBlurredTexture;
|
||||
}
|
||||
|
||||
void AmbientOcclusionFramebuffer::setResolutionLevel(int resolutionLevel) {
|
||||
if (resolutionLevel != getResolutionLevel()) {
|
||||
clear();
|
||||
_resolutionLevel = resolutionLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GaussianDistribution {
|
||||
public:
|
||||
|
||||
|
@ -90,8 +175,7 @@ public:
|
|||
|
||||
const int AmbientOcclusionEffect_FrameTransformSlot = 0;
|
||||
const int AmbientOcclusionEffect_ParamsSlot = 1;
|
||||
const int AmbientOcclusionEffect_DepthMapSlot = 0;
|
||||
const int AmbientOcclusionEffect_PyramidMapSlot = 0;
|
||||
const int AmbientOcclusionEffect_LinearDepthMapSlot = 0;
|
||||
const int AmbientOcclusionEffect_OcclusionMapSlot = 0;
|
||||
|
||||
AmbientOcclusionEffect::AmbientOcclusionEffect() {
|
||||
|
@ -147,13 +231,22 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
|||
current.y = 1.0f / config.numSamples;
|
||||
}
|
||||
|
||||
if (!_framebuffer) {
|
||||
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
|
||||
}
|
||||
|
||||
_framebuffer->setResolutionLevel(config.resolutionLevel);
|
||||
if (config.resolutionLevel != getResolutionLevel()) {
|
||||
_parametersBuffer.edit<Parameters>().resolutionInfo.w = config.resolutionLevel;
|
||||
}
|
||||
|
||||
const auto& resolutionLevel = config.resolutionLevel;
|
||||
if (resolutionLevel != getResolutionLevel()) {
|
||||
auto& current = _parametersBuffer.edit<Parameters>().resolutionInfo;
|
||||
current.x = (float)resolutionLevel;
|
||||
|
||||
// Communicate the change to the Framebuffer cache
|
||||
DependencyManager::get<FramebufferCache>()->setAmbientOcclusionResolutionLevel(resolutionLevel);
|
||||
// DependencyManager::get<FramebufferCache>()->setAmbientOcclusionResolutionLevel(resolutionLevel);
|
||||
}
|
||||
|
||||
if (config.blurRadius != getBlurRadius()) {
|
||||
|
@ -177,32 +270,6 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
|||
}
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusionEffect::getPyramidPipeline() {
|
||||
if (!_pyramidPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = gpu::Shader::createPixel(std::string(ssao_makePyramid_frag));
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionFrameTransformBuffer"), AmbientOcclusionEffect_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), AmbientOcclusionEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AmbientOcclusionEffect_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// Stencil test the pyramid passe 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
|
||||
_pyramidPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
return _pyramidPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() {
|
||||
if (!_occlusionPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
|
@ -212,7 +279,7 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() {
|
|||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionFrameTransformBuffer"), AmbientOcclusionEffect_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), AmbientOcclusionEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("pyramidMap"), AmbientOcclusionEffect_PyramidMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("pyramidMap"), AmbientOcclusionEffect_LinearDepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
@ -282,8 +349,7 @@ void AmbientOcclusionEffect::updateGaussianDistribution() {
|
|||
GaussianDistribution::evalSampling(coefs, Parameters::GAUSSIAN_COEFS_LENGTH, getBlurRadius(), getBlurDeviation());
|
||||
}
|
||||
|
||||
void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||
#ifdef FIX_THE_FRAMEBUFFER_CACHE
|
||||
void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
|
@ -294,18 +360,39 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
return;
|
||||
}
|
||||
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
auto depthBuffer = framebufferCache->getPrimaryDepthTexture();
|
||||
auto normalBuffer = framebufferCache->getDeferredNormalTexture();
|
||||
auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer();
|
||||
auto occlusionFBO = framebufferCache->getOcclusionFramebuffer();
|
||||
auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer();
|
||||
const auto frameTransform = inputs.get0();
|
||||
const auto deferredFramebuffer = inputs.get1();
|
||||
const auto linearDepthFramebuffer = inputs.get2();
|
||||
|
||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
auto sourceViewport = args->_viewport;
|
||||
auto occlusionViewport = sourceViewport;
|
||||
|
||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
||||
float sWidth = args->_viewport.z / (float)framebufferSize.width();
|
||||
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
||||
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
||||
if (!_framebuffer) {
|
||||
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
|
||||
}
|
||||
|
||||
if (_framebuffer->getResolutionLevel() > 0) {
|
||||
linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||
normalTexture = linearDepthFramebuffer->getHalfNormalTexture();
|
||||
occlusionViewport = occlusionViewport >> _framebuffer->getResolutionLevel();
|
||||
}
|
||||
|
||||
_framebuffer->updateLinearDepth(linearDepthTexture);
|
||||
|
||||
|
||||
auto occlusionFBO = _framebuffer->getOcclusionFramebuffer();
|
||||
auto occlusionBlurredFBO = _framebuffer->getOcclusionBlurredFramebuffer();
|
||||
|
||||
outputs = _framebuffer;
|
||||
|
||||
auto framebufferSize = _framebuffer->getSourceFrameSize();
|
||||
|
||||
float sMin = args->_viewport.x / (float)framebufferSize.x;
|
||||
float sWidth = args->_viewport.z / (float)framebufferSize.x;
|
||||
float tMin = args->_viewport.y / (float)framebufferSize.y;
|
||||
float tHeight = args->_viewport.w / (float)framebufferSize.y;
|
||||
|
||||
auto resolutionLevel = getResolutionLevel();
|
||||
|
||||
|
@ -341,7 +428,6 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
|
||||
}
|
||||
|
||||
auto pyramidPipeline = getPyramidPipeline();
|
||||
auto occlusionPipeline = getOcclusionPipeline();
|
||||
auto firstHBlurPipeline = getHBlurPipeline();
|
||||
auto lastVBlurPipeline = getVBlurPipeline();
|
||||
|
@ -351,7 +437,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
|
||||
_gpuTimer.begin(batch);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setViewportTransform(occlusionViewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.setViewTransform(Transform());
|
||||
|
||||
|
@ -363,32 +449,18 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
batch.setUniformBuffer(AmbientOcclusionEffect_FrameTransformSlot, _frameTransformBuffer);
|
||||
batch.setUniformBuffer(AmbientOcclusionEffect_ParamsSlot, _parametersBuffer);
|
||||
|
||||
|
||||
// Pyramid pass
|
||||
batch.setFramebuffer(pyramidFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f));
|
||||
batch.setPipeline(pyramidPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_DepthMapSlot, depthBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
// Make pyramid mips
|
||||
batch.generateTextureMips(pyramidFBO->getRenderBuffer(0));
|
||||
|
||||
// Adjust Viewport for rendering resolution
|
||||
if (resolutionLevel > 0) {
|
||||
glm::ivec4 viewport(args->_viewport.x, args->_viewport.y, args->_viewport.z >> resolutionLevel, args->_viewport.w >> resolutionLevel);
|
||||
batch.setViewportTransform(viewport);
|
||||
}
|
||||
|
||||
|
||||
// batch.generateTextureMips(linearDepthTexture);
|
||||
|
||||
// Occlusion pass
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f));
|
||||
batch.setPipeline(occlusionPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot, pyramidFBO->getRenderBuffer(0));
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, linearDepthTexture);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
|
||||
if (getBlurRadius() > 0) {
|
||||
/* if (getBlurRadius() > 0) {
|
||||
// Blur 1st pass
|
||||
batch.setFramebuffer(occlusionBlurredFBO);
|
||||
batch.setPipeline(firstHBlurPipeline);
|
||||
|
@ -400,12 +472,15 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
batch.setPipeline(lastVBlurPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, nullptr);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, nullptr);
|
||||
|
||||
_gpuTimer.end(batch);
|
||||
});
|
||||
|
||||
// Update the timer
|
||||
std::static_pointer_cast<Config>(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -16,6 +16,47 @@
|
|||
|
||||
#include "render/DrawTask.h"
|
||||
|
||||
#include "DeferredFrameTransform.h"
|
||||
#include "DeferredFramebuffer.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
|
||||
class AmbientOcclusionFramebuffer {
|
||||
public:
|
||||
AmbientOcclusionFramebuffer();
|
||||
|
||||
gpu::FramebufferPointer getOcclusionFramebuffer();
|
||||
gpu::TexturePointer getOcclusionTexture();
|
||||
|
||||
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
|
||||
gpu::TexturePointer getOcclusionBlurredTexture();
|
||||
|
||||
// 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; }
|
||||
|
||||
void setResolutionLevel(int level);
|
||||
int getResolutionLevel() const { return _resolutionLevel; }
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
void allocate();
|
||||
|
||||
gpu::TexturePointer _linearDepthTexture;
|
||||
|
||||
gpu::FramebufferPointer _occlusionFramebuffer;
|
||||
gpu::TexturePointer _occlusionTexture;
|
||||
|
||||
gpu::FramebufferPointer _occlusionBlurredFramebuffer;
|
||||
gpu::TexturePointer _occlusionBlurredTexture;
|
||||
|
||||
|
||||
glm::ivec2 _frameSize;
|
||||
int _resolutionLevel{ 0 };
|
||||
};
|
||||
|
||||
using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
|
||||
|
||||
class AmbientOcclusionEffectConfig : public render::Job::Config::Persistent {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty)
|
||||
|
@ -67,13 +108,15 @@ signals:
|
|||
|
||||
class AmbientOcclusionEffect {
|
||||
public:
|
||||
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
|
||||
using Outputs = AmbientOcclusionFramebufferPointer;
|
||||
using Config = AmbientOcclusionEffectConfig;
|
||||
using JobModel = render::Job::Model<AmbientOcclusionEffect, Config>;
|
||||
using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Inputs, Outputs, Config>;
|
||||
|
||||
AmbientOcclusionEffect();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
|
||||
float getRadius() const { return _parametersBuffer.get<Parameters>().radiusInfo.x; }
|
||||
float getObscuranceLevel() const { return _parametersBuffer.get<Parameters>().radiusInfo.w; }
|
||||
|
@ -131,16 +174,16 @@ private:
|
|||
};
|
||||
gpu::BufferView _parametersBuffer;
|
||||
|
||||
const gpu::PipelinePointer& getPyramidPipeline();
|
||||
const gpu::PipelinePointer& getOcclusionPipeline();
|
||||
const gpu::PipelinePointer& getHBlurPipeline(); // first
|
||||
const gpu::PipelinePointer& getVBlurPipeline(); // second
|
||||
|
||||
gpu::PipelinePointer _pyramidPipeline;
|
||||
gpu::PipelinePointer _occlusionPipeline;
|
||||
gpu::PipelinePointer _hBlurPipeline;
|
||||
gpu::PipelinePointer _vBlurPipeline;
|
||||
|
||||
AmbientOcclusionFramebufferPointer _framebuffer;
|
||||
|
||||
gpu::RangeTimer _gpuTimer;
|
||||
};
|
||||
|
||||
|
|
|
@ -202,14 +202,14 @@ static const std::string DEFAULT_DEBUG_SCATTERING_SHADER{
|
|||
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(obscuranceMap, uv).x), 1.0);"
|
||||
" return vec4(vec3(texture(obscuranceMap, uv).xyz), 1.0);"
|
||||
// When drawing color " return vec4(vec3(texture(occlusionMap, uv).xyz), 1.0);"
|
||||
// when drawing normal " return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);"
|
||||
// when drawing normal" return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);"
|
||||
" }"
|
||||
};
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(occlusionBlurredMap, uv).x), 1.0);"
|
||||
" return vec4(vec3(texture(occlusionBlurredMap, uv).xyz), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
|
@ -379,6 +379,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
auto& deferredFramebuffer = inputs.get0();
|
||||
auto& linearDepthTarget = inputs.get1();
|
||||
auto& surfaceGeometryFramebuffer = inputs.get2();
|
||||
auto& ambientOcclusionFramebuffer = inputs.get3();
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
@ -414,13 +415,9 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
|
||||
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
|
||||
batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
|
||||
if (DependencyManager::get<DeferredLightingEffect>()->isAmbientOcclusionEnabled()) {
|
||||
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
|
||||
} else {
|
||||
// need to assign the white texture if ao is off
|
||||
batch.setResourceTexture(AmbientOcclusion, textureCache->getWhiteTexture());
|
||||
}
|
||||
batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
|
||||
|
||||
batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture());
|
||||
batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
|
||||
|
||||
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
const glm::vec2 bottomLeft(_size.x, _size.y);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <render/DrawTask.h>
|
||||
#include "DeferredFramebuffer.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
||||
class DebugDeferredBufferConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
|
@ -36,7 +37,7 @@ signals:
|
|||
|
||||
class DebugDeferredBuffer {
|
||||
public:
|
||||
using Inputs = render::VaryingSet4<DeferredFramebufferPointer, LinearDepthFramebufferPointer, SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Inputs = render::VaryingSet4<DeferredFramebufferPointer, LinearDepthFramebufferPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer>;
|
||||
using Config = DebugDeferredBufferConfig;
|
||||
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
const LightingModelPointer& lightingModel,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const gpu::FramebufferPointer& lowCurvatureNormalFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) {
|
||||
|
||||
auto args = renderContext->args;
|
||||
|
@ -431,7 +431,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
|
||||
// FIXME: Different render modes should have different tasks
|
||||
if (args->_renderMode == RenderArgs::DEFAULT_RENDER_MODE && deferredLightingEffect->isAmbientOcclusionEnabled()) {
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, framebufferCache->getOcclusionTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, ambientOcclusionFramebuffer->getOcclusionTexture());
|
||||
} else {
|
||||
// need to assign the white texture if ao is off
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, textureCache->getWhiteTexture());
|
||||
|
@ -446,9 +446,6 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
// Subsurface scattering specific
|
||||
if (surfaceGeometryFramebuffer) {
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, surfaceGeometryFramebuffer->getCurvatureTexture());
|
||||
}
|
||||
if (lowCurvatureNormalFramebuffer) {
|
||||
// batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, lowCurvatureNormalFramebuffer->getRenderBuffer(0));
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, surfaceGeometryFramebuffer->getLowCurvatureTexture());
|
||||
}
|
||||
if (subsurfaceScatteringResource) {
|
||||
|
@ -693,7 +690,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
|
|||
auto deferredFramebuffer = inputs.get1();
|
||||
auto lightingModel = inputs.get2();
|
||||
auto surfaceGeometryFramebuffer = inputs.get3();
|
||||
auto lowCurvatureNormalFramebuffer = inputs.get4();
|
||||
auto ssaoFramebuffer = inputs.get4();
|
||||
auto subsurfaceScatteringResource = inputs.get5();
|
||||
auto args = renderContext->args;
|
||||
|
||||
|
@ -701,7 +698,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
|
|||
_gpuTimer.begin(batch);
|
||||
});
|
||||
|
||||
setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, subsurfaceScatteringResource);
|
||||
setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
|
||||
|
||||
lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "LightStage.h"
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
||||
class RenderArgs;
|
||||
struct LightLocations;
|
||||
|
@ -138,7 +139,7 @@ public:
|
|||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
const LightingModelPointer& lightingModel,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const gpu::FramebufferPointer& lowCurvatureNormalFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource);
|
||||
};
|
||||
|
||||
|
@ -178,7 +179,7 @@ signals:
|
|||
|
||||
class RenderDeferred {
|
||||
public:
|
||||
using Inputs = render::VaryingSet6 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer, SubsurfaceScatteringResourcePointer>;
|
||||
using Inputs = render::VaryingSet6 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer>;
|
||||
using Config = RenderDeferredConfig;
|
||||
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;
|
||||
|
||||
|
|
|
@ -35,10 +35,6 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
|
|||
_frameBufferSize = frameBufferSize;
|
||||
_selfieFramebuffer.reset();
|
||||
_cachedFramebuffers.clear();
|
||||
_occlusionFramebuffer.reset();
|
||||
_occlusionTexture.reset();
|
||||
_occlusionBlurredFramebuffer.reset();
|
||||
_occlusionBlurredTexture.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,35 +50,6 @@ void FramebufferCache::createPrimaryFramebuffer() {
|
|||
_selfieFramebuffer->setRenderBuffer(0, tex);
|
||||
|
||||
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
|
||||
|
||||
|
||||
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
|
||||
|
||||
void FramebufferCache::resizeAmbientOcclusionBuffers() {
|
||||
_occlusionFramebuffer.reset();
|
||||
_occlusionTexture.reset();
|
||||
_occlusionBlurredFramebuffer.reset();
|
||||
_occlusionBlurredTexture.reset();
|
||||
|
||||
|
||||
auto width = _frameBufferSize.width() >> _AOResolutionLevel;
|
||||
auto height = _frameBufferSize.height() >> _AOResolutionLevel;
|
||||
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB);
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR);
|
||||
// auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||
|
||||
_occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
|
||||
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
||||
// _occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||
|
||||
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
|
||||
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
||||
// _occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,40 +74,3 @@ gpu::FramebufferPointer FramebufferCache::getSelfieFramebuffer() {
|
|||
}
|
||||
return _selfieFramebuffer;
|
||||
}
|
||||
|
||||
void FramebufferCache::setAmbientOcclusionResolutionLevel(int level) {
|
||||
const int MAX_AO_RESOLUTION_LEVEL = 4;
|
||||
level = std::max(0, std::min(level, MAX_AO_RESOLUTION_LEVEL));
|
||||
if (level != _AOResolutionLevel) {
|
||||
_AOResolutionLevel = level;
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() {
|
||||
if (!_occlusionFramebuffer) {
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer FramebufferCache::getOcclusionTexture() {
|
||||
if (!_occlusionTexture) {
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionTexture;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() {
|
||||
if (!_occlusionBlurredFramebuffer) {
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionBlurredFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() {
|
||||
if (!_occlusionBlurredTexture) {
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionBlurredTexture;
|
||||
}
|
|
@ -30,12 +30,6 @@ public:
|
|||
void setFrameBufferSize(QSize frameBufferSize);
|
||||
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
|
||||
|
||||
void setAmbientOcclusionResolutionLevel(int level);
|
||||
gpu::FramebufferPointer getOcclusionFramebuffer();
|
||||
gpu::TexturePointer getOcclusionTexture();
|
||||
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
|
||||
gpu::TexturePointer getOcclusionBlurredTexture();
|
||||
|
||||
/// Returns the framebuffer object used to render selfie maps;
|
||||
gpu::FramebufferPointer getSelfieFramebuffer();
|
||||
|
||||
|
@ -56,18 +50,7 @@ private:
|
|||
|
||||
gpu::FramebufferPointer _selfieFramebuffer;
|
||||
|
||||
gpu::FramebufferPointer _occlusionFramebuffer;
|
||||
gpu::TexturePointer _occlusionTexture;
|
||||
|
||||
gpu::FramebufferPointer _occlusionBlurredFramebuffer;
|
||||
gpu::TexturePointer _occlusionBlurredTexture;
|
||||
|
||||
QSize _frameBufferSize{ 100, 100 };
|
||||
int _AOResolutionLevel = 1; // AO perform at half res
|
||||
|
||||
// Resize/reallocate the buffers used for AO
|
||||
// the size of the AO buffers is scaled by the AOResolutionScale;
|
||||
void resizeAmbientOcclusionBuffers();
|
||||
};
|
||||
|
||||
#endif // hifi_FramebufferCache_h
|
||||
|
|
|
@ -141,13 +141,14 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
const auto scatteringResource = addJob<SubsurfaceScattering>("Scattering");
|
||||
|
||||
// AO job
|
||||
addJob<AmbientOcclusionEffect>("AmbientOcclusion");
|
||||
const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying();
|
||||
const auto ambientOcclusionFramebuffer = addJob<AmbientOcclusionEffect>("AmbientOcclusion", ambientOcclusionInputs);
|
||||
|
||||
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
|
||||
addJob<DrawLight>("DrawLight", lights);
|
||||
|
||||
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, scatteringResource).hasVarying();
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying();
|
||||
|
||||
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
|
||||
addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
|
||||
|
@ -178,7 +179,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
addJob<DebugSubsurfaceScattering>("DebugScattering", deferredLightingInputs);
|
||||
|
||||
// Debugging Deferred buffer job
|
||||
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer));
|
||||
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer));
|
||||
addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers);
|
||||
|
||||
// Scene Octree Debuging job
|
||||
|
|
|
@ -193,7 +193,7 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const
|
|||
batch.setResourceTexture(DepthLinearPass_NormalMapSlot, normalTexture);
|
||||
batch.setPipeline(downsamplePipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
|
||||
_gpuTimer.end(batch);
|
||||
});
|
||||
|
||||
|
|
|
@ -76,6 +76,9 @@ bool isStereo() {
|
|||
float getStereoSideWidth() {
|
||||
return float(int(frameTransform._stereoInfo.y) >> getResolutionLevel());
|
||||
}
|
||||
float getStereoSideHeight() {
|
||||
return float(int(frameTransform._pixelInfo.w) >> getResolutionLevel());
|
||||
}
|
||||
|
||||
ivec3 getStereoSideInfo(int xPos) {
|
||||
int sideWidth = int(getStereoSideWidth());
|
||||
|
|
|
@ -21,7 +21,7 @@ const int MAX_MIP_LEVEL = 5;
|
|||
uniform sampler2D pyramidMap;
|
||||
|
||||
float getZEye(ivec2 pixel) {
|
||||
return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x;
|
||||
return -texelFetch(pyramidMap, pixel, 0/*getResolutionLevel()*/).x;
|
||||
}
|
||||
|
||||
vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) {
|
||||
|
@ -112,7 +112,7 @@ void main(void) {
|
|||
|
||||
// From now on, ssC is the pixel pos in the side
|
||||
ssC.x -= side.y;
|
||||
vec2 fragPos = (vec2(ssC) + 0.5) / getStereoSideWidth();
|
||||
vec2 fragPos = (vec2(ssC) + 0.5) / vec2(getStereoSideWidth(), getStereoSideHeight());
|
||||
|
||||
// The position and normal of the pixel fragment in Eye space
|
||||
vec3 Cp = evalEyePositionFromZeye(side.x, Zeye, fragPos);
|
||||
|
@ -146,16 +146,16 @@ void main(void) {
|
|||
|
||||
outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0);
|
||||
|
||||
<! // KEEP IT for Debugging
|
||||
// KEEP IT for Debugging
|
||||
// Debug Normal: outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0);
|
||||
// Debug Radius outFragColor = vec4(vec3(ssDiskRadius / 100.0), 1.0);
|
||||
// Debug MaxMiplevel outFragColor = vec4(1.0 - vec3(float(clamp(findMSB(int(ssDiskRadius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL))/ float(MAX_MIP_LEVEL)), 1.0);
|
||||
// Debug OffsetPosition
|
||||
float ssR;
|
||||
vec2 unitOffset = tapLocation(int(getNumSamples() - 1), 0, ssR);
|
||||
vec3 Q = getOffsetPosition(side, ssC, unitOffset, ssR * ssDiskRadius);
|
||||
// float ssR;
|
||||
// vec2 unitOffset = tapLocation(int(getNumSamples() - 1), 0, ssR);
|
||||
// vec3 Q = getOffsetPosition(side, ssC, unitOffset, ssR * ssDiskRadius);
|
||||
//outFragColor = vec4(vec3(Q.x / 10.0, Q.y / 2.0, -Q.z/ 3.0), 1.0);
|
||||
vec3 v = normalize(Q - Cp);
|
||||
outFragColor = vec4((v + vec3(1.0))* 0.5, 1.0);
|
||||
!>
|
||||
// vec3 v = normalize(Q - Cp);
|
||||
//outFragColor = vec4((v + vec3(1.0))* 0.5, 1.0);
|
||||
// outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue