bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFramebuffer, Resources& blurringResources) { if (!sourceFramebuffer) { return false; } if (!_blurredFramebuffer) { _blurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); // attach depthStencil if present in source //if (sourceFramebuffer->hasDepthStencil()) { // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); //} auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); _blurredFramebuffer->setRenderBuffer(0, blurringTarget); } else { // it would be easier to just call resize on the bluredFramebuffer and let it work if needed but the source might loose it's depth buffer when doing so if ((_blurredFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_blurredFramebuffer->getHeight() != sourceFramebuffer->getHeight())) { _blurredFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples()); //if (sourceFramebuffer->hasDepthStencil()) { // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); //} } } blurringResources.sourceTexture = sourceFramebuffer->getRenderBuffer(0); blurringResources.blurringFramebuffer = _blurredFramebuffer; blurringResources.blurringTexture = _blurredFramebuffer->getRenderBuffer(0); if (_generateOutputFramebuffer) { // The job output the blur result in a new Framebuffer spawning here. // Let s make sure it s ready for this if (!_outputFramebuffer) { _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); // attach depthStencil if present in source /* if (sourceFramebuffer->hasDepthStencil()) { _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); }*/ auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); _outputFramebuffer->setRenderBuffer(0, blurringTarget); } else { if ((_outputFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_outputFramebuffer->getHeight() != sourceFramebuffer->getHeight())) { _outputFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples()); /* if (sourceFramebuffer->hasDepthStencil()) { _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); }*/ } } // Should be good to use the output Framebuffer as final blurringResources.finalFramebuffer = _outputFramebuffer; } else { // Just the reuse the input as output to blur itself. blurringResources.finalFramebuffer = sourceFramebuffer; } return true; }
void Antialiasing::run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; gpu::doInBatch("Antialiasing::run", 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 float fbWidth = renderContext->args->_viewport.z; float fbHeight = renderContext->args->_viewport.w; // float sMin = args->_viewport.x / fbWidth; // float sWidth = args->_viewport.z / fbWidth; // float tMin = args->_viewport.y / fbHeight; // float tHeight = args->_viewport.w / fbHeight; glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); batch.setModelTransform(Transform()); // FXAA step auto pipeline = getAntialiasingPipeline(renderContext->args); batch.setResourceTexture(0, sourceBuffer->getRenderBuffer(0)); batch.setFramebuffer(_antialiasingBuffer); batch.setPipeline(pipeline); // 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<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); // Blend step batch.setResourceTexture(0, _antialiasingTexture); batch.setFramebuffer(sourceBuffer); batch.setPipeline(getBlendPipeline()); DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); }); }