fix fading and highlighting issues

This commit is contained in:
SamGondelman 2018-10-22 14:10:50 -07:00
parent 5652fa0b1e
commit 09ea32dcc0
10 changed files with 127 additions and 109 deletions

View file

@ -188,7 +188,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
{ {
// lock the hash for read to check the size // lock the hash for read to check the size
QReadLocker lock(&_hashLock); QReadLocker lock(&_hashLock);
if (_avatarHash.size() < 2 && _avatarsToFade.isEmpty()) { if (_avatarHash.size() < 2 && _avatarsToFadeOut.isEmpty()) {
return; return;
} }
} }
@ -346,23 +346,23 @@ void AvatarManager::sendIdentityRequest(const QUuid& avatarID) const {
} }
void AvatarManager::simulateAvatarFades(float deltaTime) { void AvatarManager::simulateAvatarFades(float deltaTime) {
if (_avatarsToFade.empty()) { if (_avatarsToFadeOut.empty()) {
return; return;
} }
QReadLocker locker(&_hashLock); QReadLocker locker(&_hashLock);
QVector<AvatarSharedPointer>::iterator avatarItr = _avatarsToFade.begin(); QVector<AvatarSharedPointer>::iterator avatarItr = _avatarsToFadeOut.begin();
const render::ScenePointer& scene = qApp->getMain3DScene(); const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction; render::Transaction transaction;
while (avatarItr != _avatarsToFade.end()) { while (avatarItr != _avatarsToFadeOut.end()) {
auto avatar = std::static_pointer_cast<Avatar>(*avatarItr); auto avatar = std::static_pointer_cast<Avatar>(*avatarItr);
avatar->updateFadingStatus(scene); avatar->updateFadingStatus();
if (!avatar->isFading()) { if (!avatar->isFading()) {
// fading to zero is such a rare event we push a unique transaction for each // fading to zero is such a rare event we push a unique transaction for each
if (avatar->isInScene()) { if (avatar->isInScene()) {
avatar->removeFromScene(*avatarItr, scene, transaction); avatar->removeFromScene(*avatarItr, scene, transaction);
} }
avatarItr = _avatarsToFade.erase(avatarItr); avatarItr = _avatarsToFadeOut.erase(avatarItr);
} else { } else {
++avatarItr; ++avatarItr;
} }
@ -457,7 +457,7 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID()); DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID());
avatar->fadeOut(qApp->getMain3DScene(), removalReason); avatar->fadeOut(qApp->getMain3DScene(), removalReason);
} }
_avatarsToFade.push_back(removedAvatar); _avatarsToFadeOut.push_back(removedAvatar);
} }
void AvatarManager::clearOtherAvatars() { void AvatarManager::clearOtherAvatars() {

View file

@ -222,7 +222,7 @@ private:
void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar,
KillAvatarReason removalReason = KillAvatarReason::NoReason) override; KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
QVector<AvatarSharedPointer> _avatarsToFade; QVector<AvatarSharedPointer> _avatarsToFadeOut;
using SetOfOtherAvatars = std::set<OtherAvatarPointer>; using SetOfOtherAvatars = std::set<OtherAvatarPointer>;
SetOfOtherAvatars _avatarsToChangeInPhysics; SetOfOtherAvatars _avatarsToChangeInPhysics;

View file

@ -857,6 +857,8 @@ void MyAvatar::simulate(float deltaTime) {
} }
updateAvatarEntities(); updateAvatarEntities();
updateFadingStatus();
} }
// As far as I know no HMD system supports a play area of a kilometer in radius. // As far as I know no HMD system supports a play area of a kilometer in radius.

View file

