mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 17:35:45 +02:00
Cleaning up the lights and the light stage
This commit is contained in:
parent
9801ff075a
commit
4bf93f66df
9 changed files with 430 additions and 96 deletions
|
@ -25,30 +25,69 @@ EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityI
|
|||
return entity;
|
||||
}
|
||||
|
||||
RenderableLightEntityItem::RenderableLightEntityItem(const EntityItemID& entityItemID) : LightEntityItem(entityItemID),
|
||||
_light(std::make_shared<model::Light>()),
|
||||
_lightStamp(-1)
|
||||
{
|
||||
}
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const LightPayload::Pointer& payload) {
|
||||
return ItemKey::Builder::light();
|
||||
}
|
||||
|
||||
template <> const Item::Bound payloadGetBound(const LightPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->_bound;
|
||||
}
|
||||
return render::Item::Bound();
|
||||
}
|
||||
template <> void payloadRender(const LightPayload::Pointer& payload, RenderArgs* args) {
|
||||
if (args) {
|
||||
if (payload) {
|
||||
payload->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableLightEntityItem::updateLightFromEntity() {
|
||||
_light->setPosition(getPosition());
|
||||
_light->setOrientation(getRotation());
|
||||
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
float largestDiameter = glm::max(dimensions.x, dimensions.y, dimensions.z);
|
||||
_light->setMaximumRadius(largestDiameter / 2.0f);
|
||||
|
||||
_light->setColor(toGlm(getXColor()));
|
||||
|
||||
float intensity = getIntensity() * (_isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f);
|
||||
_light->setIntensity(intensity);
|
||||
|
||||
_light->setFalloffRadius(getFalloffRadius());
|
||||
|
||||
|
||||
float exponent = getExponent();
|
||||
float cutoff = glm::radians(getCutoff());
|
||||
if (!_isSpotlight) {
|
||||
_light->setType(model::Light::POINT);
|
||||
} else {
|
||||
_light->setType(model::Light::SPOT);
|
||||
|
||||
_light->setSpotAngle(cutoff);
|
||||
_light->setSpotExponent(exponent);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLightEntityItem::render");
|
||||
assert(getType() == EntityTypes::Light);
|
||||
checkFading();
|
||||
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
float largestDiameter = glm::max(dimensions.x, dimensions.y, dimensions.z);
|
||||
|
||||
glm::vec3 color = toGlm(getXColor());
|
||||
updateLightFromEntity();
|
||||
|
||||
float intensity = getIntensity() * (_isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f);
|
||||
float falloffRadius = getFalloffRadius();
|
||||
float exponent = getExponent();
|
||||
float cutoff = glm::radians(getCutoff());
|
||||
|
||||
if (_isSpotlight) {
|
||||
DependencyManager::get<DeferredLightingEffect>()->addSpotLight(position, largestDiameter / 2.0f,
|
||||
color, intensity, falloffRadius, rotation, exponent, cutoff);
|
||||
} else {
|
||||
DependencyManager::get<DeferredLightingEffect>()->addPointLight(position, largestDiameter / 2.0f,
|
||||
color, intensity, falloffRadius);
|
||||
}
|
||||
DependencyManager::get<DeferredLightingEffect>()->addLight(_light);
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
Q_ASSERT(args->_batch);
|
||||
|
|
|
@ -13,12 +13,32 @@
|
|||
#define hifi_RenderableLightEntityItem_h
|
||||
|
||||
#include <LightEntityItem.h>
|
||||
#include <model/Light.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
|
||||
class LightRenderItem {
|
||||
public:
|
||||
using Payload = render::Payload<LightRenderItem>;
|
||||
using Pointer = Payload::DataPointer;
|
||||
|
||||
model::LightPointer _light;
|
||||
|
||||
render::Item::Bound _bound;
|
||||
|
||||
void render(RenderArgs* args);
|
||||
};
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const LightRenderItem::Pointer& payload);
|
||||
template <> const Item::Bound payloadGetBound(const LightRenderItem::Pointer& payload);
|
||||
template <> void payloadRender(const LightRenderItem::Pointer& payload, RenderArgs* args);
|
||||
}
|
||||
|
||||
class RenderableLightEntityItem : public LightEntityItem {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableLightEntityItem(const EntityItemID& entityItemID) : LightEntityItem(entityItemID) { }
|
||||
RenderableLightEntityItem(const EntityItemID& entityItemID);
|
||||
|
||||
virtual void render(RenderArgs* args) override;
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
|
@ -27,7 +47,62 @@ public:
|
|||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
void** intersectedObject, bool precisionPicking) const override;
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
void updateLightFromEntity();
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override {
|
||||
_myItem = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<LightRenderItem::Payload>();
|
||||
|
||||
render::Item::Status::Getters statusGetters;
|
||||
makeEntityItemStatusGetters(self, statusGetters);
|
||||
renderPayload->addStatusGetters(statusGetters);
|
||||
|
||||
pendingChanges.resetItem(_myItem, renderPayload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override {
|
||||
pendingChanges.removeItem(_myItem);
|
||||
render::Item::clearID(_myItem);
|
||||
}
|
||||
|
||||
virtual void locationChanged(bool tellPhysics = true) override {
|
||||
EntityItem::locationChanged(tellPhysics);
|
||||
if (!render::Item::isValidID(_myItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
render::PendingChanges pendingChanges;
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
||||
pendingChanges.updateItem<RenderableEntityItemProxy>(_myItem, [](RenderableEntityItemProxy& data) {
|
||||
});
|
||||
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
virtual void dimensionsChanged() override {
|
||||
EntityItem::dimensionsChanged();
|
||||
_renderHelper.notifyChanged();
|
||||
}
|
||||
|
||||
void checkFading() {
|
||||
bool transparent = isTransparent();
|
||||
if (transparent != _prevIsTransparent) {
|
||||
_renderHelper.notifyChanged();
|
||||
_isFading = false;
|
||||
_prevIsTransparent = transparent;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SimpleRenderableEntityItem _renderHelper;
|
||||
bool _prevIsTransparent { isTransparent() };
|
||||
render::ItemID _myItem { render::Item::INVALID_ITEM_ID };
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -410,9 +410,6 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
|
||||
}
|
||||
if (!lightStage.lights.empty()) {
|
||||
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
|
||||
}
|
||||
|
||||
if (linearDepthTarget) {
|
||||
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
|
||||
|
|
|
@ -99,20 +99,28 @@ void DeferredLightingEffect::init() {
|
|||
loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations);
|
||||
|
||||
// Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light
|
||||
_globalLights.push_back(0);
|
||||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||
|
||||
model::LightPointer lp = _allocatedLights[0];
|
||||
lp->setType(model::Light::SUN);
|
||||
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_lightStage.addLight(lp);
|
||||
|
||||
lp->setDirection(glm::vec3(-1.0f));
|
||||
lp->setColor(glm::vec3(1.0f));
|
||||
lp->setIntensity(1.0f);
|
||||
lp->setType(model::Light::SUN);
|
||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
|
||||
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_globalLights.push_back(_lightStage.addLight(lp));
|
||||
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addLight(const model::LightPointer& light) {
|
||||
assert(light);
|
||||
auto lightID = _lightStage.addLight(light);
|
||||
if (light->getType() == model::Light::POINT) {
|
||||
_pointLights.push_back(lightID);
|
||||
} else {
|
||||
_spotLights.push_back(lightID);
|
||||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
|
||||
|
@ -459,11 +467,14 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
|
||||
// Global directional light and ambient pass
|
||||
|
||||
assert(deferredLightingEffect->getLightStage().lights.size() > 0);
|
||||
const auto& globalShadow = deferredLightingEffect->getLightStage().lights[0]->shadow;
|
||||
assert(deferredLightingEffect->getLightStage().getNumLights() > 0);
|
||||
auto lightAndShadow = deferredLightingEffect->getLightStage().getLightAndShadow(0);
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
|
||||
// Bind the shadow buffer
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow.map);
|
||||
if (globalShadow) {
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map);
|
||||
}
|
||||
|
||||
auto& program = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadow : deferredLightingEffect->_directionalLight;
|
||||
LightLocationsPtr locations = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadowLocations : deferredLightingEffect->_directionalLightLocations;
|
||||
|
@ -492,7 +503,9 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
|
|||
}
|
||||
|
||||
if (locations->shadowTransformBuffer >= 0) {
|
||||
batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow.getBuffer());
|
||||
if (globalShadow) {
|
||||
batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow->getBuffer());
|
||||
}
|
||||
}
|
||||
batch.setPipeline(program);
|
||||
}
|
||||
|
@ -573,7 +586,10 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
||||
|
||||
for (auto lightID : deferredLightingEffect->_pointLights) {
|
||||
auto& light = deferredLightingEffect->_allocatedLights[lightID];
|
||||
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
|
||||
if (!light) {
|
||||
continue;
|
||||
}
|
||||
// IN DEBUG: light->setShowContour(true);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||
|
||||
|
@ -613,7 +629,10 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
|||
auto& conePart = mesh->getPartBuffer().get<model::Mesh::Part>(0);
|
||||
|
||||
for (auto lightID : deferredLightingEffect->_spotLights) {
|
||||
auto light = deferredLightingEffect->_allocatedLights[lightID];
|
||||
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
|
||||
if (!light) {
|
||||
continue;
|
||||
}
|
||||
// IN DEBUG:
|
||||
// light->setShowContour(true);
|
||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||
|
|
|
@ -43,6 +43,8 @@ class DeferredLightingEffect : public Dependency {
|
|||
public:
|
||||
void init();
|
||||
|
||||
void addLight(const model::LightPointer& light);
|
||||
|
||||
/// Adds a point light to render for the current frame.
|
||||
void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
float intensity = 0.5f, float falloffRadius = 0.01f);
|
||||
|
@ -58,6 +60,7 @@ public:
|
|||
void setGlobalLight(const model::LightPointer& light);
|
||||
|
||||
const LightStage& getLightStage() { return _lightStage; }
|
||||
|
||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
|
|
@ -87,10 +87,36 @@ const glm::mat4& LightStage::Shadow::getProjection() const {
|
|||
return _frustum->getProjection();
|
||||
}
|
||||
|
||||
const LightStage::LightPointer LightStage::addLight(model::LightPointer light) {
|
||||
// Shadow stageShadow{light};
|
||||
LightPointer stageLight = std::make_shared<Light>(Shadow(light));
|
||||
stageLight->light = light;
|
||||
lights.push_back(stageLight);
|
||||
return stageLight;
|
||||
LightStage::Index LightStage::findLight(const LightPointer& light) const {
|
||||
auto found = _lightMap.find(light);
|
||||
if (found != _lightMap.end()) {
|
||||
return INVALID_INDEX;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LightStage::Index LightStage::addLight(const LightPointer& light) {
|
||||
|
||||
auto found = _lightMap.find(light);
|
||||
if (found == _lightMap.end()) {
|
||||
auto lightId = _lights.newElement(light);
|
||||
// Avoid failing to allocate a light, just pass
|
||||
if (lightId != INVALID_INDEX) {
|
||||
|
||||
// Allocate the matching Desc to the light
|
||||
if (lightId >= _descs.size()) {
|
||||
_descs.emplace_back(Desc());
|
||||
} else {
|
||||
_descs.emplace(_descs.begin() + lightId, Desc());
|
||||
}
|
||||
|
||||
// INsert the light and its index in the reverese map
|
||||
_lightMap.insert(LightMap::value_type(light, lightId));
|
||||
}
|
||||
return lightId;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,15 +12,161 @@
|
|||
#ifndef hifi_render_utils_LightStage_h
|
||||
#define hifi_render_utils_LightStage_h
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "gpu/Framebuffer.h"
|
||||
|
||||
#include "model/Light.h"
|
||||
|
||||
class ViewFrustum;
|
||||
|
||||
namespace indexed_elements {
|
||||
|
||||
using Index = int32_t;
|
||||
const Index MAXIMUM_INDEX { 1 << 30 };
|
||||
const Index INVALID_INDEX { -1 };
|
||||
using Indices = std::vector< Index >;
|
||||
|
||||
template <Index MaxNumElements = MAXIMUM_INDEX>
|
||||
class Allocator {
|
||||
public:
|
||||
Allocator() {}
|
||||
Indices _freeIndices;
|
||||
Index _nextNewIndex { 0 };
|
||||
|
||||
bool checkIndex(Index index) const { return ((index >= 0) && (index < _nextNewIndex)); }
|
||||
Index getNumIndices() const { return _nextNewIndex - _freeIndices.size(); }
|
||||
|
||||
Index allocateIndex() {
|
||||
if (_freeIndices.empty()) {
|
||||
Index index = _nextNewIndex;
|
||||
if (index >= MaxNumElements) {
|
||||
// abort! we are trying to go overboard with the total number of allocated elements
|
||||
assert(false);
|
||||
// This should never happen because Bricks are allocated along with the cells and there
|
||||
// is already a cap on the cells allocation
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
_nextNewIndex++;
|
||||
return index;
|
||||
} else {
|
||||
Index index = _freeIndices.back();
|
||||
_freeIndices.pop_back();
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
void freeIndex(Index index) {
|
||||
if (checkIndex(index)) {
|
||||
_freeIndices.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_freeIndices.clear();
|
||||
_nextNewIndex = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, Index MaxNumElements = MAXIMUM_INDEX>
|
||||
class IndexedVector {
|
||||
Allocator<MaxNumElements> _allocator;
|
||||
public:
|
||||
using Element = T;
|
||||
using Elements = std::vector<T>;
|
||||
|
||||
Elements _elements;
|
||||
|
||||
bool checkIndex(Index index) const { return _allocator.checkIndex(index); };
|
||||
Index getNumElements() const { return _allocator.getNumIndices(); }
|
||||
|
||||
Index newElement(const Element& e) {
|
||||
Index index = _allocator.allocateIndex();
|
||||
if (index != INVALID_INDEX) {
|
||||
if (index < _elements.size()) {
|
||||
_elements.emplace(_elements.begin() + index, e);
|
||||
} else {
|
||||
assert(index == _elements.size());
|
||||
_elements.emplace_back(e);
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
const Element& freeElement(Index index) {
|
||||
_allocator.freeIndex(index);
|
||||
return _elements[index];
|
||||
}
|
||||
|
||||
const Element& get(Index index) const {
|
||||
return _elements[index];
|
||||
}
|
||||
Element& edit(Index index) {
|
||||
return _elements[index];
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, Index MaxNumElements = MAXIMUM_INDEX>
|
||||
class IndexedPointerVector {
|
||||
Allocator<MaxNumElements> _allocator;
|
||||
public:
|
||||
using Data = T;
|
||||
using ElementPtr = std::shared_ptr<Data>;
|
||||
using Elements = std::vector<ElementPtr>;
|
||||
|
||||
Elements _elements;
|
||||
|
||||
bool checkIndex(Index index) const { return _allocator.checkIndex(index); };
|
||||
Index getNumElements() const { return _allocator.getNumIndices(); }
|
||||
|
||||
Index newElement(const ElementPtr& e) {
|
||||
Index index = _allocator.allocateIndex();
|
||||
if (index != INVALID_INDEX) {
|
||||
if (index < _elements.size()) {
|
||||
_elements.emplace(_elements.begin() + index, e);
|
||||
} else {
|
||||
assert(index == _elements.size());
|
||||
_elements.emplace_back(e);
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
ElementPtr freeElement(Index index) {
|
||||
ElementPtr freed;
|
||||
if (checkIndex(index)) {
|
||||
_allocator.freeIndex(index);
|
||||
freed = _elements[index];
|
||||
_elements[index].reset(); // really forget it
|
||||
}
|
||||
return freed;
|
||||
}
|
||||
|
||||
ElementPtr get(Index index) const {
|
||||
if (checkIndex(index)) {
|
||||
return _elements[index];
|
||||
} else {
|
||||
return ElementPtr();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Light stage to set up light-related rendering tasks
|
||||
class LightStage {
|
||||
public:
|
||||
using Index = indexed_elements::Index;
|
||||
static const Index INVALID_INDEX { indexed_elements::INVALID_INDEX };
|
||||
|
||||
using LightPointer = model::LightPointer;
|
||||
using Lights = indexed_elements::IndexedPointerVector<model::Light>;
|
||||
using LightMap = std::unordered_map<LightPointer, Index>;
|
||||
|
||||
class Shadow {
|
||||
public:
|
||||
using UniformBufferView = gpu::BufferView;
|
||||
|
@ -56,21 +202,45 @@ public:
|
|||
friend class Light;
|
||||
};
|
||||
using ShadowPointer = std::shared_ptr<Shadow>;
|
||||
using Shadows = indexed_elements::IndexedPointerVector<Shadow>;
|
||||
|
||||
class Light {
|
||||
public:
|
||||
Light(Shadow&& shadow) : shadow{ shadow } {}
|
||||
|
||||
model::LightPointer light;
|
||||
Shadow shadow;
|
||||
struct Desc {
|
||||
Index shadowId { INVALID_INDEX };
|
||||
};
|
||||
using LightPointer = std::shared_ptr<Light>;
|
||||
using Lights = std::vector<LightPointer>;
|
||||
using Descs = std::vector<Desc>;
|
||||
|
||||
const LightPointer addLight(model::LightPointer light);
|
||||
// TODO: removeLight
|
||||
|
||||
Lights lights;
|
||||
Index findLight(const LightPointer& light) const;
|
||||
Index addLight(const LightPointer& light);
|
||||
|
||||
bool checkLightId(Index index) const { return _lights.checkIndex(index); }
|
||||
|
||||
Index getNumLights() const { return _lights.getNumElements(); }
|
||||
|
||||
LightPointer getLight(Index lightId) const {
|
||||
return _lights.get(lightId);
|
||||
}
|
||||
Index getShadowId(Index lightId) const {
|
||||
if (checkLightId(lightId)) {
|
||||
return _descs[lightId].shadowId;
|
||||
} else {
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
ShadowPointer getShadow(Index lightId) const {
|
||||
return _shadows.get(getShadowId(lightId));
|
||||
}
|
||||
|
||||
using LightAndShadow = std::pair<LightPointer, ShadowPointer>;
|
||||
LightAndShadow getLightAndShadow(Index lightId) const {
|
||||
return LightAndShadow(getLight(lightId), getShadow(lightId));
|
||||
}
|
||||
|
||||
Lights _lights;
|
||||
LightMap _lightMap;
|
||||
Descs _descs;
|
||||
|
||||
Shadows _shadows;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,9 +37,14 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
|
|||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
const auto globalLight = lightStage.lights[0];
|
||||
const auto& shadow = globalLight->shadow;
|
||||
const auto& fbo = shadow.framebuffer;
|
||||
|
||||
LightStage::Index globalLightIndex { 0 };
|
||||
|
||||
const auto globalLight = lightStage.getLight(globalLightIndex);
|
||||
const auto shadow = lightStage.getShadow(globalLightIndex);
|
||||
if (!shadow) return;
|
||||
|
||||
const auto& fbo = shadow->framebuffer;
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
|
@ -54,8 +59,8 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
|
|||
gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH,
|
||||
vec4(vec3(1.0, 1.0, 1.0), 0.0), 1.0, 0, true);
|
||||
|
||||
batch.setProjectionTransform(shadow.getProjection());
|
||||
batch.setViewTransform(shadow.getView(), false);
|
||||
batch.setProjectionTransform(shadow->getProjection());
|
||||
batch.setViewTransform(shadow->getView(), false);
|
||||
|
||||
auto shadowPipeline = _shapePlumber->pickPipeline(args, ShapeKey());
|
||||
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, ShapeKey::Builder().withSkinned());
|
||||
|
@ -140,10 +145,10 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
|
|||
}
|
||||
|
||||
const auto& lightStage = DependencyManager::get<DeferredLightingEffect>()->getLightStage();
|
||||
const auto globalLight = lightStage.lights[0];
|
||||
const auto globalShadow = lightStage.getShadow(0);
|
||||
|
||||
// If the global light is not set, bail
|
||||
if (!globalLight) {
|
||||
if (!globalShadow) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -153,10 +158,10 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
|
|||
auto nearClip = args->getViewFrustum().getNearClip();
|
||||
float nearDepth = -args->_boomOffset.z;
|
||||
const int SHADOW_FAR_DEPTH = 20;
|
||||
globalLight->shadow.setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
|
||||
// Set the keylight render args
|
||||
args->pushViewFrustum(*(globalLight->shadow.getFrustum()));
|
||||
args->pushViewFrustum(*(globalShadow->getFrustum()));
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
|
||||
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor
|
||||
|
|
|
@ -530,7 +530,7 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont
|
|||
|
||||
|
||||
|
||||
const auto theLight = DependencyManager::get<DeferredLightingEffect>()->getLightStage().lights[0];
|
||||
const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage().getLight(0);
|
||||
|
||||
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
@ -564,8 +564,8 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont
|
|||
|
||||
batch.setUniformBuffer(ScatteringTask_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
batch.setUniformBuffer(ScatteringTask_ParamSlot, scatteringResource->getParametersBuffer());
|
||||
if (theLight->light) {
|
||||
batch.setUniformBuffer(ScatteringTask_LightSlot, theLight->light->getSchemaBuffer());
|
||||
if (light) {
|
||||
batch.setUniformBuffer(ScatteringTask_LightSlot, light->getSchemaBuffer());
|
||||
}
|
||||
batch.setResourceTexture(ScatteringTask_ScatteringTableSlot, scatteringTable);
|
||||
batch.setResourceTexture(ScatteringTask_CurvatureMapSlot, curvatureFramebuffer->getRenderBuffer(0));
|
||||
|
|
Loading…
Reference in a new issue