mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
Introucing the BackgroundStage to manage the background / skybox in one place
This commit is contained in:
parent
c36035d3eb
commit
bc41be7ec1
9 changed files with 289 additions and 12 deletions
|
@ -26,6 +26,8 @@
|
|||
#include <LightPayload.h>
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include <procedural\ProceduralSkybox.h>
|
||||
|
||||
class RenderableZoneEntityItemMeta {
|
||||
public:
|
||||
RenderableZoneEntityItemMeta(EntityItemPointer entity);
|
||||
|
@ -45,7 +47,8 @@ public:
|
|||
|
||||
model::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; }
|
||||
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
|
||||
model::SkyboxPointer editSkybox() { _needSkyboxUpdate = true; return _skybox; }
|
||||
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
|
||||
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
||||
|
||||
void setAmbientURL(const QString& ambientUrl);
|
||||
|
||||
|
@ -56,16 +59,19 @@ protected:
|
|||
|
||||
model::LightPointer _sunLight;
|
||||
model::LightPointer _ambientLight;
|
||||
model::SkyboxPointer _skybox;
|
||||
model::SunSkyStagePointer _background;
|
||||
|
||||
LightStagePointer _stage;
|
||||
LightStage::Index _sunIndex { LightStage::INVALID_INDEX };
|
||||
LightStage::Index _ambientIndex { LightStage::INVALID_INDEX };
|
||||
|
||||
BackgroundStagePointer _backgroundStage;
|
||||
BackgroundStage::Index _backgroundIndex { BackgroundStage::INVALID_INDEX };
|
||||
|
||||
bool _needUpdate { true };
|
||||
bool _needSunUpdate { true };
|
||||
bool _needAmbientUpdate { true };
|
||||
bool _needSkyboxUpdate { true };
|
||||
bool _needBackgroundUpdate { true };
|
||||
bool _isVisible { true };
|
||||
|
||||
|
||||
|
@ -356,7 +362,7 @@ void RenderableZoneEntityItem::updateKeyAmbientFromEntity(RenderableZoneEntityIt
|
|||
}
|
||||
|
||||
void RenderableZoneEntityItem::updateKeyBackgroundFromEntity(RenderableZoneEntityItemMeta& keyZonePayload) {
|
||||
auto skybox = keyZonePayload.editSkybox();
|
||||
auto background = keyZonePayload.editBackground();
|
||||
|
||||
this->getBackgroundMode();
|
||||
|
||||
|
@ -436,8 +442,10 @@ RenderableZoneEntityItemMeta::RenderableZoneEntityItemMeta(EntityItemPointer ent
|
|||
entity(entity),
|
||||
_sunLight(std::make_shared<model::Light>()),
|
||||
_ambientLight(std::make_shared<model::Light>()),
|
||||
_skybox(std::make_shared<model::Skybox>())
|
||||
{}
|
||||
_background(std::make_shared<model::SunSkyStage>())
|
||||
{
|
||||
_background->setSkybox(std::make_shared<ProceduralSkybox>());
|
||||
}
|
||||
|
||||
|
||||
RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() {
|
||||
|
@ -450,6 +458,12 @@ RenderableZoneEntityItemMeta::~RenderableZoneEntityItemMeta() {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if (_backgroundStage) {
|
||||
if (!BackgroundStage::isIndexInvalid(_backgroundIndex)) {
|
||||
_backgroundStage->removeBackground(_backgroundIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItemMeta::setAmbientURL(const QString& ambientUrl) {
|
||||
|
@ -541,6 +555,10 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) {
|
|||
_stage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
}
|
||||
|
||||
if (!_backgroundStage) {
|
||||
_backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
}
|
||||
|
||||
{ // Sun
|
||||
// Need an update ?
|
||||
if (_needSunUpdate) {
|
||||
|
@ -572,11 +590,20 @@ void RenderableZoneEntityItemMeta::render(RenderArgs* args) {
|
|||
{ // Skybox
|
||||
updateSkyboxMap();
|
||||
|
||||
if (_needBackgroundUpdate) {
|
||||
if (BackgroundStage::isIndexInvalid(_backgroundIndex)) {
|
||||
_backgroundIndex = _backgroundStage->addBackground(_background);
|
||||
} else {
|
||||
|
||||
}
|
||||
_needBackgroundUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isVisible()) {
|
||||
// FInally, push the light visible in the frame
|
||||
_stage->_currentFrame.pushSunLight(_sunIndex);
|
||||
_stage->_currentFrame.pushAmbientLight(_ambientIndex);
|
||||
_backgroundStage->_currentFrame.pushBackground(_backgroundIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ AUTOSCRIBE_SHADER_LIB(gpu model render)
|
|||
# pull in the resources.qrc file
|
||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
||||
link_hifi_libraries(shared ktx gpu model model-networking render animation fbx entities image)
|
||||
link_hifi_libraries(shared ktx gpu model model-networking render animation fbx entities image procedural)
|
||||
|
||||
if (NOT ANDROID)
|
||||
target_nsight()
|
||||
|
|
142
libraries/render-utils/src/BackgroundStage.cpp
Normal file
142
libraries/render-utils/src/BackgroundStage.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
//
|
||||
// BackgroundStage.cpp
|
||||
//
|
||||
// Created by Sam Gateau on 5/9/2017.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "BackgroundStage.h"
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
BackgroundStage::Index BackgroundStage::findBackground(const BackgroundPointer& background) const {
|
||||
auto found = _backgroundMap.find(background);
|
||||
if (found != _backgroundMap.end()) {
|
||||
return INVALID_INDEX;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BackgroundStage::Index BackgroundStage::addBackground(const BackgroundPointer& background) {
|
||||
|
||||
auto found = _backgroundMap.find(background);
|
||||
if (found == _backgroundMap.end()) {
|
||||
auto backgroundId = _backgrounds.newElement(background);
|
||||
// Avoid failing to allocate a background, just pass
|
||||
if (backgroundId != INVALID_INDEX) {
|
||||
|
||||
// Insert the background and its index in the reverse map
|
||||
_backgroundMap.insert(BackgroundMap::value_type(background, backgroundId));
|
||||
}
|
||||
return backgroundId;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index) {
|
||||
BackgroundPointer removed = _backgrounds.freeElement(index);
|
||||
|
||||
if (removed) {
|
||||
_backgroundMap.erase(removed);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
|
||||
void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
|
||||
const auto& lightingModel = inputs;
|
||||
if (!lightingModel->isBackgroundEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Background rendering decision
|
||||
auto backgroundStage = DependencyManager::get<DeferredLightingEffect>()->getBackgroundStage();
|
||||
model::SunSkyStagePointer background;
|
||||
model::SkyboxPointer skybox;
|
||||
if (backgroundStage->_currentFrame._backgrounds.size()) {
|
||||
auto backgroundId = backgroundStage->_currentFrame._backgrounds.front();
|
||||
auto background = backgroundStage->getBackground(backgroundId);
|
||||
if (background) {
|
||||
skybox = background->getSkybox();
|
||||
}
|
||||
} else {
|
||||
skybox = DependencyManager::get<DeferredLightingEffect>()->getDefaultSkybox();
|
||||
}
|
||||
|
||||
/* auto backgroundMode = skyStage->getBackgroundMode();
|
||||
|
||||
switch (backgroundMode) {
|
||||
case model::SunSkyStage::SKY_DEFAULT: {
|
||||
auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage();
|
||||
auto sceneKeyLight = scene->getKeyLight();
|
||||
|
||||
scene->setSunModelEnable(false);
|
||||
sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR));
|
||||
sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY);
|
||||
sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY);
|
||||
sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION);
|
||||
// fall through: render a skybox (if available), or the defaults (if requested)
|
||||
}
|
||||
|
||||
case model::SunSkyStage::SKY_BOX: {*/
|
||||
if (skybox && !skybox->empty()) {
|
||||
PerformanceTimer perfTimer("skybox");
|
||||
auto args = renderContext->args;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
args->_batch = &batch;
|
||||
|
||||
batch.enableSkybox(true);
|
||||
|
||||
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);
|
||||
|
||||
skybox->render(batch, args->getViewFrustum());
|
||||
});
|
||||
args->_batch = nullptr;
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
|
||||
// break;
|
||||
}
|
||||
// fall through: render defaults (if requested)
|
||||
// }
|
||||
/*
|
||||
case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) {
|
||||
auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage();
|
||||
auto sceneKeyLight = scene->getKeyLight();
|
||||
auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture();
|
||||
if (defaultSkyboxAmbientTexture) {
|
||||
sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance());
|
||||
sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture);
|
||||
} else {
|
||||
static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(
|
||||
"Failed to get a valid Default Skybox Ambient Texture ? probably because it couldn't be find during initialization step");
|
||||
}
|
||||
// fall through: render defaults skybox
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
backgroundStage->_currentFrame.clear();
|
||||
}
|
80
libraries/render-utils/src/BackgroundStage.h
Normal file
80
libraries/render-utils/src/BackgroundStage.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// BackgroundStage.h
|
||||
|
||||
// Created by Sam Gateau on 5/9/2017.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_BackgroundStage_h
|
||||
#define hifi_render_utils_BackgroundStage_h
|
||||
|
||||
#include <model/Stage.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <render/IndexedContainer.h>
|
||||
|
||||
#include "LightingModel.h"
|
||||
|
||||
|
||||
// Background stage to set up background-related rendering tasks
|
||||
class BackgroundStage {
|
||||
public:
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
||||
using BackgroundPointer = model::SunSkyStagePointer;
|
||||
using Backgrounds = render::indexed_container::IndexedPointerVector<model::SunSkyStage>;
|
||||
using BackgroundMap = std::unordered_map<BackgroundPointer, Index>;
|
||||
|
||||
using BackgroundIndices = std::vector<Index>;
|
||||
|
||||
|
||||
Index findBackground(const BackgroundPointer& background) const;
|
||||
Index addBackground(const BackgroundPointer& background);
|
||||
|
||||
BackgroundPointer removeBackground(Index index);
|
||||
|
||||
bool checkBackgroundId(Index index) const { return _backgrounds.checkIndex(index); }
|
||||
|
||||
Index getNumBackgrounds() const { return _backgrounds.getNumElements(); }
|
||||
Index getNumFreeBackgrounds() const { return _backgrounds.getNumFreeIndices(); }
|
||||
Index getNumAllocatedBackgrounds() const { return _backgrounds.getNumAllocatedIndices(); }
|
||||
|
||||
BackgroundPointer getBackground(Index backgroundId) const {
|
||||
return _backgrounds.get(backgroundId);
|
||||
}
|
||||
|
||||
Backgrounds _backgrounds;
|
||||
BackgroundMap _backgroundMap;
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
Frame() {}
|
||||
|
||||
void clear() { _backgrounds.clear(); }
|
||||
|
||||
void pushBackground(BackgroundStage::Index index) { _backgrounds.emplace_back(index); }
|
||||
|
||||
BackgroundStage::BackgroundIndices _backgrounds;
|
||||
};
|
||||
|
||||
Frame _currentFrame;
|
||||
};
|
||||
using BackgroundStagePointer = std::shared_ptr<BackgroundStage>;
|
||||
|
||||
|
||||
class DrawBackgroundStage {
|
||||
public:
|
||||
using Inputs = LightingModelPointer;
|
||||
using JobModel = render::Job::ModelI<DrawBackgroundStage, Inputs>;
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -141,6 +141,19 @@ void DeferredLightingEffect::init() {
|
|||
_globalLights.push_back(_lightStage->addLight(lp));
|
||||
_lightStage->addShadow(_globalLights[0]);
|
||||
|
||||
|
||||
_backgroundStage = std::make_shared<BackgroundStage>();
|
||||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
QString skyboxUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.jpg" };
|
||||
QString skyboxAmbientUrl { PathUtils::resourcesPath() + "images/Default-Sky-9-ambient.jpg" };
|
||||
|
||||
_defaultSkyboxTexture = textureCache->getImageTexture(skyboxUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", false } });
|
||||
_defaultSkyboxAmbientTexture = textureCache->getImageTexture(skyboxAmbientUrl, image::TextureUsage::CUBE_TEXTURE, { { "generateIrradiance", true } });
|
||||
|
||||
_defaultSkybox->setCubemap(_defaultSkyboxTexture);
|
||||
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "model/Light.h"
|
||||
#include "model/Geometry.h"
|
||||
|
||||
#include <procedural/ProceduralSkybox.h>
|
||||
|
||||
#include <render/CullTask.h>
|
||||
|
||||
#include "DeferredFrameTransform.h"
|
||||
|
@ -28,11 +30,13 @@
|
|||
|
||||
#include "LightStage.h"
|
||||
#include "LightClusters.h"
|
||||
#include "BackgroundEffect.h"
|
||||
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
||||
|
||||
class RenderArgs;
|
||||
struct LightLocations;
|
||||
using LightLocationsPtr = std::shared_ptr<LightLocations>;
|
||||
|
@ -51,15 +55,21 @@ public:
|
|||
void setGlobalLight(const model::LightPointer& light);
|
||||
|
||||
const LightStagePointer& getLightStage() { return _lightStage; }
|
||||
const BackgroundStagePointer& getBackgroundStage() { return _backgroundStage; }
|
||||
|
||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
||||
model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; }
|
||||
gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; }
|
||||
gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; }
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() = default;
|
||||
|
||||
LightStagePointer _lightStage;
|
||||
BackgroundStagePointer _backgroundStage;
|
||||
|
||||
bool _shadowMapEnabled{ false };
|
||||
bool _ambientOcclusionEnabled{ false };
|
||||
|
@ -103,6 +113,10 @@ private:
|
|||
Lights _allocatedLights;
|
||||
std::vector<int> _globalLights;
|
||||
|
||||
model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() };
|
||||
gpu::TexturePointer _defaultSkyboxTexture;
|
||||
gpu::TexturePointer _defaultSkyboxAmbientTexture;
|
||||
|
||||
friend class LightClusteringPass;
|
||||
friend class RenderDeferredSetup;
|
||||
friend class RenderDeferredLocals;
|
||||
|
|
|
@ -139,9 +139,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
|
||||
|
||||
// Use Stencil and draw background in Lighting buffer to complete filling in the opaque
|
||||
const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying();
|
||||
task.addJob<DrawBackgroundDeferred>("DrawBackgroundDeferred", backgroundInputs);
|
||||
|
||||
//const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying();
|
||||
//task.addJob<DrawBackgroundDeferred>("DrawBackgroundDeferred", backgroundInputs);
|
||||
|
||||
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel);
|
||||
|
||||
// Render transparent objects forward in LightingBuffer
|
||||
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying();
|
||||
|
|
|
@ -13,7 +13,7 @@ if (WIN32)
|
|||
setup_hifi_plugin(OpenGL Script Qml Widgets)
|
||||
link_hifi_libraries(shared gl networking controllers ui
|
||||
plugins display-plugins ui-plugins input-plugins script-engine
|
||||
render-utils model gpu gpu-gl render model-networking fbx ktx image)
|
||||
render-utils model gpu gpu-gl render model-networking fbx ktx image procedural)
|
||||
|
||||
include_hifi_library_headers(octree)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ setup_hifi_project(Quick Gui OpenGL)
|
|||
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
|
||||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image)
|
||||
link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image procedural)
|
||||
|
||||
package_libraries_for_deployment()
|
||||
|
||||
|
|
Loading…
Reference in a new issue