Introducing blend stage in the AO pipeline

This commit is contained in:
Niraj Venkat 2015-07-20 16:34:02 -07:00
parent f40a6445f5
commit 075c9f05de
5 changed files with 94 additions and 47 deletions

View file

@ -21,7 +21,6 @@
#include "AbstractViewStateInterface.h"
#include "AmbientOcclusionEffect.h"
#include "ProgramObject.h"
#include "RenderUtil.h"
#include "TextureCache.h"
#include "DependencyManager.h"
@ -33,6 +32,8 @@
#include "gaussian_blur_vertical_vert.h"
#include "gaussian_blur_horizontal_vert.h"
#include "gaussian_blur_frag.h"
#include "occlusion_blend_vert.h"
#include "occlusion_blend_frag.h"
const int ROTATION_WIDTH = 4;
const int ROTATION_HEIGHT = 4;
@ -187,6 +188,9 @@ const gpu::PipelinePointer& AmbientOcclusion::getOcclusionPipeline() {
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("depthTexture"), 0));
slotBindings.insert(gpu::Shader::Binding(std::string("normalTexture"), 1));
gpu::Shader::makeProgram(*program, slotBindings);
//_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
@ -282,6 +286,39 @@ const gpu::PipelinePointer& AmbientOcclusion::getHBlurPipeline() {
return _hBlurPipeline;
}
const gpu::PipelinePointer& AmbientOcclusion::getBlendPipeline() {
if (!_blendPipeline) {
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(occlusion_blend_vert)));
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(occlusion_blend_frag)));
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(false, false, gpu::LESS_EQUAL);
// Blend on transparent
state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
// Link the horizontal blur FBO to texture
_hBlurBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32,
DependencyManager::get<TextureCache>()->getFrameBufferSize().width(), DependencyManager::get<TextureCache>()->getFrameBufferSize().height()));
auto format = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto width = _hBlurBuffer->getWidth();
auto height = _hBlurBuffer->getHeight();
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
_hBlurTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
// Good to go add the brand new pipeline
_blendPipeline.reset(gpu::Pipeline::create(program, state));
}
return _blendPipeline;
}
void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
// create a simple pipeline that does:
@ -308,7 +345,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
// Occlusion step
getOcclusionPipeline();
batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getPrimaryDepthTexture());
batch.setResourceTexture(1, DependencyManager::get<TextureCache>()->getPrimaryNormalTexture());
batch.setResourceTexture(1, DependencyManager::get<TextureCache>()->getPrimaryFramebuffer()->getRenderBuffer(0));
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
batch.setFramebuffer(_occlusionBuffer);
@ -339,7 +376,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
batch.setFramebuffer(_hBlurBuffer);
// bind the second gpu::Pipeline we need - for calculating blur buffer
// bind the third gpu::Pipeline we need - for calculating blur buffer
batch.setPipeline(getHBlurPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
@ -348,8 +385,8 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
batch.setResourceTexture(0, _hBlurTexture);
batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryFramebuffer());
// bind the second gpu::Pipeline we need
batch.setPipeline(getOcclusionPipeline());
// bind the fourth gpu::Pipeline we need - for
batch.setPipeline(getBlendPipeline());
glm::vec2 bottomLeftSmall(0.5f, -1.0f);
glm::vec2 topRightSmall(1.0f, -0.5f);

View file

@ -16,46 +16,6 @@
#include "render/DrawTask.h"
class AbstractViewStateInterface;
class ProgramObject;
/// A screen space ambient occlusion effect. See John Chapman's tutorial at
/// http://john-chapman-graphics.blogspot.co.uk/2013/01/ssao-tutorial.html for reference.
/*
class AmbientOcclusionEffect : public Dependency {
SINGLETON_DEPENDENCY
public:
void init(AbstractViewStateInterface* viewState);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<AmbientOcclusionEffect> JobModel;
AmbientOcclusionEffect() {}
virtual ~AmbientOcclusionEffect() {}
private:
ProgramObject* _occlusionProgram;
int _nearLocation;
int _farLocation;
int _leftBottomLocation;
int _rightTopLocation;
int _noiseScaleLocation;
int _texCoordOffsetLocation;
int _texCoordScaleLocation;
ProgramObject* _blurProgram;
int _blurScaleLocation;
GLuint _rotationTextureID;
AbstractViewStateInterface* _viewState;
};
*/
class AmbientOcclusion {
public:
@ -67,12 +27,14 @@ public:
const gpu::PipelinePointer& getOcclusionPipeline();
const gpu::PipelinePointer& getHBlurPipeline();
const gpu::PipelinePointer& getVBlurPipeline();
const gpu::PipelinePointer& getBlendPipeline();
private:
gpu::PipelinePointer _occlusionPipeline;
gpu::PipelinePointer _hBlurPipeline;
gpu::PipelinePointer _vBlurPipeline;
gpu::PipelinePointer _blendPipeline;
gpu::FramebufferPointer _occlusionBuffer;
gpu::FramebufferPointer _hBlurBuffer;

View file

@ -40,9 +40,9 @@ void main(void) {
float c = (2.0 * n) / (f + n - z * (f - n)); // convert to linear values
//gl_FragColor = vec4(c, c, c, 1.0);
gl_FragColor = normalColor;
gl_FragColor = mix(depthColor, normalColor, normalColor.a);
//vec3 p = getPosition(i.uv);
//vec3 n = getNormal(i.uv);
vec2 rand = vec2(getRandom(varTexcoord.xy), getRandom(varTexcoord.yx));
//vec2 rand = vec2(getRandom(varTexcoord.xy), getRandom(varTexcoord.yx));
}

View file

@ -0,0 +1,24 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// occlusion_blend.frag
// fragment shader
//
// Created by Niraj Venkat on 7/20/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
<@include DeferredBufferWrite.slh@>
varying vec2 varTexcoord;
uniform sampler2D blurredOcclusionTexture;
void main(void) {
vec4 depthColor = texture2D(blurredOcclusionTexture, varTexcoord.xy);
gl_FragColor = depthColor;
}

View file

@ -0,0 +1,24 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// occlusion_blend.vert
// vertex shader
//
// Created by Niraj Venkat on 7/20/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
varying vec2 varTexcoord;
void main(void) {
varTexcoord = gl_MultiTexCoord0.xy;
gl_Position = gl_Vertex;
}