@ -612,6 +612,8 @@ void Avatar::simulate(float deltaTime, bool inView) {
PROFILE_RANGE(simulation, "entities"); PROFILE_RANGE(simulation, "entities");
updateAvatarEntities(); updateAvatarEntities();
} }
updateFadingStatus();
} }
float Avatar::getSimulationRate(const QString& rateName) const { float Avatar::getSimulationRate(const QString& rateName) const {
@ -775,14 +777,15 @@ void Avatar::fade(render::Transaction& transaction, render::Transition::Type typ
_isFading = true; _isFading = true;
} }
void Avatar::updateFadingStatus(render::ScenePointer scene) { void Avatar::updateFadingStatus() {
render::Transaction transaction; render::Transaction transaction;
transaction.queryTransitionOnItem(_renderItemID, [this](render::ItemID id, const render::Transition* transition) { transaction.queryTransitionOnItem(_renderItemID, [this](render::ItemID id, const render::Transition* transition) {
if (transition == nullptr || transition->isFinished) { if (!transition || transition->isFinished) {
AbstractViewStateInterface::instance()->getMain3DScene()->resetItemTransition(id);
_isFading = false; _isFading = false;
} }
}); });
scene->enqueueTransaction(transaction); AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
} }
void Avatar::removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { void Avatar::removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {

View file

@ -402,7 +402,7 @@ public:
void fadeIn(render::ScenePointer scene); void fadeIn(render::ScenePointer scene);
void fadeOut(render::ScenePointer scene, KillAvatarReason reason); void fadeOut(render::ScenePointer scene, KillAvatarReason reason);
bool isFading() const { return _isFading; } bool isFading() const { return _isFading; }
void updateFadingStatus(render::ScenePointer scene); void updateFadingStatus();
// JSDoc is in AvatarData.h. // JSDoc is in AvatarData.h.
Q_INVOKABLE virtual float getEyeHeight() const override; Q_INVOKABLE virtual float getEyeHeight() const override;

View file

@ -85,7 +85,11 @@ float evalFadeGradient(FadeObjectParams params, vec3 position) {
} }
float evalFadeAlpha(FadeObjectParams params, vec3 position) { float evalFadeAlpha(FadeObjectParams params, vec3 position) {
return evalFadeGradient(params, position)-params.threshold; float alpha = evalFadeGradient(params, position)-params.threshold;
if (fadeParameters[params.category]._isInverted != 0) {
alpha = -alpha;
}
return alpha;
} }
void applyFadeClip(FadeObjectParams params, vec3 position) { void applyFadeClip(FadeObjectParams params, vec3 position) {
@ -96,9 +100,6 @@ void applyFadeClip(FadeObjectParams params, vec3 position) {
void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) { void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
float alpha = evalFadeAlpha(params, position); float alpha = evalFadeAlpha(params, position);
if (fadeParameters[params.category]._isInverted!=0) {
alpha = -alpha;
}
if (alpha < 0.0) { if (alpha < 0.0) {
discard; discard;

View file

@ -826,7 +826,7 @@ render::ShapePipelinePointer GeometryCache::getFadingShapePipeline(bool textured
bool unlit, bool depthBias) { bool unlit, bool depthBias) {
auto fadeEffect = DependencyManager::get<FadeEffect>(); auto fadeEffect = DependencyManager::get<FadeEffect>();
auto fadeBatchSetter = fadeEffect->getBatchSetter(); auto fadeBatchSetter = fadeEffect->getBatchSetter();
auto fadeItemSetter = fadeEffect->getItemStoredSetter(); auto fadeItemSetter = fadeEffect->getItemUniformSetter();
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, true), nullptr, return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, true), nullptr,
[fadeBatchSetter, fadeItemSetter](const render::ShapePipeline& shapePipeline, gpu::Batch& batch, render::Args* args) { [fadeBatchSetter, fadeItemSetter](const render::ShapePipeline& shapePipeline, gpu::Batch& batch, render::Args* args) {
batch.setResourceTexture(gr::Texture::MaterialAlbedo, DependencyManager::get<TextureCache>()->getWhiteTexture()); batch.setResourceTexture(gr::Texture::MaterialAlbedo, DependencyManager::get<TextureCache>()->getWhiteTexture());

View file

@ -22,6 +22,8 @@
#include "GeometryCache.h" #include "GeometryCache.h"
#include "CubeProjectedPolygon.h" #include "CubeProjectedPolygon.h"
#include "FadeEffect.h"
#include "render-utils/ShaderConstants.h" #include "render-utils/ShaderConstants.h"
using namespace render; using namespace render;
@ -37,7 +39,7 @@ namespace gr {
#define OUTLINE_STENCIL_MASK 1 #define OUTLINE_STENCIL_MASK 1
extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
HighlightResources::HighlightResources() { HighlightResources::HighlightResources() {
} }
@ -156,7 +158,6 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
auto& highlight = highlightStage->getHighlight(highlightId); auto& highlight = highlightStage->getHighlight(highlightId);
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
ShapeKey::Builder defaultKeyBuilder;
// Render full screen // Render full screen
outputs = args->_viewport; outputs = args->_viewport;
@ -177,10 +178,6 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
gpu::doInBatch("DrawHighlightMask::run", args->_context, [&](gpu::Batch& batch) { gpu::doInBatch("DrawHighlightMask::run", args->_context, [&](gpu::Batch& batch) {
args->_batch = &batch; args->_batch = &batch;
auto maskPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder);
auto maskDeformedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed());
auto maskDeformedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed().withDualQuatSkinned());
// Setup camera, projection and viewport for all items // Setup camera, projection and viewport for all items
glm::mat4 projMat; glm::mat4 projMat;
Transform viewMat; Transform viewMat;
@ -191,38 +188,54 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
batch.setProjectionJitter(jitter.x, jitter.y); batch.setProjectionJitter(jitter.x, jitter.y);
batch.setViewTransform(viewMat); batch.setViewTransform(viewMat);
std::vector<ShapeKey> deformedShapeKeys; const std::vector<ShapeKey::Builder> keys = {
std::vector<ShapeKey> deformedDQShapeKeys; ShapeKey::Builder(), ShapeKey::Builder().withFade(),
ShapeKey::Builder().withDeformed(), ShapeKey::Builder().withDeformed().withFade(),
ShapeKey::Builder().withDeformed().withDualQuatSkinned(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withFade(),
ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade()
};
std::vector<std::vector<ShapeKey>> sortedShapeKeys(keys.size());
// Iterate through all inShapes and render the unskinned const int OWN_PIPELINE_INDEX = 6;
args->_shapePipeline = maskPipeline;
batch.setPipeline(maskPipeline->pipeline);
for (const auto& items : inShapes) { for (const auto& items : inShapes) {
itemBounds.insert(itemBounds.end(), items.second.begin(), items.second.end()); itemBounds.insert(itemBounds.end(), items.second.begin(), items.second.end());
if (items.first.isDeformed() && items.first.isDualQuatSkinned()) {
deformedDQShapeKeys.push_back(items.first); int index = items.first.hasOwnPipeline() ? OWN_PIPELINE_INDEX : 0;
} else if (items.first.isDeformed()) { if (items.first.isDeformed()) {
deformedShapeKeys.push_back(items.first); index += 2;
} else { if (items.first.isDualQuatSkinned()) {
renderItems(renderContext, items.second); index += 2;
}
}
if (items.first.isFaded()) {
index += 1;
}
sortedShapeKeys[index].push_back(items.first);
}
// Render non-withOwnPipeline things
for (size_t i = 0; i < OWN_PIPELINE_INDEX; i++) {
auto& shapeKeys = sortedShapeKeys[i];
if (shapeKeys.size() > 0) {
const auto& shapePipeline = _shapePlumber->pickPipeline(args, keys[i]);
args->_shapePipeline = shapePipeline;
for (const auto& key : shapeKeys) {
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
}
} }
} }
// Reiterate to render the skinned // Render withOwnPipeline things
if (deformedShapeKeys.size() > 0) { for (size_t i = OWN_PIPELINE_INDEX; i < keys.size(); i++) {
args->_shapePipeline = maskDeformedPipeline; auto& shapeKeys = sortedShapeKeys[i];
batch.setPipeline(maskDeformedPipeline->pipeline); if (shapeKeys.size() > 0) {
for (const auto& key : deformedShapeKeys) { args->_shapePipeline = nullptr;
renderItems(renderContext, inShapes.at(key)); for (const auto& key : shapeKeys) {
} args->_itemShapeKey = key._flags.to_ulong();
} renderShapes(renderContext, _shapePlumber, inShapes.at(key));
}
// Reiterate to render the DQ skinned
if (deformedDQShapeKeys.size() > 0) {
args->_shapePipeline = maskDeformedDQPipeline;
batch.setPipeline(maskDeformedDQPipeline->pipeline);
for (const auto& key : deformedDQShapeKeys) {
renderItems(renderContext, inShapes.at(key));
} }
} }
@ -502,7 +515,9 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
state->setColorWriteMask(false, false, false, false); state->setColorWriteMask(false, false, false, false);
initZPassPipelines(*shapePlumber, state);
auto fadeEffect = DependencyManager::get<FadeEffect>();
initZPassPipelines(*shapePlumber, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
} }
auto sharedParameters = std::make_shared<HighlightSharedParameters>(); auto sharedParameters = std::make_shared<HighlightSharedParameters>();

View file

@ -40,7 +40,7 @@ namespace gr {
void initDeferredPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter); void initDeferredPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
void initForwardPipelines(ShapePlumber& plumber); void initForwardPipelines(ShapePlumber& plumber);
void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
void addPlumberPipeline(ShapePlumber& plumber, void addPlumberPipeline(ShapePlumber& plumber,
const ShapeKey& key, int programId, const ShapeKey& key, int programId,
@ -364,37 +364,29 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr
} }
} }
void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state) { void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& extraBatchSetter, const render::ShapePipeline::ItemSetter& itemSetter) {
using namespace shader::render_utils::program; using namespace shader::render_utils::program;
gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(model_shadow);
shapePlumber.addPipeline( shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withoutDeformed().withoutFade(), ShapeKey::Filter::Builder().withoutDeformed().withoutFade(),
modelProgram, state); gpu::Shader::createProgram(model_shadow), state);
gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(deformed_model_shadow);
shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withoutFade(),
skinProgram, state);
gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(model_shadow_fade);
shapePlumber.addPipeline( shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withoutDeformed().withFade(), ShapeKey::Filter::Builder().withoutDeformed().withFade(),
modelFadeProgram, state); gpu::Shader::createProgram(model_shadow_fade), state, extraBatchSetter, itemSetter);
gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(deformed_model_shadow_fade); shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withoutFade(),
gpu::Shader::createProgram(deformed_model_shadow), state);
shapePlumber.addPipeline( shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withFade(), ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withFade(),
skinFadeProgram, state); gpu::Shader::createProgram(deformed_model_shadow_fade), state, extraBatchSetter, itemSetter);
gpu::ShaderPointer skinModelShadowDualQuatProgram = gpu::Shader::createProgram(deformed_model_shadow_dq);
shapePlumber.addPipeline( shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withoutFade(), ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withoutFade(),
skinModelShadowDualQuatProgram, state); gpu::Shader::createProgram(deformed_model_shadow_dq), state);
gpu::ShaderPointer skinModelShadowFadeDualQuatProgram = gpu::Shader::createProgram(deformed_model_shadow_fade_dq);
shapePlumber.addPipeline( shapePlumber.addPipeline(
ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withFade(), ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withFade(),
skinModelShadowFadeDualQuatProgram, state); gpu::Shader::createProgram(deformed_model_shadow_fade_dq), state, extraBatchSetter, itemSetter);
} }
// FIXME find a better way to setup the default textures // FIXME find a better way to setup the default textures

