void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; const auto& frameTransform = inputs.get0(); const auto& linearDepthFramebuffer = inputs.get2(); auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture(); auto sourceViewport = args->_viewport; auto occlusionViewport = sourceViewport; if (!_gpuTimer) { _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); } if (!_framebuffer) { _framebuffer = std::make_shared<AmbientOcclusionFramebuffer>(); } if (_parametersBuffer->getResolutionLevel() > 0) { linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture(); occlusionViewport = occlusionViewport >> _parametersBuffer->getResolutionLevel(); }
void LightClusteringPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { auto args = renderContext->args; auto deferredTransform = inputs.get0(); auto lightingModel = inputs.get1(); auto surfaceGeometryFramebuffer = inputs.get2(); if (!_lightClusters) { _lightClusters = std::make_shared<LightClusters>(); } // first update the Grid with the new frustum if (!_freeze) { _lightClusters->updateFrustum(args->getViewFrustum()); } // From the LightStage and the current frame, update the light cluster Grid auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>(); auto lightStage = deferredLightingEffect->getLightStage(); _lightClusters->updateLightStage(lightStage); _lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); auto clusteringStats = _lightClusters->updateClusters(); output = _lightClusters; auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); config->numSceneLights = lightStage->getNumLights(); config->numFreeSceneLights = lightStage->getNumFreeLights(); config->numAllocatedSceneLights = lightStage->getNumAllocatedLights(); config->setNumInputLights(clusteringStats.x); config->setNumClusteredLights(clusteringStats.y); config->setNumClusteredLightReferences(clusteringStats.z); }
void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) { auto deferredTransform = inputs.get0(); auto deferredFramebuffer = inputs.get1(); auto lightingModel = inputs.get2(); auto surfaceGeometryFramebuffer = inputs.get3(); auto ssaoFramebuffer = inputs.get4(); auto subsurfaceScatteringResource = inputs.get5(); auto args = renderContext->args; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { _gpuTimer.begin(batch); }); setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource); lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel); cleanupJob.run(sceneContext, renderContext); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { _gpuTimer.end(batch); }); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); config->setGPUBatchRunTime(_gpuTimer.getGPUAverage(), _gpuTimer.getBatchAverage()); }
void DrawLayered3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); const auto jitter = inputs.get2(); config->setNumDrawn((int)inItems.size()); emit config->numDrawnChanged(); RenderArgs* args = renderContext->args; // Clear the framebuffer without stereo // Needs to be distinct from the other batch because using the clear call // while stereo is enabled triggers a warning if (_opaquePass) { gpu::doInBatch("DrawLayered3D::run::clear", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false); }); } if (!inItems.empty()) { // Render the items gpu::doInBatch("DrawLayered3D::main", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setProjectionJitter(jitter.x, jitter.y); batch.setViewTransform(viewMat); // Setup lighting model for all items; batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); batch.setResourceTexture(ru::Texture::AmbientFresnel, lightingModel->getAmbientFresnelLUT()); if (_opaquePass) { renderStateSortShapes(renderContext, _shapePlumber, inItems, _maxDrawn); } else { renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn); } args->_batch = nullptr; }); } }
void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) { auto args = renderContext->args; auto deferredTransform = inputs.get0(); auto deferredFramebuffer = inputs.get1(); auto extraRenderBuffers = inputs.get2(); auto surfaceGeometryFramebuffer = extraRenderBuffers.get0(); auto ssaoFramebuffer = extraRenderBuffers.get1(); auto subsurfaceScatteringResource = extraRenderBuffers.get2(); auto lightingModel = inputs.get3(); auto lightClusters = inputs.get4(); const auto& lightFrame = inputs.get5(); const auto& shadowFrame = inputs.get6(); const auto& hazeFrame = inputs.get7(); if (!_gpuTimer) { _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); } auto previousBatch = args->_batch; gpu::doInBatch(nullptr, args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; _gpuTimer->begin(batch); setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, shadowFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); cleanupJob.run(renderContext); _gpuTimer->end(batch); }); args->_batch = previousBatch; auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); config->setGPUBatchRunTime(_gpuTimer->getGPUAverage(), _gpuTimer->getBatchAverage()); }
void Antialiasing::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto& deferredFrameTransform = inputs.get0(); auto& sourceBuffer = inputs.get1(); auto& linearDepthBuffer = inputs.get2(); auto& velocityBuffer = inputs.get3(); int width = sourceBuffer->getWidth(); int height = sourceBuffer->getHeight(); if (_antialiasingBuffers->get(0)) { if (_antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) {// || (sourceBuffer && (_antialiasingBuffer->getRenderBuffer(1) != sourceBuffer->getRenderBuffer(0)))) { _antialiasingBuffers->edit(0).reset(); _antialiasingBuffers->edit(1).reset(); _antialiasingTextures[0].reset(); _antialiasingTextures[1].reset(); } } if (!_antialiasingBuffers->get(0)) { // Link the antialiasing FBO to texture for (int i = 0; i < 2; i++) { auto& antiAliasingBuffer = _antialiasingBuffers->edit(i); antiAliasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get<FramebufferCache>()->getLightingTexture()->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); _antialiasingTextures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); antiAliasingBuffer->setRenderBuffer(0, _antialiasingTextures[i]); } } gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); batch.setViewportTransform(args->_viewport); // TAA step getAntialiasingPipeline(); batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0); batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0)); batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, velocityBuffer->getVelocityTexture()); // This is only used during debug batch.setResourceTexture(AntialiasingPass_DepthMapSlot, linearDepthBuffer->getLinearDepthTexture()); batch.setUniformBuffer(AntialiasingPass_ParamsSlot, _params); batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, deferredFrameTransform->getFrameTransformBuffer()); batch.setFramebufferSwapChain(_antialiasingBuffers, 1); batch.setPipeline(getAntialiasingPipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4); // Blend step batch.setResourceTexture(AntialiasingPass_SourceMapSlot, nullptr); batch.setFramebuffer(sourceBuffer); if (_params->isDebug()) { batch.setPipeline(getDebugBlendPipeline()); } else { batch.setPipeline(getBlendPipeline()); // Disable sharpen if FXAA batch._glUniform1f(_sharpenLoc, _sharpen * _params.get().regionInfo.z); } batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_NextMapSlot, _antialiasingBuffers, 1); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.advance(_antialiasingBuffers); batch.setUniformBuffer(AntialiasingPass_ParamsSlot, nullptr); batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, nullptr); batch.setResourceTexture(AntialiasingPass_DepthMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_HistoryMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_NextMapSlot, nullptr); }); args->popViewFrustum(); }
void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs) { if (!(doDrawClusterFromDepth || doDrawContent || doDrawGrid)) { return; } auto deferredTransform = inputs.get0(); auto deferredFramebuffer = inputs.get1(); auto lightingModel = inputs.get2(); auto linearDepthTarget = inputs.get3(); auto lightClusters = inputs.get4(); auto args = renderContext->args; gpu::Batch batch; batch.enableStereo(false); // Assign the camera transform batch.setViewportTransform(args->_viewport); glm::mat4 projMat; Transform viewMat; args->getViewFrustum().evalProjectionMatrix(projMat); args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); // Then the actual ClusterGrid attributes batch.setModelTransform(Transform()); // Bind the Light CLuster data strucutre batch.setUniformBuffer(LIGHT_GPU_SLOT, lightClusters->_lightStage->_lightArrayBuffer); batch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, lightClusters->_frustumGridBuffer); batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, lightClusters->_clusterGridBuffer); batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, lightClusters->_clusterContentBuffer); if (doDrawClusterFromDepth) { batch.setPipeline(getDrawClusterFromDepthPipeline()); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, deferredTransform->getFrameTransformBuffer()); if (linearDepthTarget) { batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, linearDepthTarget->getLinearDepthTexture()); } batch.draw(gpu::TRIANGLE_STRIP, 4, 0); batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, nullptr); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr); } if (doDrawContent) { // bind the one gpu::Pipeline we need batch.setPipeline(getDrawClusterContentPipeline()); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, deferredTransform->getFrameTransformBuffer()); if (linearDepthTarget) { batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, linearDepthTarget->getLinearDepthTexture()); } batch.draw(gpu::TRIANGLE_STRIP, 4, 0); batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, nullptr); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr); } gpu::Batch drawGridAndCleanBatch; if (doDrawGrid) { // bind the one gpu::Pipeline we need drawGridAndCleanBatch.setPipeline(getDrawClusterGridPipeline()); auto dims = lightClusters->_frustumGridBuffer->dims; glm::ivec3 summedDims(dims.x*dims.y * dims.z, dims.x*dims.y, dims.x); drawGridAndCleanBatch.drawInstanced(summedDims.x, gpu::LINES, 24, 0); } drawGridAndCleanBatch.setUniformBuffer(LIGHT_GPU_SLOT, nullptr); drawGridAndCleanBatch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, nullptr); drawGridAndCleanBatch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, nullptr); drawGridAndCleanBatch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, nullptr); drawGridAndCleanBatch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, nullptr); drawGridAndCleanBatch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, nullptr); drawGridAndCleanBatch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, nullptr); drawGridAndCleanBatch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, nullptr); args->_context->appendFrameBatch(batch); args->_context->appendFrameBatch(drawGridAndCleanBatch); }