mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 01:17:14 +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
|
// Used to project points
|
||||||
glm::mat4 _ourModelViewProjectionMatrix;
|
glm::mat4 _ourModelViewProjectionMatrix;
|
||||||
};
|
};
|
||||||
|
using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_ViewFrustum_h
|
#endif // hifi_ViewFrustum_h
|
||||||
|
|
|
@ -69,6 +69,8 @@ void DeferredLightingEffect::init() {
|
||||||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||||
|
|
||||||
model::LightPointer lp = _allocatedLights[0];
|
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->setDirection(-glm::vec3(1.0f, 1.0f, 1.0f));
|
||||||
lp->setColor(glm::vec3(1.0f));
|
lp->setColor(glm::vec3(1.0f));
|
||||||
|
@ -541,10 +543,6 @@ void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const gl
|
||||||
light->setAmbientIntensity(ambientIntensity);
|
light->setAmbientIntensity(ambientIntensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
model::LightPointer DeferredLightingEffect::getGlobalLight() {
|
|
||||||
return _allocatedLights[_globalLights.front()];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
||||||
_skybox = skybox;
|
_skybox = skybox;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "model/Stage.h"
|
#include "model/Stage.h"
|
||||||
#include "model/Geometry.h"
|
#include "model/Geometry.h"
|
||||||
|
|
||||||
|
#include "LightStage.h"
|
||||||
|
|
||||||
class RenderArgs;
|
class RenderArgs;
|
||||||
struct LightLocations;
|
struct LightLocations;
|
||||||
using LightLocationsPtr = std::shared_ptr<LightLocations>;
|
using LightLocationsPtr = std::shared_ptr<LightLocations>;
|
||||||
|
@ -50,9 +52,11 @@ public:
|
||||||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||||
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
||||||
|
|
||||||
model::LightPointer getGlobalLight();
|
const LightStage& getLightStage() { return _lightStage; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LightStage _lightStage;
|
||||||
|
|
||||||
DeferredLightingEffect() = default;
|
DeferredLightingEffect() = default;
|
||||||
|
|
||||||
model::MeshPointer _spotLightMesh;
|
model::MeshPointer _spotLightMesh;
|
||||||
|
@ -72,26 +76,7 @@ private:
|
||||||
gpu::PipelinePointer _spotLight;
|
gpu::PipelinePointer _spotLight;
|
||||||
LightLocationsPtr _spotLightLocations;
|
LightLocationsPtr _spotLightLocations;
|
||||||
|
|
||||||
class PointLight {
|
using Lights = std::vector<model::LightPointer>;
|
||||||
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;
|
|
||||||
|
|
||||||
Lights _allocatedLights;
|
Lights _allocatedLights;
|
||||||
std::vector<int> _globalLights;
|
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