diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index f7881b0333..c5ec6b0f6e 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "AntialiasingEffect.h" #include "StencilMaskPass.h" @@ -23,7 +24,7 @@ #include "DependencyManager.h" #include "ViewFrustum.h" #include "GeometryCache.h" - +/* #include "fxaa_vert.h" #include "fxaa_frag.h" #include "fxaa_blend_frag.h" @@ -170,3 +171,183 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); }); } +*/ + +#include "fxaa_vert.h" +#include "fxaa_frag.h" +#include "fxaa_blend_frag.h" + + +Antialiasing::Antialiasing() { + _geometryId = DependencyManager::get()->allocateID(); +} + +Antialiasing::~Antialiasing() { + auto geometryCache = DependencyManager::get(); + if (geometryCache) { + geometryCache->releaseID(_geometryId); + } +} + +const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { + int width = DependencyManager::get()->getFrameBufferSize().width(); + int height = DependencyManager::get()->getFrameBufferSize().height(); + + if (_antialiasingBuffer && _antialiasingBuffer->getSize() != uvec2(width, height)) { + _antialiasingBuffer.reset(); + } + + if (!_antialiasingBuffer) { + // Link the antialiasing FBO to texture + _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get()->getLightingTexture()->getTexelFormat(); + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + _antialiasingTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); + _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); + } + + if (!_antialiasingPipeline) { + + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(fxaa_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("colorTexture"), 0)); + + gpu::Shader::makeProgram(*program, slotBindings); + + _texcoordOffsetLoc = program->getUniforms().findLocation("texcoordOffset"); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + PrepareStencil::testMask(*state); + + state->setDepthTest(false, false, gpu::LESS_EQUAL); + state->setBlendFunction(true, gpu::State::BlendArg::SRC_ALPHA, gpu::State::BlendOp::BLEND_OP_ADD, gpu::State::BlendArg::INV_SRC_ALPHA ); + + // Good to go add the brand new pipeline + _antialiasingPipeline = gpu::Pipeline::create(program, state); + } + + return _antialiasingPipeline; +} + +const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { + if (!_blendPipeline) { + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(fxaa_blend_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("colorTexture"), 0)); + + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setDepthTest(false, false, gpu::LESS_EQUAL); + PrepareStencil::testMask(*state); + + // Good to go add the brand new pipeline + _blendPipeline = gpu::Pipeline::create(program, state); + } + return _blendPipeline; +} + +void Antialiasing::run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer) { + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + RenderArgs* args = renderContext->args; + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setViewportTransform(args->_viewport); + + // FIXME: NEED to simplify that code to avoid all the GeometryCahce call, this is purely pixel manipulation + auto framebufferCache = DependencyManager::get(); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); + float fbWidth = framebufferSize.width(); + float fbHeight = framebufferSize.height(); + + + // FXAA step + batch.setResourceTexture(0, sourceBuffer->getRenderBuffer(0)); + batch.setFramebuffer(_antialiasingBuffer); + batch.setPipeline(getAntialiasingPipeline()); + + batch.draw(gpu::TRIANGLES, 4, 0); + + // initialize the view-space unpacking uniforms using frustum data + /* float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; + + args->getViewFrustum().computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + + // float depthScale = (farVal - nearVal) / farVal; + // float nearScale = -1.0f / nearVal; + // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; + // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + + batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); + + glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); + glm::vec2 bottomLeft(-1.0f, -1.0f); + glm::vec2 topRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(0.0f, 0.0f); + glm::vec2 texCoordBottomRight(1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); + + */ + // Blend step + getBlendPipeline(); + batch.setResourceTexture(0, _antialiasingTexture); + batch.setFramebuffer(sourceBuffer); + batch.setPipeline(getBlendPipeline()); + + // DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); + batch.draw(gpu::TRIANGLES, 4, 0); + + }); +} + + + +void JitterSample::configure(const Config& config) { + _freeze = config.freeze; + _scale = config.scale; +} +void JitterSample::run(const render::RenderContextPointer& renderContext, JitterBuffer& jitterBuffer) { + auto& current = _jitterBuffer.edit().currentIndex; + if (!_freeze) { + current = (current + 1) % SampleSequence::SEQUENCE_LENGTH; + } + auto viewFrustum = renderContext->args->getViewFrustum(); + auto projMat = viewFrustum.getProjection(); + auto theNear = viewFrustum.getNearClip(); + + auto jit = _scale * jitterBuffer.get().offsets[current]; + auto width = (float) renderContext->args->_viewport.z; + auto height = (float) renderContext->args->_viewport.w; + + auto oneOverRL = 0.5 * projMat[0][0] / theNear; + auto oneOverTB = 0.5 * projMat[1][1] / theNear; + + + auto jx = -4.0 * jit.x / width; + auto jy = -4.0 * jit.y / height; + + projMat[2][0] += jx; + projMat[2][1] += jy; + + viewFrustum.setProjection(projMat); + + renderContext->args->pushViewFrustum(viewFrustum); + + jitterBuffer = _jitterBuffer; +} + + diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index e403032b4e..a74c332b91 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -50,4 +50,79 @@ private: int _geometryId { 0 }; }; +/* +class AntiAliasingConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(bool enabled MEMBER enabled) +public: + AntiAliasingConfig() : render::Job::Config(true) {} +}; + +class Antialiasing { +public: + using Config = AntiAliasingConfig; + using JobModel = render::Job::ModelI; + + Antialiasing(); + ~Antialiasing(); + void configure(const Config& config) {} + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer); + + const gpu::PipelinePointer& getAntialiasingPipeline(); + const gpu::PipelinePointer& getBlendPipeline(); + +private: + + // Uniforms for AA + gpu::int32 _texcoordOffsetLoc; + + gpu::FramebufferPointer _antialiasingBuffer; + + gpu::TexturePointer _antialiasingTexture; + + gpu::PipelinePointer _antialiasingPipeline; + gpu::PipelinePointer _blendPipeline; + int _geometryId { 0 }; +}; +*/ +class JitterSampleConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(float scale MEMBER scale NOTIFY dirty) + Q_PROPERTY(bool freeze MEMBER freeze NOTIFY dirty) +public: + JitterSampleConfig() : render::Job::Config(true) {} + + float scale { 0.5f }; + bool freeze{ false }; +signals: + void dirty(); +}; + +class JitterSample { +public: + + struct SampleSequence { + static const int SEQUENCE_LENGTH { 4 }; + int sequenceLength{ SEQUENCE_LENGTH }; + int currentIndex { 0 }; + + glm::vec2 offsets[SEQUENCE_LENGTH] { { 1.0f, 1.0f},{ -1.0f, -1.0f}, { 1.0f, -1.0f}, { -1.0f, 1.0f} }; + }; + + using JitterBuffer = gpu::StructBuffer; + + using Config = JitterSampleConfig; + using JobModel = render::Job::ModelO; + + void configure(const Config& config); + void run(const render::RenderContextPointer& renderContext, JitterBuffer& jitterBuffer); + + +private: + + JitterBuffer _jitterBuffer; + float _scale { 1.0 }; + bool _freeze { false }; +}; + #endif // hifi_AntialiasingEffect_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 1b99fe92ee..34e7eedad0 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -72,6 +72,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Prepare deferred, generate the shared Deferred Frame Transform const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); const auto lightingModel = task.addJob("LightingModel"); + + const auto jitterBuffer = task.addJob("JitterCam"); // GPU jobs: Start preparing the primary, deferred and lighting buffer const auto primaryFramebuffer = task.addJob("PreparePrimaryBuffer"); diff --git a/libraries/render-utils/src/fxaa.slf b/libraries/render-utils/src/fxaa.slf index 7b241a3ebf..fce9f3b05f 100644 --- a/libraries/render-utils/src/fxaa.slf +++ b/libraries/render-utils/src/fxaa.slf @@ -25,11 +25,12 @@ precision mediump int; uniform sampler2D colorTexture; uniform vec2 texcoordOffset; -in vec2 varTexcoord; +in vec2 varTexCoord0; out vec4 outFragColor; void main() { - // filter width limit for dependent "two-tap" texture samples + outFragColor = vec4(texture(colorTexture, varTexCoord0).xyz, 0.3); + /* // filter width limit for dependent "two-tap" texture samples float FXAA_SPAN_MAX = 8.0; // local contrast multiplier for performing AA @@ -90,5 +91,5 @@ void main() { } else { outFragColor.xyz=rgbB; } - outFragColor.a = 1.0; + outFragColor.a = 1.0;*/ } diff --git a/libraries/render-utils/src/fxaa_blend.slf b/libraries/render-utils/src/fxaa_blend.slf index d5819cc9a6..c38de8cb4e 100644 --- a/libraries/render-utils/src/fxaa_blend.slf +++ b/libraries/render-utils/src/fxaa_blend.slf @@ -14,11 +14,11 @@ <@include DeferredBufferWrite.slh@> -in vec2 varTexcoord; +in vec2 varTexCoord0; out vec4 outFragColor; uniform sampler2D colorTexture; void main(void) { - outFragColor = texture(colorTexture, varTexcoord); + outFragColor = texture(colorTexture, varTexCoord0); }