View file

@ -26,6 +26,8 @@
#include "RenderCommonTask.h" #include "RenderCommonTask.h"
#include "FadeEffect.h"
// These values are used for culling the objects rendered in the shadow map // These values are used for culling the objects rendered in the shadow map
// but are readjusted afterwards // but are readjusted afterwards
#define SHADOW_FRUSTUM_NEAR 1.0f #define SHADOW_FRUSTUM_NEAR 1.0f
@ -33,7 +35,7 @@
using namespace render; using namespace render;
extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
void RenderShadowTask::configure(const Config& configuration) { void RenderShadowTask::configure(const Config& configuration) {
DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.enabled); DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.enabled);
@ -49,7 +51,8 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
state->setCullMode(gpu::State::CULL_BACK); state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
initZPassPipelines(*shapePlumber, state); auto fadeEffect = DependencyManager::get<FadeEffect>();
initZPassPipelines(*shapePlumber, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
} }
// FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw // FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw
@ -222,7 +225,6 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
auto& fbo = cascade.framebuffer; auto& fbo = cascade.framebuffer;
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
ShapeKey::Builder defaultKeyBuilder;
auto adjustedShadowFrustum = args->getViewFrustum(); auto adjustedShadowFrustum = args->getViewFrustum();
// Adjust the frustum near and far depths based on the rendered items bounding box to have // Adjust the frustum near and far depths based on the rendered items bounding box to have
@ -253,53 +255,56 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
batch.setProjectionTransform(projMat); batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat, false); batch.setViewTransform(viewMat, false);
auto shadowPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder); const std::vector<ShapeKey::Builder> keys = {
auto shadowDeformedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed()); ShapeKey::Builder(), ShapeKey::Builder().withFade(),
auto shadowDeformedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed().withDualQuatSkinned()); ShapeKey::Builder().withDeformed(), ShapeKey::Builder().withDeformed().withFade(),
ShapeKey::Builder().withDeformed().withDualQuatSkinned(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withFade(),
ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade()
};
std::vector<std::vector<ShapeKey>> sortedShapeKeys(keys.size());
std::vector<ShapeKey> deformedShapeKeys{}; const int OWN_PIPELINE_INDEX = 6;
std::vector<ShapeKey> deformedDQShapeKeys{}; for (const auto& items : inShapes) {
std::vector<ShapeKey> ownPipelineShapeKeys{}; int index = items.first.hasOwnPipeline() ? OWN_PIPELINE_INDEX : 0;
// Iterate through all inShapes and render the unskinned
args->_shapePipeline = shadowPipeline;
batch.setPipeline(shadowPipeline->pipeline);
for (auto items : inShapes) {
if (items.first.isDeformed()) { if (items.first.isDeformed()) {
index += 2;
if (items.first.isDualQuatSkinned()) { if (items.first.isDualQuatSkinned()) {
deformedDQShapeKeys.push_back(items.first); index += 2;
} else { }
deformedShapeKeys.push_back(items.first); }
if (items.first.isFaded()) {
index += 1;
}
sortedShapeKeys[index].push_back(items.first);
}
// Render non-withOwnPipeline things
for (size_t i = 0; i < OWN_PIPELINE_INDEX; i++) {
auto& shapeKeys = sortedShapeKeys[i];
if (shapeKeys.size() > 0) {
const auto& shapePipeline = _shapePlumber->pickPipeline(args, keys[i]);
args->_shapePipeline = shapePipeline;
for (const auto& key : shapeKeys) {
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
} }
} else if (!items.first.hasOwnPipeline()) {
renderItems(renderContext, items.second);
} else {
ownPipelineShapeKeys.push_back(items.first);
} }
} }
// Reiterate to render the skinned // Render withOwnPipeline things
args->_shapePipeline = shadowDeformedPipeline; for (size_t i = OWN_PIPELINE_INDEX; i < keys.size(); i++) {
batch.setPipeline(shadowDeformedPipeline->pipeline); auto& shapeKeys = sortedShapeKeys[i];
for (const auto& key : deformedShapeKeys) { if (shapeKeys.size() > 0) {
renderItems(renderContext, inShapes.at(key)); args->_shapePipeline = nullptr;
for (const auto& key : shapeKeys) {
args->_itemShapeKey = key._flags.to_ulong();
renderShapes(renderContext, _shapePlumber, inShapes.at(key));
}
}
} }
// Reiterate to render the DQ skinned
args->_shapePipeline = shadowDeformedDQPipeline;
batch.setPipeline(shadowDeformedDQPipeline->pipeline);
for (const auto& key : deformedDQShapeKeys) {
renderItems(renderContext, inShapes.at(key));
}
// Finally render the items with their own pipeline last to prevent them from breaking the
// render state. This is probably a temporary code as there is probably something better
// to do in the render call of objects that have their own pipeline.
args->_shapePipeline = nullptr; args->_shapePipeline = nullptr;
for (const auto& key : ownPipelineShapeKeys) {
args->_itemShapeKey = key._flags.to_ulong();
renderItems(renderContext, inShapes.at(key));
}
} }
args->_batch = nullptr; args->_batch = nullptr;