From 8a12d0c106be25a3db8b55aa80579b04b9bb73b0 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Jun 2017 08:54:23 +0200 Subject: [PATCH] Fade effect working again for basic enter domain but with various Fade jobs --- .../src/RenderablePolyVoxEntityItem.cpp | 16 +- .../src/RenderablePolyVoxEntityItem.h | 2 + .../src/RenderableShapeEntityItem.cpp | 1 - .../entities-renderer/src/polyvox_fade.slf | 5 +- libraries/entities/src/EntityItem.h | 1 + libraries/render-utils/src/Fade.slh | 78 ++++- libraries/render-utils/src/FadeEffect.cpp | 238 +++++++++++--- libraries/render-utils/src/FadeEffect.h | 307 ++++++++++++++++-- libraries/render-utils/src/GeometryCache.cpp | 2 - .../render-utils/src/MeshPartPayload.cpp | 20 +- libraries/render-utils/src/MeshPartPayload.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 39 +-- .../render-utils/src/RenderShadowTask.cpp | 4 +- libraries/render-utils/src/model_fade.slf | 5 +- .../render-utils/src/model_lightmap_fade.slf | 6 +- .../src/model_lightmap_normal_map_fade.slf | 6 +- ...odel_lightmap_normal_specular_map_fade.slf | 6 +- .../src/model_lightmap_specular_map_fade.slf | 6 +- .../src/model_normal_map_fade.slf | 4 +- .../src/model_normal_specular_map_fade.slf | 6 +- .../render-utils/src/model_shadow_fade.slf | 2 +- .../src/model_specular_map_fade.slf | 6 +- .../src/model_translucent_fade.slf | 6 +- .../src/model_translucent_unlit_fade.slf | 6 +- .../render-utils/src/model_unlit_fade.slf | 6 +- libraries/render-utils/src/simple_fade.slf | 12 +- .../render-utils/src/simple_textured_fade.slf | 8 +- .../src/simple_textured_unlit_fade.slf | 8 +- .../src/simple_transparent_textured_fade.slf | 8 +- ...simple_transparent_textured_unlit_fade.slf | 6 +- .../src/skin_model_shadow_fade.slf | 2 +- libraries/render/src/render/Args.h | 1 + libraries/render/src/render/Item.h | 7 +- .../src/render/RenderFetchCullSortTask.cpp | 3 +- .../src/render/RenderFetchCullSortTask.h | 2 +- libraries/render/src/render/ShapePipeline.cpp | 4 +- libraries/render/src/render/ShapePipeline.h | 2 + libraries/render/src/task/Varying.h | 5 + .../developer/utilities/render/debugFade.js | 2 +- scripts/developer/utilities/render/fade.qml | 237 ++++++++++++-- 40 files changed, 900 insertions(+), 187 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 614af2c64e..32e71389ab 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -740,10 +740,11 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS)); slotBindings.insert(gpu::Shader::Binding(std::string("xMap"), 0)); slotBindings.insert(gpu::Shader::Binding(std::string("yMap"), 1)); slotBindings.insert(gpu::Shader::Binding(std::string("zMap"), 2)); - slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), 3)); + slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), render::ShapePipeline::Slot::MAP::FADE_MASK)); auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_BACK); @@ -823,9 +824,9 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { } // Apply fade effect - auto fadeEffect = DependencyManager::get(); - if (fadeEffect->bindPerItem(batch, pipeline.get(), glm::vec3(0, 0, 0), _fadeStartTime, isFading())) { - fadeEffect->bindPerBatch(batch, 3); + if (args->_enableFade) { + FadeRenderJob::bindPerBatch(batch, render::ShapePipeline::Slot::MAP::FADE_MASK, render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS); + FadeRenderJob::bindPerItem(batch, pipeline.get(), glm::vec3(0, 0, 0), _fadeStartTime); } int voxelVolumeSizeLocation = pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize"); @@ -882,6 +883,13 @@ namespace render { payload->_owner->getRenderableInterface()->render(args); } } + + template <> bool payloadMustFade(const PolyVoxPayload::Pointer& payload) { + if (payload && payload->_owner) { + return payload->_owner->mustFade(); + } + return false; + } } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 73ab0e5937..72871f0439 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -38,6 +38,7 @@ namespace render { template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload); template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload); template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args); + template <> bool payloadMustFade(const PolyVoxPayload::Pointer& payload); } @@ -205,4 +206,5 @@ private: bool inUserBounds(const PolyVox::SimpleVolume* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle, int x, int y, int z); + #endif // hifi_RenderablePolyVoxEntityItem_h diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 917b97dc29..a8ead00771 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -126,7 +126,6 @@ void RenderableShapeEntityItem::render(RenderArgs* args) { color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; // FIXME, support instanced multi-shape rendering using multidraw indirect auto geometryCache = DependencyManager::get(); - auto fadeEffect = DependencyManager::get(); auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); assert(pipeline != nullptr); diff --git a/libraries/entities-renderer/src/polyvox_fade.slf b/libraries/entities-renderer/src/polyvox_fade.slf index ac2d77564b..29bd51200a 100644 --- a/libraries/entities-renderer/src/polyvox_fade.slf +++ b/libraries/entities-renderer/src/polyvox_fade.slf @@ -30,7 +30,8 @@ uniform vec3 voxelVolumeSize; <$declareFadeFragment()$> void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 emissive; + applyFade(_worldFadePosition.xyz, emissive); vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); @@ -54,7 +55,7 @@ void main(void) { vec3(diffuse), DEFAULT_ROUGHNESS, DEFAULT_METALLIC, - DEFAULT_EMISSIVE, + DEFAULT_EMISSIVE+emissive, DEFAULT_OCCLUSION, DEFAULT_SCATTERING); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 0318c72991..6cd8e18a27 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -459,6 +459,7 @@ public: bool isFading() const { return _isFading; } float getFadingRatio() const { return (isFading() ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f); } + bool mustFade() const { return _isFading; } virtual void emitScriptEvent(const QVariant& message) {} diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index 351cbad863..776343dc53 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -18,9 +18,26 @@ <@func declareFadeFragment()@> -uniform vec3 fadeOffset; -uniform float fadePercent; -uniform float fadeInvScale; +struct FadeParameters +{ + vec4 _baseInvSizeAndLevel; + vec4 _noiseInvSizeAndLevel; + vec3 _innerEdgeColor; + vec3 _outerEdgeColor; + vec2 _edgeWidthInvWidth; + int _invertBase; + float _padding; +}; + +#define EVENT_CATEGORY_COUNT 5 + +uniform fadeParametersBuffer { + FadeParameters fadeParameters[EVENT_CATEGORY_COUNT]; +}; +uniform int fadeCategory; +uniform vec3 fadeNoiseOffset; +uniform vec3 fadeBaseOffset; +uniform float fadeThreshold; uniform sampler2D fadeMaskMap; vec2 hash2D(vec3 position) { @@ -31,9 +48,9 @@ float noise3D(vec3 position) { return textureLod(fadeMaskMap, hash2D(position), 0).r; } -float evalFadeMask(vec3 position) { +float evalFadeNoiseGradient(vec3 position) { // Do tri-linear interpolation - vec3 noisePosition = position * fadeInvScale + fadeOffset; + vec3 noisePosition = position * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.xyz + fadeNoiseOffset; vec3 noisePositionFloored = floor(noisePosition); vec3 noisePositionFraction = fract(noisePosition); float noiseLowXLowYLowZ = noise3D(noisePositionFloored); @@ -49,14 +66,59 @@ float evalFadeMask(vec3 position) { vec4 maskXY = mix(maskLowZ, maskHighZ, noisePositionFraction.z); vec2 maskY = mix(maskXY.xy, maskXY.zw, noisePositionFraction.x); - return mix(maskY.x, maskY.y, noisePositionFraction.y); + return mix(maskY.x, maskY.y, noisePositionFraction.y) * fadeParameters[fadeCategory]._noiseInvSizeAndLevel.w; } -void applyFade(vec3 position) { - if (evalFadeMask(position) > fadePercent) { +float evalFadeBaseGradient(vec3 position) { + float gradient = length((position - fadeBaseOffset) * fadeParameters[fadeCategory]._baseInvSizeAndLevel.xyz); + if (fadeParameters[fadeCategory]._invertBase!=0) { + gradient = 1.0 - gradient; + } + gradient *= fadeParameters[fadeCategory]._baseInvSizeAndLevel.w; + return gradient; +} + +float evalFadeGradient(vec3 position) { + float baseGradient = evalFadeBaseGradient(position); + float noiseGradient = evalFadeNoiseGradient(position); + float gradient = (noiseGradient-0.5*fadeParameters[fadeCategory]._baseInvSizeAndLevel.w); + + // This is to be sure the noise is zero at the start of the gradient + gradient *= (1-baseGradient*baseGradient); + gradient += baseGradient; + return gradient; +} + +float evalFadeAlpha(vec3 position) { +/* float edgeWidth = fadeParameters[fadeCategory]._edgeWidthInvWidth.x; + float cutoff = mix(-edgeWidth, 1.0+edgeWidth, fadeThreshold); + + return evalFadeGradient(position)-cutoff;*/ + return evalFadeNoiseGradient(position)-fadeThreshold; +} + +void applyFadeClip(vec3 position) { + if (evalFadeAlpha(position) < 0) { discard; } } + +void applyFade(vec3 position, out vec3 emissive) { + float alpha = evalFadeAlpha(position); + if (alpha < 0) { + discard; + } + /* + float edgeMask = alpha * fadeParameters[fadeCategory]._edgeWidthInvWidth.y; + float edgeAlpha = 1.0-clamp(edgeMask, 0, 1); + + edgeMask = step(edgeMask, 1.f); + edgeAlpha *= edgeAlpha; // Square to have a nice ease out + emissive = mix(fadeParameters[fadeCategory]._innerEdgeColor, fadeParameters[fadeCategory]._outerEdgeColor, edgeAlpha); + emissive *= edgeMask; + */ + emissive = vec3(0,0,0); +} <@endfunc@> <@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/FadeEffect.cpp b/libraries/render-utils/src/FadeEffect.cpp index 516fd56478..d2bad0d1ef 100644 --- a/libraries/render-utils/src/FadeEffect.cpp +++ b/libraries/render-utils/src/FadeEffect.cpp @@ -4,73 +4,223 @@ #include #include #include -#include +#include -FadeEffect::FadeEffect() : - _invScale{ 1.f }, - _duration{ 3.f }, - _debugFadePercent{ 0.f }, - _isDebugEnabled{ false } +void FadeSwitchJob::configure(const Config& config) { + _isEditEnabled = config.editFade; +} + +void FadeSwitchJob::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) { + auto& normalOutputs = output.edit0(); + auto& fadeOutputs = output.edit1(); + + // Only shapes are affected by fade at this time. + normalOutputs[RenderFetchCullSortTask::LIGHT] = input[RenderFetchCullSortTask::LIGHT]; + normalOutputs[RenderFetchCullSortTask::META] = input[RenderFetchCullSortTask::META]; + normalOutputs[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE] = input[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; + normalOutputs[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE] = input[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; + normalOutputs[RenderFetchCullSortTask::BACKGROUND] = input[RenderFetchCullSortTask::BACKGROUND]; + normalOutputs[RenderFetchCullSortTask::SPATIAL_SELECTION] = input[RenderFetchCullSortTask::SPATIAL_SELECTION]; + + // Now, distribute items that need to be faded accross both outputs + distribute(renderContext, input[RenderFetchCullSortTask::OPAQUE_SHAPE], normalOutputs[RenderFetchCullSortTask::OPAQUE_SHAPE], fadeOutputs[OPAQUE_SHAPE]); + distribute(renderContext, input[RenderFetchCullSortTask::TRANSPARENT_SHAPE], normalOutputs[RenderFetchCullSortTask::TRANSPARENT_SHAPE], fadeOutputs[TRANSPARENT_SHAPE]); +} + +void FadeSwitchJob::distribute(const render::RenderContextPointer& renderContext, const render::Varying& input, + render::Varying& normalOutput, render::Varying& fadeOutput) const { + auto& scene = renderContext->_scene; + assert(_parameters); + const double fadeDuration = double(_parameters->_durations[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]) * USECS_PER_SECOND; + const auto& inputItems = input.get(); + + // Clear previous values + normalOutput.template edit().clear(); + fadeOutput.template edit().clear(); + + for (const auto& itemBound : inputItems) { + auto& item = scene->getItem(itemBound.id); + + if (!item.mustFade()) { + // No need to fade + normalOutput.template edit().emplace_back(itemBound); + } + else { + fadeOutput.template edit().emplace_back(itemBound); + } + } +/* if (!_isEditEnabled) { + + }*/ +} + +FadeConfigureJob::FadeConfigureJob(FadeCommonParameters::Pointer commonParams) : + _parameters{ commonParams } { auto texturePath = PathUtils::resourcesPath() + "images/fadeMask.png"; _fadeMaskMap = DependencyManager::get()->getImageTexture(texturePath, image::TextureUsage::STRICT_TEXTURE); } -render::ShapeKey::Builder FadeEffect::getKeyBuilder(render::ShapeKey::Builder builder) const { - if (_isDebugEnabled) { - // Force fade for everyone - builder.withFade(); - } - return builder; +void FadeConfigureJob::configure(const Config& config) { + assert(_parameters); + for (auto i = 0; i < FadeJobConfig::EVENT_CATEGORY_COUNT; i++) { + auto& configuration = _configurations[i]; + + _parameters->_durations[i] = config.duration[i]; + configuration._baseInvSizeAndLevel.x = 1.f / config.baseSize[i].x; + configuration._baseInvSizeAndLevel.y = 1.f / config.baseSize[i].y; + configuration._baseInvSizeAndLevel.z = 1.f / config.baseSize[i].z; + configuration._baseInvSizeAndLevel.w = config.baseLevel[i]; + configuration._noiseInvSizeAndLevel.x = 1.f / config.noiseSize[i].x; + configuration._noiseInvSizeAndLevel.y = 1.f / config.noiseSize[i].y; + configuration._noiseInvSizeAndLevel.z = 1.f / config.noiseSize[i].z; + configuration._noiseInvSizeAndLevel.w = config.noiseLevel[i]; + configuration._invertBase = config.baseInverted[i]; + configuration._edgeWidthInvWidth.x = config.edgeWidth[i]; + configuration._edgeWidthInvWidth.y = 1.f / configuration._edgeWidthInvWidth.x; + configuration._innerEdgeColor.r = config.edgeInnerColor[i].r * config.edgeInnerColor[i].a; + configuration._innerEdgeColor.g = config.edgeInnerColor[i].g * config.edgeInnerColor[i].a; + configuration._innerEdgeColor.b = config.edgeInnerColor[i].b * config.edgeInnerColor[i].a; + configuration._outerEdgeColor.r = config.edgeOuterColor[i].r * config.edgeOuterColor[i].a; + configuration._outerEdgeColor.g = config.edgeOuterColor[i].g * config.edgeOuterColor[i].a; + configuration._outerEdgeColor.b = config.edgeOuterColor[i].b * config.edgeOuterColor[i].a; + } + _isBufferDirty = true; } -void FadeEffect::bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation) const { - batch.setResourceTexture(fadeMaskMapLocation, _fadeMaskMap); +void FadeConfigureJob::run(const render::RenderContextPointer& renderContext, Output& output) { + if (_isBufferDirty) { + auto& configurations = output.edit1().edit(); + std::copy(_configurations, _configurations + FadeJobConfig::EVENT_CATEGORY_COUNT, configurations.parameters); + _isBufferDirty = false; + } + output.edit0() = _fadeMaskMap; } -void FadeEffect::bindPerBatch(gpu::Batch& batch, const gpu::PipelinePointer& pipeline) const { - auto program = pipeline->getProgram(); - auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap"); - bindPerBatch(batch, maskMapLocation); -} +const FadeRenderJob* FadeRenderJob::_currentInstance{ nullptr }; +gpu::TexturePointer FadeRenderJob::_currentFadeMaskMap; +const gpu::BufferView* FadeRenderJob::_currentFadeBuffer{ nullptr }; -float FadeEffect::computeFadePercent(quint64 startTime) const { +float FadeRenderJob::computeFadePercent(quint64 startTime) { + assert(_currentInstance); float fadeAlpha = 1.0f; - const double INV_FADE_PERIOD = 1.0 / (double)(_duration * USECS_PER_SECOND); - double fraction = (double)(usecTimestampNow() - startTime) * INV_FADE_PERIOD; + const double INV_FADE_PERIOD = 1.0 / (double)(_currentInstance->_parameters->_durations[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN] * USECS_PER_SECOND); + double fraction = (double)(int64_t(usecTimestampNow()) - int64_t(startTime)) * INV_FADE_PERIOD; + fraction = std::max(fraction, 0.0); if (fraction < 1.0) { fadeAlpha = Interpolate::easeInOutQuad(fraction); } return fadeAlpha; } -bool FadeEffect::bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime, bool isFading) const { - return bindPerItem(batch, args->_pipeline->pipeline.get(), offset, startTime, isFading); +void FadeRenderJob::run(const render::RenderContextPointer& renderContext, const Input& inputs) { + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + const auto& inItems = inputs.get0(); + + if (!inItems.empty()) { + const auto& lightingModel = inputs.get1(); + const auto& configuration = inputs.get2(); + const auto& fadeMaskMap = configuration.get0(); + const auto& fadeParamBuffer = configuration.get1(); + + // Very, very ugly hack to keep track of the current fade render job + RenderArgs* args = renderContext->args; + render::ShapeKey::Builder defaultKeyBuilder; + + defaultKeyBuilder.withFade(); + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + _currentInstance = this; + _currentFadeMaskMap = fadeMaskMap; + _currentFadeBuffer = &fadeParamBuffer; + + // Setup camera, projection and viewport for all items + 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.setViewTransform(viewMat); + + // Setup lighting model for all items; + batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); + + // From the lighting model define a global shapKey ORED with individiual keys + render::ShapeKey::Builder keyBuilder = defaultKeyBuilder; + if (lightingModel->isWireframeEnabled()) { + keyBuilder.withWireframe(); + } + + // Prepare fade effect + bindPerBatch(batch, fadeMaskMap, render::ShapePipeline::Slot::MAP::FADE_MASK, &fadeParamBuffer, render::ShapePipeline::Slot::BUFFER::FADE_PARAMETERS); + + render::ShapeKey globalKey = keyBuilder.build(); + args->_globalShapeKey = globalKey._flags.to_ulong(); + args->_enableFade = true; + + renderShapes(renderContext, _shapePlumber, inItems, -1, globalKey); + + args->_enableFade = false; + args->_batch = nullptr; + args->_globalShapeKey = 0; + + // Very, very ugly hack to keep track of the current fade render job + _currentInstance = nullptr; + _currentFadeMaskMap.reset(); + _currentFadeBuffer = nullptr; + }); + } } -bool FadeEffect::bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime, bool isFading) const { - if (isFading || _isDebugEnabled) { - auto& uniforms = pipeline->getProgram()->getUniforms(); - auto fadeScaleLocation = uniforms.findLocation("fadeInvScale"); - auto fadeOffsetLocation = uniforms.findLocation("fadeOffset"); - auto fadePercentLocation = uniforms.findLocation("fadePercent"); +void FadeRenderJob::bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation) { + assert(_currentFadeMaskMap); + assert(_currentFadeBuffer!=nullptr); + bindPerBatch(batch, _currentFadeMaskMap, fadeMaskMapLocation, _currentFadeBuffer, fadeBufferLocation); +} - if (fadeScaleLocation >= 0 || fadeOffsetLocation >= 0 || fadePercentLocation>=0) { - float percent; +void FadeRenderJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation) { + batch.setResourceTexture(fadeMaskMapLocation, texture); + batch.setUniformBuffer(fadeBufferLocation, *buffer); +} - // A bit ugly to have the test at every bind... - if (!_isDebugEnabled) { - percent = computeFadePercent(startTime); - } - else { - percent = _debugFadePercent; - } - batch._glUniform1f(fadeScaleLocation, _invScale); - batch._glUniform1f(fadePercentLocation, percent); - batch._glUniform3f(fadeOffsetLocation, offset.x, offset.y, offset.z); +void FadeRenderJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline) { + auto program = pipeline->getProgram(); + auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap"); + auto bufferLocation = program->getUniformBuffers().findLocation("fadeParametersBuffer"); + bindPerBatch(batch, texture, maskMapLocation, buffer, bufferLocation); +} - return percent < 1.f; - } +bool FadeRenderJob::bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime) { + return bindPerItem(batch, args->_pipeline->pipeline.get(), offset, startTime); +} + +bool FadeRenderJob::bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime) { + auto& uniforms = pipeline->getProgram()->getUniforms(); + auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset"); + auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset"); + auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold"); + auto fadeCategoryLocation = uniforms.findLocation("fadeCategory"); + + if (fadeNoiseOffsetLocation >= 0 || fadeBaseOffsetLocation>=0 || fadeThresholdLocation >= 0 || fadeCategoryLocation>=0) { + float percent; + + percent = computeFadePercent(startTime); + batch._glUniform1i(fadeCategoryLocation, FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN); + batch._glUniform1f(fadeThresholdLocation, 1.f-percent); + // This is really temporary + batch._glUniform3f(fadeNoiseOffsetLocation, offset.x, offset.y, offset.z); + // This is really temporary + batch._glUniform3f(fadeBaseOffsetLocation, offset.x, offset.y, offset.z); + + return percent < 1.f; } return false; } diff --git a/libraries/render-utils/src/FadeEffect.h b/libraries/render-utils/src/FadeEffect.h index 80e3b79e2e..295dbb333a 100644 --- a/libraries/render-utils/src/FadeEffect.h +++ b/libraries/render-utils/src/FadeEffect.h @@ -11,47 +11,304 @@ #ifndef hifi_FadeEffect_h #define hifi_FadeEffect_h -#include #include #include +#include + +#include "LightingModel.h" + +class FadeSwitchJobConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(bool editFade MEMBER editFade NOTIFY dirty) -// Centralizes fade effect data and functions -class FadeEffect : public Dependency { - SINGLETON_DEPENDENCY public: - FadeEffect(); + bool editFade{ false }; - const gpu::TexturePointer getFadeMaskMap() const { return _fadeMaskMap; } +signals: + void dirty(); - void setScale(float value) { assert(value > 0.f); _invScale = 1.f / value; } - float getScale() const { return 1.f / _invScale; } +}; - void setDuration(float seconds) { assert(seconds > 0.f); _duration = seconds; } - float getDuration() const { return 1.f / _duration; } +class FadeJobConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(int editedCategory MEMBER editedCategory WRITE setEditedCategory NOTIFY dirty) + Q_PROPERTY(float duration READ getDuration WRITE setDuration NOTIFY dirty) + Q_PROPERTY(float baseSizeX READ getBaseSizeX WRITE setBaseSizeX NOTIFY dirty) + Q_PROPERTY(float baseSizeY READ getBaseSizeY WRITE setBaseSizeY NOTIFY dirty) + Q_PROPERTY(float baseSizeZ READ getBaseSizeZ WRITE setBaseSizeZ NOTIFY dirty) + Q_PROPERTY(float baseLevel READ getBaseLevel WRITE setBaseLevel NOTIFY dirty) + Q_PROPERTY(bool baseInverted READ isBaseInverted WRITE setBaseInverted NOTIFY dirty) + Q_PROPERTY(float noiseSizeX READ getNoiseSizeX WRITE setNoiseSizeX NOTIFY dirty) + Q_PROPERTY(float noiseSizeY READ getNoiseSizeY WRITE setNoiseSizeY NOTIFY dirty) + Q_PROPERTY(float noiseSizeZ READ getNoiseSizeZ WRITE setNoiseSizeZ NOTIFY dirty) + Q_PROPERTY(float noiseLevel READ getNoiseLevel WRITE setNoiseLevel NOTIFY dirty) + Q_PROPERTY(float edgeWidth READ getEdgeWidth WRITE setEdgeWidth NOTIFY dirty) + Q_PROPERTY(float edgeInnerColorR READ getEdgeInnerColorR WRITE setEdgeInnerColorR NOTIFY dirty) + Q_PROPERTY(float edgeInnerColorG READ getEdgeInnerColorG WRITE setEdgeInnerColorG NOTIFY dirty) + Q_PROPERTY(float edgeInnerColorB READ getEdgeInnerColorB WRITE setEdgeInnerColorB NOTIFY dirty) + Q_PROPERTY(float edgeInnerIntensity READ getEdgeInnerIntensity WRITE setEdgeInnerIntensity NOTIFY dirty) + Q_PROPERTY(float edgeOuterColorR READ getEdgeOuterColorR WRITE setEdgeOuterColorR NOTIFY dirty) + Q_PROPERTY(float edgeOuterColorG READ getEdgeOuterColorG WRITE setEdgeOuterColorG NOTIFY dirty) + Q_PROPERTY(float edgeOuterColorB READ getEdgeOuterColorB WRITE setEdgeOuterColorB NOTIFY dirty) + Q_PROPERTY(float edgeOuterIntensity READ getEdgeOuterIntensity WRITE setEdgeOuterIntensity NOTIFY dirty) - void setDebugEnabled(bool isEnabled) { _isDebugEnabled = isEnabled; } - bool isDebugEnabled() const { return _isDebugEnabled; } +public: - void setDebugFadePercent(float value) { assert(value >= 0.f && value <= 1.f); _debugFadePercent = value; } - float getDebugFadePercent() const { return _debugFadePercent; } + enum EventCategory { + ELEMENT_ENTER_LEAVE_DOMAIN = 0, + BUBBLE_ISECT_OWNER, + BUBBLE_ISECT_TRESPASSER, + USER_ENTER_LEAVE_DOMAIN, + AVATAR_CHANGE, - render::ShapeKey::Builder getKeyBuilder(render::ShapeKey::Builder builder = render::ShapeKey::Builder()) const; + // Don't forget to modify Fade.slh to reflect the change in number of categories + EVENT_CATEGORY_COUNT + }; - void bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation = render::ShapePipeline::Slot::MAP::FADE_MASK) const; - void bindPerBatch(gpu::Batch& batch, const gpu::PipelinePointer& pipeline) const; - bool bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime, bool isFading) const; - bool bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime, bool isFading) const; + void setEditedCategory(int value) { assert(value < EVENT_CATEGORY_COUNT); editedCategory = std::min(EVENT_CATEGORY_COUNT, value); } - float computeFadePercent(quint64 startTime) const; + void setDuration(float value) { duration[editedCategory] = value; } + float getDuration() const { return duration[editedCategory]; } + + void setBaseSizeX(float value) { baseSize[editedCategory].x = value; } + float getBaseSizeX() const { return baseSize[editedCategory].x; } + + void setBaseSizeY(float value) { baseSize[editedCategory].y = value; } + float getBaseSizeY() const { return baseSize[editedCategory].y; } + + void setBaseSizeZ(float value) { baseSize[editedCategory].z = value; } + float getBaseSizeZ() const { return baseSize[editedCategory].z; } + + void setBaseLevel(float value) { baseLevel[editedCategory] = value; } + float getBaseLevel() const { return baseLevel[editedCategory]; } + + void setBaseInverted(bool value) { baseInverted[editedCategory] = value; } + bool isBaseInverted() const { return baseInverted[editedCategory]; } + + void setNoiseSizeX(float value) { noiseSize[editedCategory].x = value; } + float getNoiseSizeX() const { return noiseSize[editedCategory].x; } + + void setNoiseSizeY(float value) { noiseSize[editedCategory].y = value; } + float getNoiseSizeY() const { return noiseSize[editedCategory].y; } + + void setNoiseSizeZ(float value) { noiseSize[editedCategory].z = value; } + float getNoiseSizeZ() const { return noiseSize[editedCategory].z; } + + void setNoiseLevel(float value) { noiseLevel[editedCategory] = value; } + float getNoiseLevel() const { return noiseLevel[editedCategory]; } + + void setEdgeWidth(float value) { edgeWidth[editedCategory] = value; } + float getEdgeWidth() const { return edgeWidth[editedCategory]; } + + void setEdgeInnerColorR(float value) { edgeInnerColor[editedCategory].r = value; } + float getEdgeInnerColorR() const { return edgeInnerColor[editedCategory].r; } + + void setEdgeInnerColorG(float value) { edgeInnerColor[editedCategory].g = value; } + float getEdgeInnerColorG() const { return edgeInnerColor[editedCategory].g; } + + void setEdgeInnerColorB(float value) { edgeInnerColor[editedCategory].b = value; } + float getEdgeInnerColorB() const { return edgeInnerColor[editedCategory].b; } + + void setEdgeInnerIntensity(float value) { edgeInnerColor[editedCategory].a = value; } + float getEdgeInnerIntensity() const { return edgeInnerColor[editedCategory].a; } + + void setEdgeOuterColorR(float value) { edgeOuterColor[editedCategory].r = value; } + float getEdgeOuterColorR() const { return edgeOuterColor[editedCategory].r; } + + void setEdgeOuterColorG(float value) { edgeOuterColor[editedCategory].g = value; } + float getEdgeOuterColorG() const { return edgeOuterColor[editedCategory].g; } + + void setEdgeOuterColorB(float value) { edgeOuterColor[editedCategory].b = value; } + float getEdgeOuterColorB() const { return edgeOuterColor[editedCategory].b; } + + void setEdgeOuterIntensity(float value) { edgeOuterColor[editedCategory].a = value; } + float getEdgeOuterIntensity() const { return edgeOuterColor[editedCategory].a; } + + int editedCategory{ ELEMENT_ENTER_LEAVE_DOMAIN }; + glm::vec3 baseSize[EVENT_CATEGORY_COUNT]{ + { 1.0f, 1.0f, 1.0f }, // ELEMENT_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_OWNER + { 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_TRESPASSER + { 1.0f, 1.0f, 1.0f }, // USER_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f }, // AVATAR_CHANGE + }; + float baseLevel[EVENT_CATEGORY_COUNT]{ + 1.0f, // ELEMENT_ENTER_LEAVE_DOMAIN + 1.0f, // BUBBLE_ISECT_OWNER + 1.0f, // BUBBLE_ISECT_TRESPASSER + 1.0f, // USER_ENTER_LEAVE_DOMAIN + 1.0f, // AVATAR_CHANGE + }; + bool baseInverted[EVENT_CATEGORY_COUNT]{ + false, // ELEMENT_ENTER_LEAVE_DOMAIN + false, // BUBBLE_ISECT_OWNER + false, // BUBBLE_ISECT_TRESPASSER + false, // USER_ENTER_LEAVE_DOMAIN + false, // AVATAR_CHANGE + }; + glm::vec3 noiseSize[EVENT_CATEGORY_COUNT]{ + { 1.0f, 1.0f, 1.0f }, // ELEMENT_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_OWNER + { 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_TRESPASSER + { 1.0f, 1.0f, 1.0f }, // USER_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f }, // AVATAR_CHANGE + }; + float noiseLevel[EVENT_CATEGORY_COUNT]{ + 1.0f, // ELEMENT_ENTER_LEAVE_DOMAIN + 1.0f, // BUBBLE_ISECT_OWNER + 1.0f, // BUBBLE_ISECT_TRESPASSER + 1.0f, // USER_ENTER_LEAVE_DOMAIN + 1.0f, // AVATAR_CHANGE + }; + float duration[EVENT_CATEGORY_COUNT]{ + 5.0f, // ELEMENT_ENTER_LEAVE_DOMAIN + 0.0f, // BUBBLE_ISECT_OWNER + 0.0f, // BUBBLE_ISECT_TRESPASSER + 3.0f, // USER_ENTER_LEAVE_DOMAIN + 3.0f, // AVATAR_CHANGE + }; + float edgeWidth[EVENT_CATEGORY_COUNT]{ + 0.1f, // ELEMENT_ENTER_LEAVE_DOMAIN + 0.1f, // BUBBLE_ISECT_OWNER + 0.1f, // BUBBLE_ISECT_TRESPASSER + 0.1f, // USER_ENTER_LEAVE_DOMAIN + 0.1f, // AVATAR_CHANGE + }; + glm::vec4 edgeInnerColor[EVENT_CATEGORY_COUNT]{ + { 1.0f, 1.0f, 1.0f, 1.0f }, // ELEMENT_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_OWNER + { 1.0f, 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_TRESPASSER + { 1.0f, 1.0f, 1.0f, 1.0f }, // USER_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f, 1.0f }, // AVATAR_CHANGE + }; + glm::vec4 edgeOuterColor[EVENT_CATEGORY_COUNT]{ + { 1.0f, 1.0f, 1.0f, 1.0f }, // ELEMENT_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_OWNER + { 1.0f, 1.0f, 1.0f, 1.0f }, // BUBBLE_ISECT_TRESPASSER + { 1.0f, 1.0f, 1.0f, 1.0f }, // USER_ENTER_LEAVE_DOMAIN + { 1.0f, 1.0f, 1.0f, 1.0f }, // AVATAR_CHANGE + }; + +signals: + void dirty(); + +}; + +struct FadeCommonParameters +{ + using Pointer = std::shared_ptr; + + float _durations[FadeJobConfig::EVENT_CATEGORY_COUNT]{ + 30.0f, // ELEMENT_ENTER_LEAVE_DOMAIN + 0.0f, // BUBBLE_ISECT_OWNER + 0.0f, // BUBBLE_ISECT_TRESPASSER + 3.0f, // USER_ENTER_LEAVE_DOMAIN + 3.0f, // AVATAR_CHANGE + }; +}; + +class FadeSwitchJob { +public: + + enum FadeBuckets { + OPAQUE_SHAPE = 0, + TRANSPARENT_SHAPE, + + NUM_BUCKETS + }; + + using FadeOutput = render::VaryingArray; + + using Input = RenderFetchCullSortTask::Output; + using Output = render::VaryingSet2; + using Config = FadeSwitchJobConfig; + using JobModel = render::Job::ModelIO; + + FadeSwitchJob(FadeCommonParameters::Pointer commonParams) : _parameters{ commonParams } {} + + void configure(const Config& config); + void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output); private: - gpu::TexturePointer _fadeMaskMap; - float _invScale; - float _duration; - float _debugFadePercent; - bool _isDebugEnabled; + FadeCommonParameters::Pointer _parameters; + bool _isEditEnabled{ false }; + + void distribute(const render::RenderContextPointer& renderContext, const render::Varying& input, + render::Varying& normalOutput, render::Varying& fadeOutput) const; +}; + +struct FadeParameters +{ + glm::vec4 _baseInvSizeAndLevel; + glm::vec4 _noiseInvSizeAndLevel; + glm::vec3 _innerEdgeColor; + glm::vec3 _outerEdgeColor; + glm::vec2 _edgeWidthInvWidth; + glm::int32 _invertBase; + glm::float32 _padding; +}; + +struct FadeConfiguration +{ + FadeParameters parameters[FadeJobConfig::EVENT_CATEGORY_COUNT]; +}; + +class FadeConfigureJob { + +public: + + using UniformBuffer = gpu::StructBuffer; + using Output = render::VaryingSet2; + using Config = FadeJobConfig; + using JobModel = render::Job::ModelO; + + FadeConfigureJob(FadeCommonParameters::Pointer commonParams); + + const gpu::TexturePointer getFadeMaskMap() const { return _fadeMaskMap; } + + void configure(const Config& config); + void run(const render::RenderContextPointer& renderContext, Output& output); + +private: + + FadeCommonParameters::Pointer _parameters; + bool _isBufferDirty{ true }; + gpu::TexturePointer _fadeMaskMap; + FadeParameters _configurations[FadeJobConfig::EVENT_CATEGORY_COUNT]; +}; + +class FadeRenderJob { + +public: + + using Input = render::VaryingSet3; + using JobModel = render::Job::ModelI; + + FadeRenderJob(FadeCommonParameters::Pointer commonParams, render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber }, _parameters{ commonParams } {} + + void run(const render::RenderContextPointer& renderContext, const Input& inputs); + + static void bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation); + static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation); + static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline); + + static bool bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime); + static bool bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime); + + static float computeFadePercent(quint64 startTime); + +private: + + static const FadeRenderJob* _currentInstance; + static gpu::TexturePointer _currentFadeMaskMap; + static const gpu::BufferView* _currentFadeBuffer; + + render::ShapePlumberPointer _shapePlumber; + FadeCommonParameters::Pointer _parameters; + + }; #endif // hifi_FadeEffect_h diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 9179354435..5c1632167e 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -523,12 +523,10 @@ render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool } render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading) { - isFading = isFading || DependencyManager::get()->isDebugEnabled(); return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline; } render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) { - isFading = isFading || DependencyManager::get()->isDebugEnabled(); return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline; } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 3e75666fcb..7db75a4df4 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -319,6 +319,11 @@ template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args) { return payload->render(args); } + +template <> bool payloadMustFade(const ModelMeshPartPayload::Pointer& payload) { + return payload->mustFade(); +} + } ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : @@ -525,6 +530,10 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline: batch.setModelTransform(_transform); } +bool ModelMeshPartPayload::mustFade() const { + return _fadeState != STATE_COMPLETE; +} + void ModelMeshPartPayload::render(RenderArgs* args) { PerformanceTimer perfTimer("ModelMeshPartPayload::render"); @@ -572,11 +581,16 @@ void ModelMeshPartPayload::render(RenderArgs* args) { // apply material properties bindMaterial(batch, locations, args->_enableTexturing); - // Apply fade effect - if (!DependencyManager::get()->bindPerItem(batch, args, _transform.getTranslation(), _fadeStartTime, _fadeState != STATE_COMPLETE)) { + if (args->_enableFade) { + // Apply fade effect + if (!FadeRenderJob::bindPerItem(batch, args, _transform.getTranslation(), _fadeStartTime)) { + _fadeState = STATE_COMPLETE; + } + } + /* else { // TODO : very ugly way to update the fade state. Need to improve this with global fade manager. _fadeState = STATE_COMPLETE; - } + }*/ args->_details._materialSwitches++; diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index b68a542bce..620976804f 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -97,6 +97,7 @@ public: int getLayer() const; render::ShapeKey getShapeKey() const override; // shape interface void render(RenderArgs* args) override; + bool mustFade() const; // ModelMeshPartPayload functions to perform render void bindMesh(gpu::Batch& batch) override; @@ -135,6 +136,7 @@ namespace render { template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload); template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload); template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args); + template <> bool payloadMustFade(const ModelMeshPartPayload::Pointer& payload); } #endif // hifi_MeshPartPayload_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index c9a67fea3f..a8ead6e76e 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -50,20 +50,15 @@ extern void initDeferredPipelines(render::ShapePlumber& plumber); void RenderDeferredTask::configure(const Config& config) { - const float SCALE_MIN = 0.01f; - const float SCALE_MAX = 5.f; - - auto fadeEffect = DependencyManager::get(); - float scale = SCALE_MIN + (SCALE_MAX - SCALE_MIN)*config.fadeScale*config.fadeScale*config.fadeScale; - - fadeEffect->setScale(scale); - fadeEffect->setDuration(config.fadeDuration); - fadeEffect->setDebugEnabled(config.debugFade); - fadeEffect->setDebugFadePercent(config.debugFadePercent); } void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { - auto items = input.get(); + auto commonFadeParameters = std::make_shared(); + const auto fadeSwitchOutputs = task.addJob("FadeSwitch", input, commonFadeParameters).get(); + const auto fadeConfigureOutputs = task.addJob("FadeConfigure", commonFadeParameters).get(); + + const auto& items = fadeSwitchOutputs.get0(); + const auto& fadeItems = fadeSwitchOutputs.get1(); // Prepare the ShapePipelines ShapePlumberPointer shapePlumber = std::make_shared(); @@ -97,8 +92,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); - DependencyManager::set(); - // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", primaryFramebuffer); @@ -106,6 +99,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); + const auto fadeOpaques = fadeItems[FadeSwitchJob::OPAQUE_SHAPE]; + const auto fadeOpaqueInputs = FadeRenderJob::Input(fadeOpaques, lightingModel, fadeConfigureOutputs).hasVarying(); + task.addJob("DrawFadeOpaque", fadeOpaqueInputs, commonFadeParameters, shapePlumber); + task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -159,6 +156,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying(); task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); + const auto fadeTransparents = fadeItems[FadeSwitchJob::TRANSPARENT_SHAPE]; + const auto fadeTransparentInputs = FadeRenderJob::Input(fadeTransparents, lightingModel, fadeConfigureOutputs).hasVarying(); + task.addJob("DrawFadeTransparent", fadeTransparentInputs, commonFadeParameters, shapePlumber); + // LIght Cluster Grid Debuging job { const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).hasVarying(); @@ -262,7 +263,6 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& const auto& lightingModel = inputs.get1(); RenderArgs* args = renderContext->args; - ShapeKey::Builder defaultKeyBuilder = DependencyManager::get()->getKeyBuilder(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -283,14 +283,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); // From the lighting model define a global shapKey ORED with individiual keys - ShapeKey::Builder keyBuilder = defaultKeyBuilder; + ShapeKey::Builder keyBuilder; if (lightingModel->isWireframeEnabled()) { keyBuilder.withWireframe(); } - // Prepare fade effect - DependencyManager::get()->bindPerBatch(batch); - ShapeKey globalKey = keyBuilder.build(); args->_globalShapeKey = globalKey._flags.to_ulong(); @@ -313,7 +310,6 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const const auto& lightingModel = inputs.get1(); RenderArgs* args = renderContext->args; - ShapeKey::Builder defaultKeyBuilder = DependencyManager::get()->getKeyBuilder(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -334,14 +330,11 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); // From the lighting model define a global shapeKey ORED with individiual keys - ShapeKey::Builder keyBuilder = defaultKeyBuilder; + ShapeKey::Builder keyBuilder; if (lightingModel->isWireframeEnabled()) { keyBuilder.withWireframe(); } - // Prepare fade effect - DependencyManager::get()->bindPerBatch(batch); - ShapeKey globalKey = keyBuilder.build(); args->_globalShapeKey = globalKey._flags.to_ulong(); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index a74a814630..c0d7f43516 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -53,7 +53,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, const auto& fbo = shadow->framebuffer; RenderArgs* args = renderContext->args; - ShapeKey::Builder defaultKeyBuilder = DependencyManager::get()->getKeyBuilder(); + ShapeKey::Builder defaultKeyBuilder;// TODO: support fade on shadows = DependencyManager::get()->getKeyBuilder(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -75,7 +75,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned()); // Prepare fade effect - DependencyManager::get()->bindPerBatch(batch); + // TODO: support fade on shadows DependencyManager::get()->bindPerBatch(batch); std::vector skinnedShapeKeys{}; diff --git a/libraries/render-utils/src/model_fade.slf b/libraries/render-utils/src/model_fade.slf index 1526dea7c2..7d145bc76b 100644 --- a/libraries/render-utils/src/model_fade.slf +++ b/libraries/render-utils/src/model_fade.slf @@ -30,7 +30,9 @@ in vec2 _texCoord1; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -50,6 +52,7 @@ void main(void) { vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; + emissive += fadeEmissive; float scattering = getMaterialScattering(mat); diff --git a/libraries/render-utils/src/model_lightmap_fade.slf b/libraries/render-utils/src/model_lightmap_fade.slf index f2055e7ffc..ccad86214a 100644 --- a/libraries/render-utils/src/model_lightmap_fade.slf +++ b/libraries/render-utils/src/model_lightmap_fade.slf @@ -31,7 +31,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -46,5 +48,5 @@ void main(void) { getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), getMaterialFresnel(mat), - lightmapVal); + lightmapVal+fadeEmissive); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf index 137e40dd3c..a1dbd398ee 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf @@ -32,7 +32,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -49,5 +51,5 @@ void main(void) { getMaterialRoughness(mat), getMaterialMetallic(mat), getMaterialFresnel(mat), - lightmapVal); + lightmapVal+fadeEmissive); } diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf index b6cdfbd2a2..d7a8697b7a 100644 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map_fade.slf @@ -32,7 +32,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -49,5 +51,5 @@ void main(void) { getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat) * metallicTex, /*specular, // no use of */ getMaterialFresnel(mat), - lightmapVal); + lightmapVal+fadeEmissive); } diff --git a/libraries/render-utils/src/model_lightmap_specular_map_fade.slf b/libraries/render-utils/src/model_lightmap_specular_map_fade.slf index e6d82b778d..c4280ed6d1 100644 --- a/libraries/render-utils/src/model_lightmap_specular_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map_fade.slf @@ -31,7 +31,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -45,5 +47,5 @@ void main(void) { getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat) * metallicTex, /*metallicTex, // no use of */getMaterialFresnel(mat), - lightmapVal); + lightmapVal+fadeEmissive); } diff --git a/libraries/render-utils/src/model_normal_map_fade.slf b/libraries/render-utils/src/model_normal_map_fade.slf index 61314fc834..7c70dabda2 100644 --- a/libraries/render-utils/src/model_normal_map_fade.slf +++ b/libraries/render-utils/src/model_normal_map_fade.slf @@ -31,7 +31,9 @@ in vec3 _tangent; in vec3 _color; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); diff --git a/libraries/render-utils/src/model_normal_specular_map_fade.slf b/libraries/render-utils/src/model_normal_specular_map_fade.slf index d9c4288e29..bdf917efea 100644 --- a/libraries/render-utils/src/model_normal_specular_map_fade.slf +++ b/libraries/render-utils/src/model_normal_specular_map_fade.slf @@ -31,7 +31,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -66,7 +68,7 @@ void main(void) { albedo, roughness, metallic, - emissive, + emissive+fadeEmissive, occlusionTex, scattering); } diff --git a/libraries/render-utils/src/model_shadow_fade.slf b/libraries/render-utils/src/model_shadow_fade.slf index 635917b9f4..76720d6053 100644 --- a/libraries/render-utils/src/model_shadow_fade.slf +++ b/libraries/render-utils/src/model_shadow_fade.slf @@ -20,7 +20,7 @@ layout(location = 0) out vec4 _fragColor; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + applyFadeClip(_worldFadePosition.xyz); // pass-through to set z-buffer _fragColor = vec4(1.0, 1.0, 1.0, 0.0); diff --git a/libraries/render-utils/src/model_specular_map_fade.slf b/libraries/render-utils/src/model_specular_map_fade.slf index 3579cf1059..75db1d72a2 100644 --- a/libraries/render-utils/src/model_specular_map_fade.slf +++ b/libraries/render-utils/src/model_specular_map_fade.slf @@ -30,7 +30,9 @@ in vec3 _color; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -62,7 +64,7 @@ void main(void) { albedo, roughness, metallic, - emissive, + emissive+fadeEmissive, occlusionTex, scattering); } diff --git a/libraries/render-utils/src/model_translucent_fade.slf b/libraries/render-utils/src/model_translucent_fade.slf index 3bbfdabc7f..9802e863b0 100644 --- a/libraries/render-utils/src/model_translucent_fade.slf +++ b/libraries/render-utils/src/model_translucent_fade.slf @@ -38,7 +38,9 @@ in vec4 _worldFadePosition; out vec4 _fragColor; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -81,7 +83,7 @@ void main(void) { albedo, fresnel, metallic, - emissive, + emissive+fadeEmissive, roughness, opacity), opacity); } diff --git a/libraries/render-utils/src/model_translucent_unlit_fade.slf b/libraries/render-utils/src/model_translucent_unlit_fade.slf index dd885f66d7..6c6846228e 100644 --- a/libraries/render-utils/src/model_translucent_unlit_fade.slf +++ b/libraries/render-utils/src/model_translucent_unlit_fade.slf @@ -29,7 +29,9 @@ in vec4 _worldFadePosition; out vec4 _fragColor; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -41,6 +43,6 @@ void main(void) { vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; - + albedo += fadeEmissive; _fragColor = vec4(albedo * isUnlitEnabled(), opacity); } diff --git a/libraries/render-utils/src/model_unlit_fade.slf b/libraries/render-utils/src/model_unlit_fade.slf index be0af7afea..59fdc87bee 100644 --- a/libraries/render-utils/src/model_unlit_fade.slf +++ b/libraries/render-utils/src/model_unlit_fade.slf @@ -29,7 +29,9 @@ in float _alpha; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material mat = getMaterial(); int matKey = getMaterialKey(mat); @@ -42,7 +44,7 @@ void main(void) { vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; - + albedo += fadeEmissive; packDeferredFragmentUnlit( normalize(_normal), opacity, diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index c082ea26f3..526b7157d9 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -33,7 +33,9 @@ in vec4 _worldFadePosition; #line 2030 void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); Material material = getMaterial(); vec3 normal = normalize(_normal.xyz); @@ -61,14 +63,14 @@ void main(void) { packDeferredFragmentTranslucent( normal, _color.a, - specular, + specular+fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { packDeferredFragmentTranslucent( normal, _color.a, - diffuse, + diffuse+fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } @@ -77,7 +79,7 @@ void main(void) { packDeferredFragmentLightmap( normal, 1.0, - diffuse, + diffuse+fadeEmissive, max(0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, @@ -89,7 +91,7 @@ void main(void) { diffuse, max(0, 1.0 - shininess / 128.0), length(specular), - DEFAULT_EMISSIVE, + DEFAULT_EMISSIVE+fadeEmissive, DEFAULT_OCCLUSION, DEFAULT_SCATTERING); } diff --git a/libraries/render-utils/src/simple_textured_fade.slf b/libraries/render-utils/src/simple_textured_fade.slf index c939a8d676..5130720277 100644 --- a/libraries/render-utils/src/simple_textured_fade.slf +++ b/libraries/render-utils/src/simple_textured_fade.slf @@ -29,7 +29,9 @@ in vec2 _texCoord0; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); vec4 texel = texture(originalTexture, _texCoord0); float colorAlpha = _color.a; @@ -43,7 +45,7 @@ void main(void) { packDeferredFragmentTranslucent( normalize(_normal), colorAlpha * texel.a, - _color.rgb * texel.rgb, + _color.rgb * texel.rgb + fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { @@ -53,7 +55,7 @@ void main(void) { _color.rgb * texel.rgb, DEFAULT_ROUGHNESS, DEFAULT_METALLIC, - DEFAULT_EMISSIVE, + DEFAULT_EMISSIVE + fadeEmissive, DEFAULT_OCCLUSION, DEFAULT_SCATTERING); } diff --git a/libraries/render-utils/src/simple_textured_unlit_fade.slf b/libraries/render-utils/src/simple_textured_unlit_fade.slf index 2db2dfa222..60b6921ae3 100644 --- a/libraries/render-utils/src/simple_textured_unlit_fade.slf +++ b/libraries/render-utils/src/simple_textured_unlit_fade.slf @@ -28,7 +28,9 @@ in vec2 _texCoord0; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); vec4 texel = texture(originalTexture, _texCoord0.st); float colorAlpha = _color.a; @@ -42,13 +44,13 @@ void main(void) { packDeferredFragmentTranslucent( normalize(_normal), colorAlpha * texel.a, - _color.rgb * texel.rgb, + _color.rgb * texel.rgb+fadeEmissive, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } else { packDeferredFragmentUnlit( normalize(_normal), 1.0, - _color.rgb * texel.rgb); + _color.rgb * texel.rgb+fadeEmissive); } } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_fade.slf b/libraries/render-utils/src/simple_transparent_textured_fade.slf index 84cdffeeec..8aa7bf176b 100644 --- a/libraries/render-utils/src/simple_transparent_textured_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_fade.slf @@ -35,7 +35,9 @@ in vec2 _texCoord0; in vec4 _worldFadePosition; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); vec4 texel = texture(originalTexture, _texCoord0.st); float opacity = _color.a; @@ -59,8 +61,8 @@ void main(void) { fragNormal, albedo, DEFAULT_FRESNEL, - 0.0, - vec3(0.0f), + 0.0f, + fadeEmissive, DEFAULT_ROUGHNESS, opacity), opacity); diff --git a/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf b/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf index 688e1de422..9f74eacc96 100644 --- a/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_unlit_fade.slf @@ -29,7 +29,9 @@ in vec4 _worldFadePosition; layout(location = 0) out vec4 _fragColor0; void main(void) { - applyFade(_worldFadePosition.xyz); + vec3 fadeEmissive; + + applyFade(_worldFadePosition.xyz, fadeEmissive); vec4 texel = texture(originalTexture, _texCoord0.st); float colorAlpha = _color.a; @@ -37,5 +39,5 @@ void main(void) { texel = colorToLinearRGBA(texel); colorAlpha = -_color.a; } - _fragColor0 = vec4(_color.rgb * texel.rgb, colorAlpha * texel.a); + _fragColor0 = vec4(_color.rgb * texel.rgb+fadeEmissive, colorAlpha * texel.a); } \ No newline at end of file diff --git a/libraries/render-utils/src/skin_model_shadow_fade.slf b/libraries/render-utils/src/skin_model_shadow_fade.slf index 7b164f5db1..666525a3ae 100644 --- a/libraries/render-utils/src/skin_model_shadow_fade.slf +++ b/libraries/render-utils/src/skin_model_shadow_fade.slf @@ -20,7 +20,7 @@ in vec4 _worldFadePosition; layout(location = 0) out vec4 _fragColor; void main(void) { - applyFade(_worldFadePosition.xyz); + applyFadeClip(_worldFadePosition.xyz); // pass-through to set z-buffer _fragColor = vec4(1.0, 1.0, 1.0, 0.0); diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a75488ce7a..6f0bb226ca 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -115,6 +115,7 @@ namespace render { uint32_t _globalShapeKey { 0 }; bool _enableTexturing { true }; + bool _enableFade{ false }; RenderDetails _details; render::ScenePointer _scene; diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 007b34395d..4690f0de74 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -316,7 +316,7 @@ public: virtual const ItemKey getKey() const = 0; virtual const Bound getBound() const = 0; virtual int getLayer() const = 0; - + virtual bool mustFade() const = 0; virtual void render(RenderArgs* args) = 0; virtual const ShapeKey getShapeKey() const = 0; @@ -364,6 +364,8 @@ public: // Get the layer where the item belongs. 0 by default meaning NOT LAYERED int getLayer() const { return _payload->getLayer(); } + bool mustFade() const { return _payload->mustFade(); } + // Render call for the item void render(RenderArgs* args) const { _payload->render(args); } @@ -409,6 +411,7 @@ template const ItemKey payloadGetKey(const std::shared_ptr& payload template const Item::Bound payloadGetBound(const std::shared_ptr& payloadData) { return Item::Bound(); } template int payloadGetLayer(const std::shared_ptr& payloadData) { return 0; } template void payloadRender(const std::shared_ptr& payloadData, RenderArgs* args) { } +template bool payloadMustFade(const std::shared_ptr& payloadData) { return false; } // Shape type interface // This allows shapes to characterize their pipeline via a ShapeKey, to be picked with a subclass of Shape. @@ -435,7 +438,7 @@ public: virtual const ItemKey getKey() const override { return payloadGetKey(_data); } virtual const Item::Bound getBound() const override { return payloadGetBound(_data); } virtual int getLayer() const override { return payloadGetLayer(_data); } - + virtual bool mustFade() const override { return payloadMustFade(_data); } virtual void render(RenderArgs* args) override { payloadRender(_data, args); } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index d735afa52d..6e5d723ce6 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -65,6 +65,5 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin const auto overlayTransparents = task.addJob("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false)); const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET]; - output = Varying(Output{{ - opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background, spatialSelection }}); + output = Output{opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background, spatialSelection}; } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.h b/libraries/render/src/render/RenderFetchCullSortTask.h index f32293f001..f3f326aae8 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.h +++ b/libraries/render/src/render/RenderFetchCullSortTask.h @@ -31,7 +31,7 @@ public: NUM_BUCKETS }; - using Output = std::array; + using Output = render::VaryingArray; using JobModel = render::Task::ModelO; RenderFetchCullSortTask() {} diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 6a52f90297..57cfa6342e 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -70,6 +70,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT)); slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK)); + slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS)); gpu::Shader::makeProgram(*program, slotBindings); @@ -89,7 +90,8 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p locations->lightAmbientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer"); locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap"); locations->fadeMaskTextureUnit = program->getTextures().findLocation("fadeMaskMap"); - + locations->fadeParameterBufferUnit = program->getUniformBuffers().findLocation("fadeParametersBuffer"); + ShapeKey key{filter._flags}; auto gpuPipeline = gpu::Pipeline::create(program, state); auto shapePipeline = std::make_shared(gpuPipeline, locations, batchSetter); diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h index 06ca1ba15c..5d747a924d 100644 --- a/libraries/render/src/render/ShapePipeline.h +++ b/libraries/render/src/render/ShapePipeline.h @@ -215,6 +215,7 @@ public: LIGHTING_MODEL, LIGHT, LIGHT_AMBIENT_BUFFER, + FADE_PARAMETERS, }; enum MAP { @@ -246,6 +247,7 @@ public: int lightAmbientBufferUnit; int lightAmbientMapUnit; int fadeMaskTextureUnit; + int fadeParameterBufferUnit; }; using LocationsPointer = std::shared_ptr; diff --git a/libraries/render/src/task/Varying.h b/libraries/render/src/task/Varying.h index 50f4acd414..d5021383fb 100644 --- a/libraries/render/src/task/Varying.h +++ b/libraries/render/src/task/Varying.h @@ -281,6 +281,11 @@ public: (*this)[i] = Varying(T()); } } + + VaryingArray(std::initializer_list list) { + assert(list.size() == NUM); + std::copy(list.begin(), list.end(), begin()); + } }; } diff --git a/scripts/developer/utilities/render/debugFade.js b/scripts/developer/utilities/render/debugFade.js index 064337dae1..80c2deff73 100644 --- a/scripts/developer/utilities/render/debugFade.js +++ b/scripts/developer/utilities/render/debugFade.js @@ -15,7 +15,7 @@ var window = new OverlayWindow({ title: 'Fade', source: qml, width: 500, - height: 80 + height: 900 }); window.setPosition(50, 50); window.closed.connect(function() { Script.stop(); }); \ No newline at end of file diff --git a/scripts/developer/utilities/render/fade.qml b/scripts/developer/utilities/render/fade.qml index 0a99ca2e7e..ba7ed59398 100644 --- a/scripts/developer/utilities/render/fade.qml +++ b/scripts/developer/utilities/render/fade.qml @@ -12,47 +12,228 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import "configSlider" -Row { - property var taskConfig: Render.getConfig("RenderDeferredTask"); - spacing: 4 - Column { +Column { + property var config: Render.getConfig("RenderDeferredTask"); + spacing: 8 + Row { spacing: 8 CheckBox { - text: "Manual Fade" - checked: taskConfig["debugFade"] - onCheckedChanged: { taskConfig["debugFade"] = checked } + text: "Edit Fade" + checked: config["editFade"] + onCheckedChanged: { config["editFade"] = checked } + } + ComboBox { + width: 400 + model: ["Elements enter/leave domain", "Bubble isect. - Owner POV", "Bubble isect. - Trespasser POV", "Another user leaves/arrives", "Changing an avatar"] + onCurrentIndexChanged: { config["editedCategory"] = currentIndex } } } Column { spacing: 8 - ConfigSlider { - label: "Percent" - integral: false - config: taskConfig - property: "debugFadePercent" - max: 1.0 - min: 0.0 - width: 250 - } - ConfigSlider { - label: "Scale" - integral: false - config: taskConfig - property: "fadeScale" - max: 1.0 - min: 0.0 - width: 250 - } ConfigSlider { label: "Duration" integral: false - config: taskConfig - property: "fadeDuration" + config: config + property: "duration" max: 10.0 min: 0.1 - width: 250 + width: 400 + } + GroupBox { + title: "Base Gradient" + width: 500 + Column { + spacing: 8 + + ConfigSlider { + label: "Size X" + integral: false + config: config + property: "baseSizeX" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Size Y" + integral: false + config: config + property: "baseSizeY" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Size Z" + integral: false + config: config + property: "baseSizeZ" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Level" + integral: false + config: config + property: "baseLevel" + max: 1.0 + min: 0.0 + width: 400 + } + CheckBox { + text: "Invert" + checked: config["baseInverted"] + onCheckedChanged: { config["baseInverted"] = checked } + } + } + } + GroupBox { + title: "Noise Gradient" + width: 500 + Column { + spacing: 8 + + ConfigSlider { + label: "Size X" + integral: false + config: config + property: "noiseSizeX" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Size Y" + integral: false + config: config + property: "noiseSizeY" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Size Z" + integral: false + config: config + property: "noiseSizeZ" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Level" + integral: false + config: config + property: "noiseLevel" + max: 1.0 + min: 0.0 + width: 400 + } + } + } + GroupBox { + title: "Edge" + width: 500 + Column { + spacing: 8 + + ConfigSlider { + label: "Width" + integral: false + config: config + property: "edgeWidth" + max: 1.0 + min: 0.0 + width: 400 + } + GroupBox { + title: "Inner color" + Column { + spacing: 8 + ConfigSlider { + label: "Color R" + integral: false + config: config + property: "edgeInnerColorR" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color G" + integral: false + config: config + property: "edgeInnerColorG" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color B" + integral: false + config: config + property: "edgeInnerColorB" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color intensity" + integral: false + config: config + property: "edgeInnerIntensity" + max: 5.0 + min: 0.0 + width: 400 + } + } + } + GroupBox { + title: "Outer color" + Column { + spacing: 8 + ConfigSlider { + label: "Color R" + integral: false + config: config + property: "edgeOuterColorR" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color G" + integral: false + config: config + property: "edgeOuterColorG" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color B" + integral: false + config: config + property: "edgeOuterColorB" + max: 1.0 + min: 0.0 + width: 400 + } + ConfigSlider { + label: "Color intensity" + integral: false + config: config + property: "edgeOuterIntensity" + max: 5.0 + min: 0.0 + width: 400 + } + } + } + } } } }