diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 7fbd89acc1..365fbdb16a 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -62,7 +62,8 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); - state->setDepthTest(false); + // state->setDepthTest(false); + state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index d6ebd001d2..eb154f77c9 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,7 +35,9 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _primaryFramebufferFull.reset(); _primaryFramebufferDepthColor.reset(); + _primaryFramebufferDepthStencilColor.reset(); _primaryDepthTexture.reset(); + _primaryStencilTexture.reset(); _primaryColorTexture.reset(); _primaryNormalTexture.reset(); _primarySpecularTexture.reset(); @@ -47,6 +49,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebufferDepthStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); auto width = _frameBufferSize.width(); @@ -63,12 +66,19 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); + _primaryFramebufferDepthStencilColor->setRenderBuffer(0, _primaryColorTexture); + auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); + auto stencilFormat = gpu::Element(gpu::VEC2, gpu::UINT32, gpu::DEPTH_STENCIL); + _primaryStencilTexture = gpu::TexturePointer(gpu::Texture::create2D(stencilFormat, width, height, defaultSampler)); + _primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _primaryFramebufferDepthStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); @@ -89,6 +99,12 @@ gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { return _primaryFramebufferDepthColor; } +gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthStencilColor() { + if (!_primaryFramebufferDepthStencilColor) { + createPrimaryFramebuffer(); + } + return _primaryFramebufferDepthStencilColor; +} gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { if (!_primaryDepthTexture) { @@ -97,6 +113,13 @@ gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { return _primaryDepthTexture; } +gpu::TexturePointer FramebufferCache::getPrimaryStencilTexture() { + if (!_primaryStencilTexture) { + createPrimaryFramebuffer(); + } + return _primaryStencilTexture; +} + gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() { if (!_primaryColorTexture) { createPrimaryFramebuffer(); diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index c2274a77e8..baca07af24 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -31,8 +31,10 @@ public: /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); + gpu::FramebufferPointer getPrimaryFramebufferDepthStencilColor(); gpu::TexturePointer getPrimaryDepthTexture(); + gpu::TexturePointer getPrimaryStencilTexture(); gpu::TexturePointer getPrimaryColorTexture(); gpu::TexturePointer getPrimaryNormalTexture(); gpu::TexturePointer getPrimarySpecularTexture(); @@ -58,7 +60,9 @@ private: gpu::FramebufferPointer _primaryFramebufferFull; gpu::FramebufferPointer _primaryFramebufferDepthColor; + gpu::FramebufferPointer _primaryFramebufferDepthStencilColor; gpu::TexturePointer _primaryDepthTexture; + gpu::TexturePointer _primaryStencilTexture; gpu::TexturePointer _primaryColorTexture; gpu::TexturePointer _primaryNormalTexture; gpu::TexturePointer _primarySpecularTexture; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 65f77689c3..d21b6377be 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "FramebufferCache.h" #include "DeferredLightingEffect.h" @@ -28,6 +29,8 @@ #include "overlay3D_vert.h" #include "overlay3D_frag.h" +#include "drawOpaqueStencil_frag.h" + using namespace render; void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -65,7 +68,7 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); + // _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", @@ -79,7 +82,10 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput()))); auto& renderedOpaques = _jobs.back().getOutput(); _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput()))); - + + _jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil"))); + _jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred"))); + _jobs.push_back(Job(new DrawLight::JobModel("DrawLight"))); _jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred"))); _jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred"))); @@ -289,3 +295,100 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon args->_whiteTexture.reset(); } } + +gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; +const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { + if (!_opaquePipeline) { + auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); + auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + + _opaquePipeline.reset(gpu::Pipeline::create(program, state)); + } + return _opaquePipeline; +} + +void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // from the touched pixel generate the stencil buffer + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [=](gpu::Batch& batch) { + args->_batch = &batch; + + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); + auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); + + batch.setFramebuffer(primaryFboColorDepthStencil); + + batch.enableStereo(false); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setPipeline(getOpaquePipeline()); + batch.setResourceTexture(0, primaryDepth); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(0, nullptr); + + batch.setFramebuffer(primaryFboFull); + + }); + args->_batch = nullptr; +} + +void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background()); + + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.emplace_back(id); + } + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [=](gpu::Batch& batch) { + args->_batch = &batch; + + // auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); + + batch.setFramebuffer(primaryFboColorDepthStencil); + + batch.enableSkybox(true); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + renderItems(sceneContext, renderContext, inItems); + + batch.setFramebuffer(primaryFboFull); + + }); + args->_batch = nullptr; +} \ No newline at end of file diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 8366a2665d..04483fc037 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -59,6 +59,23 @@ public: typedef render::Job::ModelI JobModel; }; +class DrawStencilDeferred { + static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable +public: + static const gpu::PipelinePointer& getOpaquePipeline(); + + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; +}; + +class DrawBackgroundDeferred { +public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; +}; + class DrawOverlay3D { static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable public: diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf new file mode 100644 index 0000000000..0634d2d66a --- /dev/null +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -0,0 +1,30 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// drawOpaqueStencil.frag +// fragment shader +// +// Created by Sam Gateau on 9/29/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()$> + +in vec2 varTexCoord0; +out vec4 outFragColor; + +uniform sampler2D depthTexture; + +void main(void) { + + float depth = texture(depthTexture, varTexCoord0).r; + + outFragColor = vec4(vec3(depth), 1.0); +} diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index ec6656c0dc..b7a03b81e2 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -257,6 +257,7 @@ class DrawBackground { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + typedef Job::Model JobModel; };