Switched to uniforms for sending fade shader data. Moved more fade functions to FadeEffect class

This commit is contained in:
Olivier Prat 2017-06-06 17:07:20 +02:00
parent a9ab9d2476
commit de143d0ea2
6 changed files with 60 additions and 84 deletions

View file

@ -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;
}
}

View file

@ -2,6 +2,9 @@
#include "TextureCache.h"
#include <PathUtils.h>
#include <NumericalConstants.h>
#include <Interpolate.h>
#include <render/ShapePipeline.h>
FadeEffect::FadeEffect() :
_isDebugEnabled{ false },
@ -11,8 +14,7 @@ FadeEffect::FadeEffect() :
_fadeMaskMap = DependencyManager::get<TextureCache>()->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);
}
}

View file

@ -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;

View file

@ -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<gpu::Buffer>(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<FadeEffect>()->isDebugEnabled();
if (_fadeState != FADE_COMPLETE || isDebugEnabled) {
auto& fade = _fadeBuffer.edit<Fade>();
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<FadeEffect>()->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<FadeEffect>()->bindPerItem(batch, args, _transform.getTranslation(), _fadeStartTime, _fadeState);
args->_details._materialSwitches++;

View file

@ -22,10 +22,7 @@
#include <model/Geometry.h>
#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 } ;
};

View file

@ -258,7 +258,6 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
RenderArgs* args = renderContext->args;
ShapeKey::Builder defaultKeyBuilder = DependencyManager::get<FadeEffect>()->getKeyBuilder();
gpu::TexturePointer fadeMaskMap = DependencyManager::get<FadeEffect>()->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<FadeEffect>()->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<FadeEffect>()->getKeyBuilder();
gpu::TexturePointer fadeMaskMap = DependencyManager::get<FadeEffect>()->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<FadeEffect>()->bindPerBatch(batch);
ShapeKey globalKey = keyBuilder.build();
args->_globalShapeKey = globalKey._flags.to_ulong();