Cleaning up the lights and the light stage

This commit is contained in:
samcake 2016-08-26 17:47:20 -07:00
parent 9801ff075a
commit 4bf93f66df
9 changed files with 430 additions and 96 deletions

View file

@ -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);

View file

@ -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 };
};

View file

@ -403,51 +403,48 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
batch.setPipeline(getPipeline(_mode, first));
if (deferredFramebuffer) {
batch.setResourceTexture(Albedo, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(Normal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(Specular, deferredFramebuffer->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
}
if (!lightStage.lights.empty()) {
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
}
if (deferredFramebuffer) {
batch.setResourceTexture(Albedo, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(Normal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(Specular, deferredFramebuffer->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
}
if (linearDepthTarget) {
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture());
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
}
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
}
if (ambientOcclusionFramebuffer) {
batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture());
batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
}
if (linearDepthTarget) {
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture());
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
}
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
}
if (ambientOcclusionFramebuffer) {
batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture());
batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
}
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
const glm::vec2 bottomLeft(_size.x, _size.y);
const glm::vec2 topRight(_size.z, _size.w);
geometryBuffer->renderQuad(batch, bottomLeft, topRight, color);
batch.setResourceTexture(Albedo, nullptr);
batch.setResourceTexture(Normal, nullptr);
batch.setResourceTexture(Specular, nullptr);
batch.setResourceTexture(Depth, nullptr);
batch.setResourceTexture(Lighting, nullptr);
batch.setResourceTexture(Shadow, nullptr);
batch.setResourceTexture(LinearDepth, nullptr);
batch.setResourceTexture(HalfLinearDepth, nullptr);
batch.setResourceTexture(HalfNormal, nullptr);
batch.setResourceTexture(Albedo, nullptr);
batch.setResourceTexture(Normal, nullptr);
batch.setResourceTexture(Specular, nullptr);
batch.setResourceTexture(Depth, nullptr);
batch.setResourceTexture(Lighting, nullptr);
batch.setResourceTexture(Shadow, nullptr);
batch.setResourceTexture(LinearDepth, nullptr);
batch.setResourceTexture(HalfLinearDepth, nullptr);
batch.setResourceTexture(HalfNormal, nullptr);
batch.setResourceTexture(Curvature, nullptr);
batch.setResourceTexture(DiffusedCurvature, nullptr);
batch.setResourceTexture(Curvature, nullptr);
batch.setResourceTexture(DiffusedCurvature, nullptr);
batch.setResourceTexture(AmbientOcclusion, nullptr);
batch.setResourceTexture(AmbientOcclusionBlurred, nullptr);
batch.setResourceTexture(AmbientOcclusion, nullptr);
batch.setResourceTexture(AmbientOcclusionBlurred, nullptr);
});
}

View file

@ -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());

View file

@ -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; }

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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));