mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-05 19:09:23 -05:00
Feature/model lighting (#670)
* Fix NH texture and add lighting options * Add missing comma * Light sources: work in progress. * Add light sources * Remove unused values * Add types to documentation * Add light sources to various missions * Code cleanup based on review
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/lightsource.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/misc/invariants.h>
|
||||
@@ -52,6 +54,24 @@ namespace {
|
||||
"rendered in this object."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AmbientIntensityInfo = {
|
||||
"AmbientIntensity",
|
||||
"Ambient Intensity",
|
||||
"A multiplier for ambient lighting."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DiffuseIntensityInfo = {
|
||||
"DiffuseIntensity",
|
||||
"Diffuse Intensity",
|
||||
"A multiplier for diffuse lighting."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SpecularIntensityInfo = {
|
||||
"SpecularIntensity",
|
||||
"Specular Intensity",
|
||||
"A multiplier for specular lighting."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ShadingInfo = {
|
||||
"PerformShading",
|
||||
"Perform Shading",
|
||||
@@ -65,6 +85,12 @@ namespace {
|
||||
"This value specifies the model transform that is applied to the model before "
|
||||
"all other transformations are applied."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LightSourcesInfo = {
|
||||
"LightSources",
|
||||
"Light Sources",
|
||||
"A list of light sources that this model should accept light from."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -87,6 +113,24 @@ documentation::Documentation RenderableModel::Documentation() {
|
||||
Optional::Yes,
|
||||
TextureInfo.description
|
||||
},
|
||||
{
|
||||
AmbientIntensityInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
AmbientIntensityInfo.description
|
||||
},
|
||||
{
|
||||
DiffuseIntensityInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
DiffuseIntensityInfo.description
|
||||
},
|
||||
{
|
||||
SpecularIntensityInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
SpecularIntensityInfo.description
|
||||
},
|
||||
{
|
||||
ShadingInfo.identifier,
|
||||
new BoolVerifier,
|
||||
@@ -98,6 +142,18 @@ documentation::Documentation RenderableModel::Documentation() {
|
||||
new DoubleMatrix3Verifier,
|
||||
Optional::Yes,
|
||||
ModelTransformInfo.description
|
||||
},
|
||||
{
|
||||
LightSourcesInfo.identifier,
|
||||
new TableVerifier({
|
||||
{
|
||||
"*",
|
||||
new ReferencingVerifier("core_light_source"),
|
||||
Optional::Yes
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
LightSourcesInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -106,8 +162,12 @@ documentation::Documentation RenderableModel::Documentation() {
|
||||
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath(TextureInfo)
|
||||
, _ambientIntensity(AmbientIntensityInfo, 0.2, 0.0, 1.0)
|
||||
, _diffuseIntensity(DiffuseIntensityInfo, 1.0, 0.0, 1.0)
|
||||
, _specularIntensity(SpecularIntensityInfo, 1.0, 0.0, 1.0)
|
||||
, _performShading(ShadingInfo, true)
|
||||
, _modelTransform(ModelTransformInfo, glm::mat3(1.0))
|
||||
, _lightSourcePropertyOwner({ "LightSources", "Light Sources" })
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
@@ -134,22 +194,58 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
_modelTransform = dictionary.value<glm::dmat3>(ModelTransformInfo.identifier);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(AmbientIntensityInfo.identifier)) {
|
||||
_ambientIntensity = dictionary.value<float>(AmbientIntensityInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(DiffuseIntensityInfo.identifier)) {
|
||||
_diffuseIntensity = dictionary.value<float>(DiffuseIntensityInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(SpecularIntensityInfo.identifier)) {
|
||||
_specularIntensity = dictionary.value<float>(SpecularIntensityInfo.identifier);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(ShadingInfo.identifier)) {
|
||||
_performShading = dictionary.value<bool>(ShadingInfo.identifier);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LightSourcesInfo.identifier)) {
|
||||
const ghoul::Dictionary& lsDictionary =
|
||||
dictionary.value<ghoul::Dictionary>(LightSourcesInfo.identifier);
|
||||
|
||||
for (const std::string& k : lsDictionary.keys()) {
|
||||
std::unique_ptr<LightSource> lightSource = LightSource::createFromDictionary(
|
||||
lsDictionary.value<ghoul::Dictionary>(k)
|
||||
);
|
||||
_lightSourcePropertyOwner.addPropertySubOwner(lightSource.get());
|
||||
_lightSources.push_back(std::move(lightSource));
|
||||
}
|
||||
}
|
||||
|
||||
addPropertySubOwner(_lightSourcePropertyOwner);
|
||||
addPropertySubOwner(_geometry.get());
|
||||
|
||||
addProperty(_colorTexturePath);
|
||||
_colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this));
|
||||
|
||||
|
||||
addProperty(_ambientIntensity);
|
||||
addProperty(_diffuseIntensity);
|
||||
addProperty(_specularIntensity);
|
||||
addProperty(_performShading);
|
||||
}
|
||||
|
||||
RenderableModel::~RenderableModel() {}
|
||||
|
||||
bool RenderableModel::isReady() const {
|
||||
return _programObject && _texture;
|
||||
}
|
||||
|
||||
void RenderableModel::initialize() {
|
||||
for (const std::unique_ptr<LightSource>& ls : _lightSources) {
|
||||
ls->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableModel::initializeGL() {
|
||||
_programObject = BaseModule::ProgramObjectManager.requestProgramObject(
|
||||
ProgramName,
|
||||
@@ -161,21 +257,7 @@ void RenderableModel::initializeGL() {
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
_uniformCache.opacity = _programObject->uniformLocation("opacity");
|
||||
_uniformCache.directionToSunViewSpace = _programObject->uniformLocation(
|
||||
"directionToSunViewSpace"
|
||||
);
|
||||
_uniformCache.modelViewTransform = _programObject->uniformLocation(
|
||||
"modelViewTransform"
|
||||
);
|
||||
_uniformCache.projectionTransform = _programObject->uniformLocation(
|
||||
"projectionTransform"
|
||||
);
|
||||
_uniformCache.performShading = _programObject->uniformLocation(
|
||||
"performShading"
|
||||
);
|
||||
_uniformCache.texture = _programObject->uniformLocation("texture1");
|
||||
updateUniformCache();
|
||||
|
||||
loadTexture();
|
||||
|
||||
@@ -213,15 +295,33 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
|
||||
const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() *
|
||||
modelTransform;
|
||||
|
||||
const glm::vec3 directionToSun = glm::normalize(
|
||||
_sunPos - data.modelTransform.translation
|
||||
);
|
||||
const glm::vec3 directionToSunViewSpace =
|
||||
glm::normalize(glm::mat3(data.camera.combinedViewMatrix()) * directionToSun);
|
||||
int nLightSources = 0;
|
||||
_lightIntensitiesBuffer.resize(_lightSources.size());
|
||||
_lightDirectionsViewSpaceBuffer.resize(_lightSources.size());
|
||||
for (const std::unique_ptr<LightSource>& lightSource : _lightSources) {
|
||||
if (!lightSource->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
_lightIntensitiesBuffer[nLightSources] = lightSource->intensity();
|
||||
_lightDirectionsViewSpaceBuffer[nLightSources] =
|
||||
lightSource->directionViewSpace(data);
|
||||
|
||||
++nLightSources;
|
||||
}
|
||||
|
||||
_programObject->setUniform(
|
||||
_uniformCache.directionToSunViewSpace,
|
||||
directionToSunViewSpace
|
||||
_uniformCache.nLightSources,
|
||||
nLightSources
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.lightIntensities,
|
||||
_lightIntensitiesBuffer.data(),
|
||||
nLightSources
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.lightDirectionsViewSpace,
|
||||
_lightDirectionsViewSpaceBuffer.data(),
|
||||
nLightSources
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.modelViewTransform,
|
||||
@@ -231,6 +331,18 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
|
||||
_uniformCache.projectionTransform,
|
||||
data.camera.projectionMatrix()
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.ambientIntensity,
|
||||
_ambientIntensity
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.diffuseIntensity,
|
||||
_diffuseIntensity
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.specularIntensity,
|
||||
_specularIntensity
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.performShading,
|
||||
_performShading
|
||||
@@ -252,26 +364,41 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
|
||||
void RenderableModel::update(const UpdateData&) {
|
||||
if (_programObject->isDirty()) {
|
||||
_programObject->rebuildFromFile();
|
||||
|
||||
_uniformCache.opacity = _programObject->uniformLocation("opacity");
|
||||
_uniformCache.directionToSunViewSpace = _programObject->uniformLocation(
|
||||
"directionToSunViewSpace"
|
||||
);
|
||||
_uniformCache.modelViewTransform = _programObject->uniformLocation(
|
||||
"modelViewTransform"
|
||||
);
|
||||
_uniformCache.projectionTransform = _programObject->uniformLocation(
|
||||
"projectionTransform"
|
||||
);
|
||||
_uniformCache.performShading = _programObject->uniformLocation(
|
||||
"performShading"
|
||||
);
|
||||
_uniformCache.texture = _programObject->uniformLocation("texture1");
|
||||
updateUniformCache();
|
||||
}
|
||||
}
|
||||
|
||||
_sunPos = OsEng.renderEngine().scene()->sceneGraphNode(
|
||||
"SolarSystemBarycenter"
|
||||
)->worldPosition();
|
||||
|
||||
void RenderableModel::updateUniformCache() {
|
||||
_uniformCache.opacity = _programObject->uniformLocation("opacity");
|
||||
_uniformCache.nLightSources = _programObject->uniformLocation(
|
||||
"nLightSources"
|
||||
);
|
||||
_uniformCache.lightDirectionsViewSpace = _programObject->uniformLocation(
|
||||
"lightDirectionsViewSpace"
|
||||
);
|
||||
_uniformCache.lightIntensities = _programObject->uniformLocation(
|
||||
"lightIntensities"
|
||||
);
|
||||
_uniformCache.modelViewTransform = _programObject->uniformLocation(
|
||||
"modelViewTransform"
|
||||
);
|
||||
_uniformCache.projectionTransform = _programObject->uniformLocation(
|
||||
"projectionTransform"
|
||||
);
|
||||
_uniformCache.performShading = _programObject->uniformLocation(
|
||||
"performShading"
|
||||
);
|
||||
_uniformCache.ambientIntensity = _programObject->uniformLocation(
|
||||
"ambientIntensity"
|
||||
);
|
||||
_uniformCache.diffuseIntensity = _programObject->uniformLocation(
|
||||
"diffuseIntensity"
|
||||
);
|
||||
_uniformCache.specularIntensity = _programObject->uniformLocation(
|
||||
"specularIntensity"
|
||||
);
|
||||
_uniformCache.texture = _programObject->uniformLocation("texture1");
|
||||
}
|
||||
|
||||
void RenderableModel::loadTexture() {
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
struct UpdateData;
|
||||
class LightSource;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace modelgeometry { class ModelGeometry; }
|
||||
@@ -50,7 +51,9 @@ namespace modelgeometry { class ModelGeometry; }
|
||||
class RenderableModel : public Renderable {
|
||||
public:
|
||||
RenderableModel(const ghoul::Dictionary& dictionary);
|
||||
~RenderableModel();
|
||||
|
||||
void initialize() override;
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
|
||||
@@ -65,19 +68,32 @@ protected:
|
||||
void loadTexture();
|
||||
|
||||
private:
|
||||
void updateUniformCache();
|
||||
|
||||
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
|
||||
properties::FloatProperty _ambientIntensity;
|
||||
properties::FloatProperty _diffuseIntensity;
|
||||
properties::FloatProperty _specularIntensity;
|
||||
|
||||
properties::BoolProperty _performShading;
|
||||
properties::Mat3Property _modelTransform;
|
||||
|
||||
ghoul::opengl::ProgramObject* _programObject = nullptr;
|
||||
UniformCache(opacity, directionToSunViewSpace, modelViewTransform,
|
||||
projectionTransform, performShading, texture) _uniformCache;
|
||||
UniformCache(opacity, nLightSources, lightDirectionsViewSpace, lightIntensities,
|
||||
modelViewTransform, projectionTransform, performShading, texture,
|
||||
ambientIntensity, diffuseIntensity, specularIntensity) _uniformCache;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
std::vector<std::unique_ptr<LightSource>> _lightSources;
|
||||
|
||||
glm::dvec3 _sunPos;
|
||||
// Buffers for uniform uploading
|
||||
std::vector<float> _lightIntensitiesBuffer;
|
||||
std::vector<glm::vec3> _lightDirectionsViewSpaceBuffer;
|
||||
|
||||
properties::PropertyOwner _lightSourcePropertyOwner;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user