mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 09:44:21 +02:00
Fade effect working again for basic enter domain but with various Fade jobs
This commit is contained in:
parent
b76a8a6f9b
commit
8a12d0c106
40 changed files with 900 additions and 187 deletions
|
@ -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<gpu::State>();
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
|
@ -823,9 +824,9 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
// Apply fade effect
|
||||
auto fadeEffect = DependencyManager::get<FadeEffect>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||
int x, int y, int z);
|
||||
|
||||
|
||||
#endif // hifi_RenderablePolyVoxEntityItem_h
|
||||
|
|
|
@ -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<GeometryCache>();
|
||||
auto fadeEffect = DependencyManager::get<FadeEffect>();
|
||||
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
|
||||
assert(pipeline != nullptr);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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@>
|
|
@ -4,73 +4,223 @@
|
|||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <Interpolate.h>
|
||||
#include <render/ShapePipeline.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
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<render::ItemBounds>();
|
||||
|
||||
// Clear previous values
|
||||
normalOutput.template edit<render::ItemBounds>().clear();
|
||||
fadeOutput.template edit<render::ItemBounds>().clear();
|
||||
|
||||
for (const auto& itemBound : inputItems) {
|
||||
auto& item = scene->getItem(itemBound.id);
|
||||
|
||||
if (!item.mustFade()) {
|
||||
// No need to fade
|
||||
normalOutput.template edit<render::ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
else {
|
||||
fadeOutput.template edit<render::ItemBounds>().emplace_back(itemBound);
|
||||
}
|
||||
}
|
||||
/* if (!_isEditEnabled) {
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
FadeConfigureJob::FadeConfigureJob(FadeCommonParameters::Pointer commonParams) :
|
||||
_parameters{ commonParams }
|
||||
{
|
||||
auto texturePath = PathUtils::resourcesPath() + "images/fadeMask.png";
|
||||
_fadeMaskMap = DependencyManager::get<TextureCache>()->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;
|
||||
}
|
||||
|
|
|
@ -11,47 +11,304 @@
|
|||
#ifndef hifi_FadeEffect_h
|
||||
#define hifi_FadeEffect_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <render/ShapePipeline.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
|
||||
#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<int>(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<FadeCommonParameters>;
|
||||
|
||||
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<render::ItemBounds, FadeBuckets::NUM_BUCKETS>;
|
||||
|
||||
using Input = RenderFetchCullSortTask::Output;
|
||||
using Output = render::VaryingSet2<RenderFetchCullSortTask::Output, FadeOutput>;
|
||||
using Config = FadeSwitchJobConfig;
|
||||
using JobModel = render::Job::ModelIO<FadeSwitchJob, Input, Output, Config>;
|
||||
|
||||
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<FadeConfiguration>;
|
||||
using Output = render::VaryingSet2<gpu::TexturePointer, UniformBuffer>;
|
||||
using Config = FadeJobConfig;
|
||||
using JobModel = render::Job::ModelO<FadeConfigureJob, Output, Config>;
|
||||
|
||||
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<render::ItemBounds, LightingModelPointer, FadeConfigureJob::Output>;
|
||||
using JobModel = render::Job::ModelI<FadeRenderJob, Input>;
|
||||
|
||||
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
|
||||
|
|
|
@ -523,12 +523,10 @@ render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool
|
|||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading) {
|
||||
isFading = isFading || DependencyManager::get<FadeEffect>()->isDebugEnabled();
|
||||
return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline;
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) {
|
||||
isFading = isFading || DependencyManager::get<FadeEffect>()->isDebugEnabled();
|
||||
return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<FadeEffect>()->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++;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<FadeEffect>();
|
||||
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<Input>();
|
||||
auto commonFadeParameters = std::make_shared<FadeCommonParameters>();
|
||||
const auto fadeSwitchOutputs = task.addJob<FadeSwitchJob>("FadeSwitch", input, commonFadeParameters).get<FadeSwitchJob::Output>();
|
||||
const auto fadeConfigureOutputs = task.addJob<FadeConfigureJob>("FadeConfigure", commonFadeParameters).get<FadeConfigureJob::Output>();
|
||||
|
||||
const auto& items = fadeSwitchOutputs.get0();
|
||||
const auto& fadeItems = fadeSwitchOutputs.get1();
|
||||
|
||||
// Prepare the ShapePipelines
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||
|
@ -97,8 +92,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto deferredFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(0);
|
||||
const auto lightingFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(1);
|
||||
|
||||
DependencyManager::set<FadeEffect>();
|
||||
|
||||
// draw a stencil mask in hidden regions of the framebuffer.
|
||||
task.addJob<PrepareStencil>("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<DrawStateSortDeferred>("DrawOpaqueDeferred", opaqueInputs, shapePlumber);
|
||||
|
||||
const auto fadeOpaques = fadeItems[FadeSwitchJob::OPAQUE_SHAPE];
|
||||
const auto fadeOpaqueInputs = FadeRenderJob::Input(fadeOpaques, lightingModel, fadeConfigureOutputs).hasVarying();
|
||||
task.addJob<FadeRenderJob>("DrawFadeOpaque", fadeOpaqueInputs, commonFadeParameters, shapePlumber);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("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<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber);
|
||||
|
||||
const auto fadeTransparents = fadeItems[FadeSwitchJob::TRANSPARENT_SHAPE];
|
||||
const auto fadeTransparentInputs = FadeRenderJob::Input(fadeTransparents, lightingModel, fadeConfigureOutputs).hasVarying();
|
||||
task.addJob<FadeRenderJob>("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<FadeEffect>()->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<FadeEffect>()->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<FadeEffect>()->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<FadeEffect>()->bindPerBatch(batch);
|
||||
|
||||
ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
|
||||
|
|
|
@ -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<FadeEffect>()->getKeyBuilder();
|
||||
ShapeKey::Builder defaultKeyBuilder;// TODO: support fade on shadows = DependencyManager::get<FadeEffect>()->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<FadeEffect>()->bindPerBatch(batch);
|
||||
// TODO: support fade on shadows DependencyManager::get<FadeEffect>()->bindPerBatch(batch);
|
||||
|
||||
std::vector<ShapeKey> skinnedShapeKeys{};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -115,6 +115,7 @@ namespace render {
|
|||
|
||||
uint32_t _globalShapeKey { 0 };
|
||||
bool _enableTexturing { true };
|
||||
bool _enableFade{ false };
|
||||
|
||||
RenderDetails _details;
|
||||
render::ScenePointer _scene;
|
||||
|
|
|
@ -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 <class T> const ItemKey payloadGetKey(const std::shared_ptr<T>& payload
|
|||
template <class T> const Item::Bound payloadGetBound(const std::shared_ptr<T>& payloadData) { return Item::Bound(); }
|
||||
template <class T> int payloadGetLayer(const std::shared_ptr<T>& payloadData) { return 0; }
|
||||
template <class T> void payloadRender(const std::shared_ptr<T>& payloadData, RenderArgs* args) { }
|
||||
template <class T> bool payloadMustFade(const std::shared_ptr<T>& 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<T>(_data); }
|
||||
virtual const Item::Bound getBound() const override { return payloadGetBound<T>(_data); }
|
||||
virtual int getLayer() const override { return payloadGetLayer<T>(_data); }
|
||||
|
||||
virtual bool mustFade() const override { return payloadMustFade<T>(_data); }
|
||||
|
||||
virtual void render(RenderArgs* args) override { payloadRender<T>(_data, args); }
|
||||
|
||||
|
|
|
@ -65,6 +65,5 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin
|
|||
const auto overlayTransparents = task.addJob<DepthSortItems>("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};
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
NUM_BUCKETS
|
||||
};
|
||||
|
||||
using Output = std::array<render::Varying, Buckets::NUM_BUCKETS>;
|
||||
using Output = render::VaryingArray<render::ItemBounds, Buckets::NUM_BUCKETS>;
|
||||
using JobModel = render::Task::ModelO<RenderFetchCullSortTask, Output>;
|
||||
|
||||
RenderFetchCullSortTask() {}
|
||||
|
|
|
@ -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<Pipeline>(gpuPipeline, locations, batchSetter);
|
||||
|
|
|
@ -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<Locations>;
|
||||
|
||||
|
|
|
@ -281,6 +281,11 @@ public:
|
|||
(*this)[i] = Varying(T());
|
||||
}
|
||||
}
|
||||
|
||||
VaryingArray(std::initializer_list<Varying> list) {
|
||||
assert(list.size() == NUM);
|
||||
std::copy(list.begin(), list.end(), begin());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); });
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue