From de143d0ea28592ade76fed5cdc8fc4904b0168f1 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 6 Jun 2017 17:07:20 +0200 Subject: [PATCH] Switched to uniforms for sending fade shader data. Moved more fade functions to FadeEffect class --- libraries/render-utils/src/Fade.slh | 15 ++--- libraries/render-utils/src/FadeEffect.cpp | 39 +++++++++++- libraries/render-utils/src/FadeEffect.h | 10 +++ .../render-utils/src/MeshPartPayload.cpp | 61 ++----------------- libraries/render-utils/src/MeshPartPayload.h | 13 +--- .../render-utils/src/RenderDeferredTask.cpp | 6 +- 6 files changed, 60 insertions(+), 84 deletions(-) diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index 06eed5b21f..d634473dd0 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -18,15 +18,8 @@ <@func declareFadeFragment()@> -struct Fade { - vec3 _Offset; - float _Percent; -}; - -uniform fadeBuffer { - Fade fade; -}; - +uniform vec3 fadeOffset; +uniform float fadePercent; uniform sampler2D fadeMaskMap; vec2 hash2D(vec3 position) { @@ -37,7 +30,7 @@ float evalFadeMask(vec3 position) { const float FADE_MASK_INV_SCALE = 1.0; // Do tri-linear interpolation - vec3 noisePosition = position * FADE_MASK_INV_SCALE + fade._Offset; + vec3 noisePosition = position * FADE_MASK_INV_SCALE + fadeOffset; vec3 noisePositionFloored = floor(noisePosition); vec3 noisePositionFraction = fract(noisePosition); float noiseLowXLowYLowZ = textureLod(fadeMaskMap, hash2D(noisePositionFloored), 0).r; @@ -57,7 +50,7 @@ float evalFadeMask(vec3 position) { } void applyFade(vec3 position) { - if (evalFadeMask(position) > fade._Percent) { + if (evalFadeMask(position) > fadePercent) { discard; } } diff --git a/libraries/render-utils/src/FadeEffect.cpp b/libraries/render-utils/src/FadeEffect.cpp index f750798914..0bca42ad12 100644 --- a/libraries/render-utils/src/FadeEffect.cpp +++ b/libraries/render-utils/src/FadeEffect.cpp @@ -2,6 +2,9 @@ #include "TextureCache.h" #include +#include +#include +#include FadeEffect::FadeEffect() : _isDebugEnabled{ false }, @@ -11,8 +14,7 @@ FadeEffect::FadeEffect() : _fadeMaskMap = DependencyManager::get()->getImageTexture(texturePath, image::TextureUsage::STRICT_TEXTURE); } -render::ShapeKey::Builder FadeEffect::getKeyBuilder() const -{ +render::ShapeKey::Builder FadeEffect::getKeyBuilder() const { render::ShapeKey::Builder builder; if (_isDebugEnabled) { @@ -23,3 +25,36 @@ render::ShapeKey::Builder FadeEffect::getKeyBuilder() const return builder; } +void FadeEffect::bindPerBatch(gpu::Batch& batch) const +{ + batch.setResourceTexture(render::ShapePipeline::Slot::MAP::FADE_MASK, _fadeMaskMap); +} + +float FadeEffect::computeFadePercent(quint64 startTime) const { + float fadeAlpha = 1.0f; + const double INV_FADE_PERIOD = 1.0 / (double)(3 * USECS_PER_SECOND); + double fraction = (double)(usecTimestampNow() - startTime) * INV_FADE_PERIOD; + if (fraction < 1.0) { + fadeAlpha = Interpolate::simpleNonLinearBlend(fraction); + } + return fadeAlpha; +} + +void FadeEffect::bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime, State state) const { + if (state != Complete || _isDebugEnabled) { + const gpu::ShaderPointer& program = args->_pipeline->pipeline->getProgram(); + int fadeOffsetLoc = program->getUniforms().findLocation("fadeOffset"); + int fadePercentLoc = program->getUniforms().findLocation("fadePercent"); + float percent; + + // A bit ugly to have the test at every bind... + if (!_isDebugEnabled) { + percent = computeFadePercent(startTime); + } + else { + percent = _debugFadePercent; + } + batch._glUniform1f(fadePercentLoc, percent); + batch._glUniform3f(fadeOffsetLoc, offset.x, offset.y, offset.z); + } +} diff --git a/libraries/render-utils/src/FadeEffect.h b/libraries/render-utils/src/FadeEffect.h index 6c5b2c90c8..b1cbf0cb29 100644 --- a/libraries/render-utils/src/FadeEffect.h +++ b/libraries/render-utils/src/FadeEffect.h @@ -20,6 +20,12 @@ class FadeEffect : public Dependency { SINGLETON_DEPENDENCY public: + enum State : uint8_t { + WaitingToStart = 0, + InProgress = 1, + Complete = 2, + }; + FadeEffect(); const gpu::TexturePointer getFadeMaskMap() const { return _fadeMaskMap; } @@ -32,6 +38,10 @@ public: render::ShapeKey::Builder getKeyBuilder() const; + void bindPerBatch(gpu::Batch& batch) const; + void bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime, State state = InProgress) const; + float computeFadePercent(quint64 startTime) const; + private: gpu::TexturePointer _fadeMaskMap; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 1d6ddea70f..a44974cc92 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -321,19 +321,10 @@ template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, Ren } } -struct ModelMeshPartPayload::Fade -{ - glm::vec3 _offset; // The noise offset - float _percent; // The fade percent -}; - ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : _meshIndex(_meshIndex), _shapeID(shapeIndex) { - Fade fade; - _fadeBuffer = gpu::BufferView(std::make_shared(sizeof(Fade), (const gpu::Byte*) &fade)); - assert(model && model->isLoaded()); _model = model; auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex); @@ -493,7 +484,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const { if (wireframe) { builder.withWireframe(); } - if (_fadeState != FADE_COMPLETE) { + if (_fadeState != FadeEffect::Complete) { builder.withFade(); } return builder.build(); @@ -529,48 +520,6 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline: batch.setModelTransform(_transform); } -float ModelMeshPartPayload::computeFadePercent() const { - if (_fadeState == FADE_WAITING_TO_START) { - return 0.0f; - } - float fadeAlpha = 1.0f; - const double INV_FADE_PERIOD = 1.0 / (double)(3 * USECS_PER_SECOND); - double fraction = (double)(usecTimestampNow() - _fadeStartTime) * INV_FADE_PERIOD; - if (fraction < 1.0) { - fadeAlpha = Interpolate::simpleNonLinearBlend(fraction); - } - if (fadeAlpha >= 1.0f) { - _fadeState = FADE_COMPLETE; - // when fade-in completes we flag model for one last "render item update" - ModelPointer model = _model.lock(); - if (model) { - model->setRenderItemsNeedUpdate(); - } - fadeAlpha = 1.0f; - } - return fadeAlpha; -} - -void ModelMeshPartPayload::bindFade(gpu::Batch& batch) const { - const bool isDebugEnabled = DependencyManager::get()->isDebugEnabled(); - - if (_fadeState != FADE_COMPLETE || isDebugEnabled) { - auto& fade = _fadeBuffer.edit(); - glm::vec3 offset = _transform.getTranslation(); - - // A bit ugly to have the test at every bind... - if (!isDebugEnabled) { - fade._percent = computeFadePercent(); - } - else { - fade._percent = DependencyManager::get()->getDebugFadePercent(); - } - - fade._offset = offset; - batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::FADE, _fadeBuffer); - } -} - void ModelMeshPartPayload::render(RenderArgs* args) { PerformanceTimer perfTimer("ModelMeshPartPayload::render"); @@ -579,13 +528,13 @@ void ModelMeshPartPayload::render(RenderArgs* args) { return; // bail asap } - if (_fadeState == FADE_WAITING_TO_START) { + if (_fadeState == FadeEffect::WaitingToStart) { if (model->isLoaded()) { if (EntityItem::getEntitiesShouldFadeFunction()()) { _fadeStartTime = usecTimestampNow(); - _fadeState = FADE_IN_PROGRESS; + _fadeState = FadeEffect::InProgress; } else { - _fadeState = FADE_COMPLETE; + _fadeState = FadeEffect::Complete; } model->setRenderItemsNeedUpdate(); } else { @@ -618,7 +567,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) { bindMaterial(batch, locations, args->_enableTexturing); // Apply fade effect - bindFade(batch); + DependencyManager::get()->bindPerItem(batch, args, _transform.getTranslation(), _fadeStartTime, _fadeState); args->_details._materialSwitches++; diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 0d3a8df576..6762601738 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -22,10 +22,7 @@ #include #include "Model.h" - -const uint8_t FADE_WAITING_TO_START = 0; -const uint8_t FADE_IN_PROGRESS = 1; -const uint8_t FADE_COMPLETE = 2; +#include "FadeEffect.h" class Model; @@ -95,8 +92,6 @@ public: const Transform& boundTransform, const gpu::BufferPointer& buffer); - float computeFadePercent() const; - // Render Item interface render::ItemKey getKey() const override; int getLayer() const; @@ -106,7 +101,6 @@ public: // ModelMeshPartPayload functions to perform render void bindMesh(gpu::Batch& batch) override; void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override; - void bindFade(gpu::Batch& batch) const; void initCache(); @@ -124,11 +118,8 @@ public: private: - struct Fade; - - mutable gpu::BufferView _fadeBuffer; mutable quint64 _fadeStartTime { 0 }; - mutable uint8_t _fadeState { FADE_WAITING_TO_START }; + mutable FadeEffect::State _fadeState { FadeEffect::WaitingToStart } ; }; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 1e8673b385..8b2a232c87 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -258,7 +258,6 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& RenderArgs* args = renderContext->args; ShapeKey::Builder defaultKeyBuilder = DependencyManager::get()->getKeyBuilder(); - gpu::TexturePointer fadeMaskMap = DependencyManager::get()->getFadeMaskMap(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -285,7 +284,7 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& } // Prepare fade effect - batch.setResourceTexture(ShapePipeline::Slot::MAP::FADE_MASK, fadeMaskMap); + DependencyManager::get()->bindPerBatch(batch); ShapeKey globalKey = keyBuilder.build(); args->_globalShapeKey = globalKey._flags.to_ulong(); @@ -310,7 +309,6 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const RenderArgs* args = renderContext->args; ShapeKey::Builder defaultKeyBuilder = DependencyManager::get()->getKeyBuilder(); - gpu::TexturePointer fadeMaskMap = DependencyManager::get()->getFadeMaskMap(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -337,7 +335,7 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const } // Prepare fade effect - batch.setResourceTexture(ShapePipeline::Slot::MAP::FADE_MASK, fadeMaskMap); + DependencyManager::get()->bindPerBatch(batch); ShapeKey globalKey = keyBuilder.build(); args->_globalShapeKey = globalKey._flags.to_ulong();