mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-19 14:03:20 +02:00
Add LightStage for rendering lights
This commit is contained in:
parent
82f7ea515d
commit
0776ae7e72
5 changed files with 150 additions and 25 deletions
|
@ -162,6 +162,7 @@ private:
|
|||
// Used to project points
|
||||
glm::mat4 _ourModelViewProjectionMatrix;
|
||||
};
|
||||
using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;
|
||||
|
||||
|
||||
#endif // hifi_ViewFrustum_h
|
||||
|
|
|
@ -69,6 +69,8 @@ void DeferredLightingEffect::init() {
|
|||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||
|
||||
model::LightPointer lp = _allocatedLights[0];
|
||||
// Add the global light to the light stage (for later shadow rendering)
|
||||
_lightStage.addLight(lp);
|
||||
|
||||
lp->setDirection(-glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
lp->setColor(glm::vec3(1.0f));
|
||||
|
@ -541,10 +543,6 @@ void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const gl
|
|||
light->setAmbientIntensity(ambientIntensity);
|
||||
}
|
||||
|
||||
model::LightPointer DeferredLightingEffect::getGlobalLight() {
|
||||
return _allocatedLights[_globalLights.front()];
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
||||
_skybox = skybox;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "model/Stage.h"
|
||||
#include "model/Geometry.h"
|
||||
|
||||
#include "LightStage.h"
|
||||
|
||||
class RenderArgs;
|
||||
struct LightLocations;
|
||||
using LightLocationsPtr = std::shared_ptr<LightLocations>;
|
||||
|
@ -50,9 +52,11 @@ public:
|
|||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
||||
|
||||
model::LightPointer getGlobalLight();
|
||||
const LightStage& getLightStage() { return _lightStage; }
|
||||
|
||||
private:
|
||||
LightStage _lightStage;
|
||||
|
||||
DeferredLightingEffect() = default;
|
||||
|
||||
model::MeshPointer _spotLightMesh;
|
||||
|
@ -72,26 +76,7 @@ private:
|
|||
gpu::PipelinePointer _spotLight;
|
||||
LightLocationsPtr _spotLightLocations;
|
||||
|
||||
class PointLight {
|
||||
public:
|
||||
glm::vec4 position;
|
||||
float radius;
|
||||
glm::vec4 ambient;
|
||||
glm::vec4 diffuse;
|
||||
glm::vec4 specular;
|
||||
float constantAttenuation;
|
||||
float linearAttenuation;
|
||||
float quadraticAttenuation;
|
||||
};
|
||||
|
||||
class SpotLight : public PointLight {
|
||||
public:
|
||||
glm::vec3 direction;
|
||||
float exponent;
|
||||
float cutoff;
|
||||
};
|
||||
|
||||
typedef std::vector< model::LightPointer > Lights;
|
||||
using Lights = std::vector<model::LightPointer>;
|
||||
|
||||
Lights _allocatedLights;
|
||||
std::vector<int> _globalLights;
|
||||
|
|
79
libraries/render-utils/src/LightStage.cpp
Normal file
79
libraries/render-utils/src/LightStage.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// LightStage.cpp
|
||||
// render-utils/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/14/2015.
|
||||
// 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 "ViewFrustum.h"
|
||||
|
||||
#include "LightStage.h"
|
||||
|
||||
LightStage::Shadow::Shadow(model::LightPointer light) : _light{ light}, _frustum{ std::make_shared<ViewFrustum>() } {
|
||||
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
|
||||
map = framebuffer->getDepthStencilBuffer();
|
||||
}
|
||||
|
||||
void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float zBack, float zFront) {
|
||||
// Orient the keylight frustum
|
||||
const auto& direction = glm::normalize(_light->getDirection());
|
||||
glm::quat orientation;
|
||||
if (direction == IDENTITY_UP) {
|
||||
orientation = glm::quat(glm::mat3(IDENTITY_UP, -IDENTITY_FRONT, IDENTITY_RIGHT));
|
||||
} else {
|
||||
auto side = glm::normalize(glm::cross(direction, IDENTITY_UP));
|
||||
auto up = glm::normalize(glm::cross(side, direction));
|
||||
auto orientation = glm::quat(glm::mat3(direction, up, side));
|
||||
}
|
||||
_frustum->setOrientation(orientation);
|
||||
|
||||
// Position the keylight frustum
|
||||
_frustum->setPosition(viewFrustum->getPosition() - 21.0f * direction);
|
||||
|
||||
_view = _frustum->getView();
|
||||
const Transform viewInverse{ _view.getInverseMatrix() };
|
||||
|
||||
viewFrustum->calculate();
|
||||
//const auto nearCorners = viewFrustum->getCorners(0);
|
||||
const auto nearClip = viewFrustum->getNearClip();
|
||||
const auto nearCorners = viewFrustum->getCorners(nearClip - 1);
|
||||
const auto farCorners = viewFrustum->getCorners(nearClip + 20);
|
||||
|
||||
vec3 min{ viewInverse.transform(nearCorners.bottomLeft) };
|
||||
vec3 max{ min };
|
||||
// Expand keylight frustum to fit view frustum
|
||||
auto fitFrustum = [&min, &max, &viewInverse](const vec3& viewCorner) {
|
||||
const auto corner = viewInverse.transform(viewCorner);
|
||||
|
||||
min.x = glm::min(min.x, corner.x);
|
||||
min.y = glm::min(min.y, corner.y);
|
||||
min.z = glm::min(min.z, corner.z);
|
||||
|
||||
max.x = glm::max(max.x, corner.x);
|
||||
max.y = glm::max(max.y, corner.y);
|
||||
max.z = glm::max(max.z, corner.z);
|
||||
};
|
||||
fitFrustum(nearCorners.bottomLeft);
|
||||
fitFrustum(nearCorners.bottomRight);
|
||||
fitFrustum(nearCorners.topLeft);
|
||||
fitFrustum(nearCorners.topRight);
|
||||
fitFrustum(farCorners.bottomLeft);
|
||||
fitFrustum(farCorners.bottomRight);
|
||||
fitFrustum(farCorners.topLeft);
|
||||
fitFrustum(farCorners.topRight);
|
||||
|
||||
glm::mat4 ortho = glm::ortho<float>(min.x, max.x, min.y, max.y, -max.z, -min.z);
|
||||
_frustum->setProjection(ortho);
|
||||
_projection = ortho;
|
||||
}
|
||||
|
||||
const LightStage::LightPointer& LightStage::addLight(model::LightPointer light) {
|
||||
Shadow stageShadow{light};
|
||||
LightPointer stageLight = std::make_shared<Light>(std::move(stageShadow));
|
||||
lights.push_back(stageLight);
|
||||
return stageLight;
|
||||
}
|
62
libraries/render-utils/src/LightStage.h
Normal file
62
libraries/render-utils/src/LightStage.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// LightStage.h
|
||||
// render-utils/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/14/2015.
|
||||
// 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_LightStage_h
|
||||
#define hifi_render_utils_LightStage_h
|
||||
|
||||
#include "gpu/Framebuffer.h"
|
||||
|
||||
#include "model/Light.h"
|
||||
|
||||
class ViewFrustum;
|
||||
|
||||
// Light stage to set up light-related rendering tasks
|
||||
class LightStage {
|
||||
public:
|
||||
class Shadow {
|
||||
public:
|
||||
const int MAP_SIZE = 2048;
|
||||
|
||||
Shadow(model::LightPointer light);
|
||||
|
||||
void setKeylightFrustum(ViewFrustum* viewFrustum, float zBack, float zFront);
|
||||
|
||||
const std::shared_ptr<ViewFrustum> getFrustum() const { return _frustum; }
|
||||
const glm::mat4& getProjection() const { return _projection; }
|
||||
const Transform& getView() const { return _view; }
|
||||
|
||||
gpu::FramebufferPointer framebuffer;
|
||||
gpu::TexturePointer map;
|
||||
protected:
|
||||
model::LightPointer _light;
|
||||
std::shared_ptr<ViewFrustum> _frustum;
|
||||
glm::mat4 _projection;
|
||||
Transform _view;
|
||||
};
|
||||
using ShadowPointer = std::shared_ptr<Shadow>;
|
||||
|
||||
class Light {
|
||||
public:
|
||||
Light(Shadow&& shadow) : shadow{ shadow } {}
|
||||
|
||||
model::LightPointer light;
|
||||
Shadow shadow;
|
||||
};
|
||||
using LightPointer = std::shared_ptr<Light>;
|
||||
using Lights = std::vector<LightPointer>;
|
||||
|
||||
const LightPointer& addLight(model::LightPointer light);
|
||||
// TODO: removeLight
|
||||
|
||||
Lights lights;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue