mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-29 23:39:26 -05:00
Merged develop in NewAtmosphere.
This commit is contained in:
@@ -136,9 +136,13 @@ void BaseModule::internalInitialize() {
|
||||
|
||||
std::vector<Documentation> BaseModule::documentations() const {
|
||||
return {
|
||||
SpiceRotation::Documentation(),
|
||||
StaticScale::Documentation(),
|
||||
StaticTranslation::Documentation(),
|
||||
SpiceTranslation::Documentation()
|
||||
SpiceTranslation::Documentation(),
|
||||
RenderableRings::Documentation(),
|
||||
modelgeometry::ModelGeometry::Documentation(),
|
||||
planetgeometry::PlanetGeometry::Documentation()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/base/rendering/modelgeometry.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -35,59 +37,70 @@ namespace {
|
||||
const int8_t CurrentCacheVersion = 3;
|
||||
const std::string keyType = "Type";
|
||||
const std::string keyName = "Name";
|
||||
const std::string keySize = "Magnification";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace modelgeometry {
|
||||
|
||||
Documentation ModelGeometry::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Model Geometry",
|
||||
"base_geometry_model",
|
||||
{
|
||||
{
|
||||
keyType,
|
||||
new StringVerifier,
|
||||
"The type of the Model Geometry that should be generated",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
keyGeomModelFile,
|
||||
new StringVerifier,
|
||||
"The file that should be loaded in this ModelGeometry. The file can "
|
||||
"contain filesystem tokens or can be specified relatively to the "
|
||||
"location of the .mod file.",
|
||||
Optional::No
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
std::string geometryType;
|
||||
const bool success = dictionary.getValue(
|
||||
keyType, geometryType);
|
||||
if (!success) {
|
||||
LERROR("ModelGeometry did not contain a correct value of the key '"
|
||||
<< keyType << "'");
|
||||
return nullptr;
|
||||
if (!dictionary.hasKeyAndValue<std::string>(keyType)) {
|
||||
throw ghoul::RuntimeError("Dictionary did not contain a key 'Type'");
|
||||
}
|
||||
ghoul::TemplateFactory<ModelGeometry>* factory
|
||||
= FactoryManager::ref().factory<ModelGeometry>();
|
||||
|
||||
std::string geometryType = dictionary.value<std::string>(keyType);
|
||||
auto factory = FactoryManager::ref().factory<ModelGeometry>();
|
||||
|
||||
ModelGeometry* result = factory->create(geometryType, dictionary);
|
||||
if (result == nullptr) {
|
||||
LERROR("Failed to create a ModelGeometry object of type '" << geometryType
|
||||
<< "'");
|
||||
return nullptr;
|
||||
throw ghoul::RuntimeError(
|
||||
"Failed to create a ModelGeometry object of type '" + geometryType + "'"
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
|
||||
: _parent(nullptr)
|
||||
, _magnification("magnification", "Magnification", 1.f, 0.f, 10.f)
|
||||
, _mode(GL_TRIANGLES)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"ModelGeometry"
|
||||
);
|
||||
|
||||
setName("ModelGeometry");
|
||||
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
ghoul_assert(success, "Name tag was not present");
|
||||
|
||||
if (dictionary.hasKeyAndValue<double>(keySize))
|
||||
_magnification = static_cast<float>(dictionary.value<double>(keySize));
|
||||
|
||||
success = dictionary.getValue(keyGeomModelFile, _file);
|
||||
if (!success) {
|
||||
LERROR("Geometric Model file of '" << name << "' did not provide a key '"
|
||||
<< keyGeomModelFile << "'");
|
||||
}
|
||||
_file = FileSys.absolutePath(_file);
|
||||
|
||||
if (!FileSys.fileExists(_file, ghoul::filesystem::FileSystem::RawPath::Yes))
|
||||
LERROR("Could not load the geometric model file '" << _file << "': File not found");
|
||||
|
||||
|
||||
addProperty(_magnification);
|
||||
_file = absPath(dictionary.value<std::string>(keyGeomModelFile));
|
||||
}
|
||||
|
||||
double ModelGeometry::boundingRadius() const {
|
||||
@@ -273,7 +286,6 @@ bool ModelGeometry::getIndices(std::vector<int>* indexList) {
|
||||
}
|
||||
|
||||
void ModelGeometry::setUniforms(ghoul::opengl::ProgramObject& program) {
|
||||
program.setUniform("_magnification", _magnification);
|
||||
}
|
||||
|
||||
} // namespace modelgeometry
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/scalarproperty.h>
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
@@ -59,13 +60,14 @@ public:
|
||||
|
||||
virtual void setUniforms(ghoul::opengl::ProgramObject& program);
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
protected:
|
||||
Renderable* _parent;
|
||||
|
||||
bool loadObj(const std::string& filename);
|
||||
bool loadCachedFile(const std::string& filename);
|
||||
bool saveCachedFile(const std::string& filename);
|
||||
properties::FloatProperty _magnification;
|
||||
|
||||
GLuint _vaoID;
|
||||
GLuint _vbo;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <modules/base/rendering/planetgeometry.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "PlanetGeometry";
|
||||
const std::string KeyType = "Type";
|
||||
@@ -33,22 +35,38 @@ namespace {
|
||||
namespace openspace {
|
||||
namespace planetgeometry {
|
||||
|
||||
PlanetGeometry* PlanetGeometry::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
std::string geometryType;
|
||||
const bool success = dictionary.getValue(KeyType, geometryType);
|
||||
if (!success) {
|
||||
LERROR("PlanetGeometry did not contain a correct value of the key '"
|
||||
<< KeyType << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ghoul::TemplateFactory<PlanetGeometry>* factory
|
||||
= FactoryManager::ref().factory<PlanetGeometry>();
|
||||
Documentation PlanetGeometry::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Planet Geometry",
|
||||
"base_geometry_planet",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringVerifier,
|
||||
"The type of the PlanetGeometry that will can be constructed.",
|
||||
Optional::No
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
PlanetGeometry* PlanetGeometry::createFromDictionary(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"PlanetGeometry"
|
||||
);
|
||||
|
||||
std::string geometryType = dictionary.value<std::string>(KeyType);
|
||||
auto factory = FactoryManager::ref().factory<PlanetGeometry>();
|
||||
|
||||
PlanetGeometry* result = factory->create(geometryType, dictionary);
|
||||
if (result == nullptr) {
|
||||
LERROR("Failed to create a PlanetGeometry object of type '" << geometryType
|
||||
<< "'");
|
||||
return nullptr;
|
||||
throw ghoul::RuntimeError(
|
||||
"Failed to create a PlanetGeometry object of type '" + geometryType + "'"
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
#define __PLANETGEOMETRY_H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <modules/base/rendering/renderableplanet.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace openspace {
|
||||
class Renderable;
|
||||
|
||||
namespace planetgeometry {
|
||||
|
||||
@@ -43,6 +44,8 @@ public:
|
||||
virtual void deinitialize();
|
||||
virtual void render() = 0;
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
protected:
|
||||
Renderable* _parent;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,38 +66,6 @@ public:
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
// See: Precomputed Atmospheric Scattering from Bruneton et al.
|
||||
// for explanation of the following parameters.
|
||||
|
||||
const unsigned int TRANSMITTANCE_TABLE_WIDTH = 256;
|
||||
const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 64;
|
||||
|
||||
const unsigned int IRRADIANCE_TABLE_WIDTH = 64;
|
||||
const unsigned int IRRADIANCE_TABLE_HEIGHT = 16;
|
||||
|
||||
const unsigned int DELTA_E_TABLE_WIDTH = 64;
|
||||
const unsigned int DELTA_E_TABLE_HEIGHT = 16;
|
||||
|
||||
|
||||
/*const unsigned int TRANSMITTANCE_TABLE_WIDTH = 512;
|
||||
const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 128;
|
||||
|
||||
const unsigned int IRRADIANCE_TABLE_WIDTH = 128;
|
||||
const unsigned int IRRADIANCE_TABLE_HEIGHT = 32;
|
||||
|
||||
const unsigned int DELTA_E_TABLE_WIDTH = 128;
|
||||
const unsigned int DELTA_E_TABLE_HEIGHT = 32;*/
|
||||
|
||||
const unsigned int R_SAMPLES = 32;
|
||||
const unsigned int MU_SAMPLES = 128;
|
||||
const unsigned int MU_S_SAMPLES = 32;
|
||||
const unsigned int NU_SAMPLES = 8;
|
||||
|
||||
/*const unsigned int R_SAMPLES = 64;
|
||||
const unsigned int MU_SAMPLES = 256;
|
||||
const unsigned int MU_S_SAMPLES = 64;
|
||||
const unsigned int NU_SAMPLES = 16;*/
|
||||
|
||||
public:
|
||||
explicit RenderablePlanet(const ghoul::Dictionary& dictionary);
|
||||
~RenderablePlanet();
|
||||
@@ -111,98 +79,22 @@ public:
|
||||
|
||||
protected:
|
||||
void loadTexture();
|
||||
|
||||
private:
|
||||
void loadComputationPrograms();
|
||||
void unloadComputationPrograms();
|
||||
void createComputationTextures();
|
||||
void deleteComputationTextures();
|
||||
void deleteUnusedComputationTextures();
|
||||
void updateAtmosphereParameters();
|
||||
void loadAtmosphereDataIntoShaderProgram(std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg);
|
||||
void executeCalculations(const GLuint vao, const GLenum drawBuffers[1], const GLsizei vertexSize);
|
||||
void preCalculateAtmosphereParam();
|
||||
void resetAtmosphereTextures(const GLuint vao, const GLenum drawBuffers[1], const GLsizei vertexSize);
|
||||
void createAtmosphereFBO();
|
||||
void createRenderQuad(GLuint * vao, GLuint * vbo, const GLfloat size);
|
||||
void renderQuadForCalc(const GLuint vao, const GLsizei size);
|
||||
void step3DTexture(std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg,
|
||||
const int layer, const bool doCalc = true);
|
||||
void saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName,
|
||||
const int width, const int height) const;
|
||||
void checkFrameBufferState(const std::string & codePosition) const;
|
||||
|
||||
private:
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _nightTexturePath;
|
||||
properties::StringProperty _heightMapTexturePath;
|
||||
properties::StringProperty _cloudsTexturePath;
|
||||
properties::StringProperty _reflectanceTexturePath;
|
||||
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaEProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaJProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _atmosphereProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deferredAtmosphereProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _cleanTextureProgramObject;
|
||||
ghoul::opengl::TextureUnit _dummyTextureUnit;
|
||||
ghoul::opengl::TextureUnit _transmittanceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _irradianceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _inScatteringTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _deltaETableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _deltaSRayleighTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _deltaSMieTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _deltaJTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _atmosphereTextureUnit;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _nightTexture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _reflectanceTexture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _heightMapTexture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _cloudsTexture;
|
||||
GLuint _transmittanceTableTexture;
|
||||
GLuint _irradianceTableTexture;
|
||||
GLuint _inScatteringTableTexture;
|
||||
GLuint _deltaETableTexture;
|
||||
GLuint _deltaSRayleighTableTexture;
|
||||
GLuint _deltaSMieTableTexture;
|
||||
GLuint _deltaJTableTexture;
|
||||
GLuint _dummyTexture;
|
||||
GLuint _atmosphereTexture;
|
||||
GLuint _atmosphereDepthTexture;
|
||||
GLuint _atmosphereFBO;
|
||||
GLuint _atmosphereRenderVAO;
|
||||
GLuint _atmosphereRenderVBO;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _nightTexture;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _heightMapTexture;
|
||||
|
||||
properties::FloatProperty _heightExaggeration;
|
||||
|
||||
planetgeometry::PlanetGeometry* _geometry;
|
||||
planetgeometry::PlanetGeometry* _atmosphereGeometry;
|
||||
properties::BoolProperty _performShading;
|
||||
properties::IntProperty _rotation;
|
||||
|
||||
|
||||
// ATMOSPHERE PROPERTIES
|
||||
properties::FloatProperty _atmosphereHeightP;
|
||||
properties::FloatProperty _groundAverageReflectanceP;
|
||||
properties::FloatProperty _rayleighHeightScaleP;
|
||||
properties::FloatProperty _mieHeightScaleP;
|
||||
properties::FloatProperty _mieScatteringCoefficientP;
|
||||
properties::FloatProperty _mieScatteringExtinctionPropCoefficientP;
|
||||
properties::FloatProperty _mieAsymmetricFactorGP;
|
||||
properties::FloatProperty _sunIntensityP;
|
||||
|
||||
|
||||
// DEBUG Properties:
|
||||
properties::BoolProperty _saveDeferredFramebuffer;
|
||||
|
||||
|
||||
float _alpha;
|
||||
std::vector< ShadowConf > _shadowConfArray;
|
||||
float _planetRadius;
|
||||
@@ -211,32 +103,12 @@ private:
|
||||
std::string _frame;
|
||||
std::string _target;
|
||||
bool _hasNightTexture;
|
||||
bool _hasReflectanceTexture;
|
||||
bool _hasHeightTexture;
|
||||
bool _hasCloudsTexture;
|
||||
bool _shadowEnabled;
|
||||
double _time;
|
||||
|
||||
// Atmosphere Data
|
||||
bool _atmosphereCalculated;
|
||||
bool _atmosphereEnabled;
|
||||
float _atmosphereRadius;
|
||||
float _atmospherePlanetRadius;
|
||||
float _planetAverageGroundReflectance;
|
||||
float _rayleighHeightScale;
|
||||
float _mieHeightScale;
|
||||
float _miePhaseConstant;
|
||||
float _sunRadianceIntensity;
|
||||
glm::vec3 _mieExtinctionCoeff;
|
||||
glm::vec3 _rayleighScatteringCoeff;
|
||||
glm::vec3 _mieScatteringCoeff;
|
||||
|
||||
|
||||
bool tempPic;
|
||||
|
||||
unsigned int count;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
|
||||
#include <modules/base/rendering/renderablerings.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
@@ -35,25 +36,56 @@
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableRings";
|
||||
|
||||
const std::string KeySize = "Size";
|
||||
const std::string KeyTexture = "Texture";
|
||||
const std::string KeyBody = "Body";
|
||||
const std::string KeyFrame = "Frame";
|
||||
const std::string KeyOrientation = "Orientation";
|
||||
const std::string KeySize = "Size";
|
||||
const std::string KeyOffset = "Offset";
|
||||
const std::string KeyNightFactor = "NightFactor";
|
||||
const std::string KeyTransparency = "Transparency";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Documentation RenderableRings::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Renderable Rings",
|
||||
"base_renderable_rings",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("RenderableRings"),
|
||||
"",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyTexture,
|
||||
new StringVerifier,
|
||||
"The one dimensional texture that is used for both sides of the ring.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeySize,
|
||||
new DoubleVerifier,
|
||||
"The radius of the rings in meters.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyOffset,
|
||||
new DoubleVector2Verifier,
|
||||
"The offset that is used to limit the width of the rings. Each of the "
|
||||
"two values is a value between 0 and 1, where 0 is the center of the "
|
||||
"ring and 1 is the maximum extent at the radius. If this value is, for "
|
||||
"example {0.5, 1.0}, the ring is only shown between radius/2 and radius. "
|
||||
"It defaults to {0.0, 1.0}.",
|
||||
Optional::Yes
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
RenderableRings::RenderableRings(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _texturePath("texture", "Texture")
|
||||
, _size("size", "Size", glm::vec2(1.f, 1.f), glm::vec2(0.f), glm::vec2(1.f, 25.f))
|
||||
, _offset("offset", "Texture Offset", glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f))
|
||||
, _size("size", "Size", 1.f, 0.f, std::pow(1.f, 25.f))
|
||||
, _offset("offset", "Offset", glm::vec2(0, 1.f), glm::vec2(0.f), glm::vec2(1.f))
|
||||
, _nightFactor("nightFactor", "Night Factor", 0.33f, 0.f, 1.f)
|
||||
, _transparency("transparency", "Transparency", 0.15f, 0.f, 1.f)
|
||||
, _shader(nullptr)
|
||||
@@ -63,62 +95,36 @@ RenderableRings::RenderableRings(const ghoul::Dictionary& dictionary)
|
||||
, _quad(0)
|
||||
, _vertexPositionBuffer(0)
|
||||
, _planeIsDirty(false)
|
||||
, _hasSunPosition(false)
|
||||
{
|
||||
glm::vec2 size;
|
||||
dictionary.getValue(KeySize, size);
|
||||
_size = size;
|
||||
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyBody)) {
|
||||
_body = dictionary.value<std::string>(KeyBody);
|
||||
_hasSunPosition = true;
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyFrame)) {
|
||||
_frame = dictionary.value<std::string>(KeyFrame);
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<glm::mat3>(KeyOrientation)) {
|
||||
_orientation = dictionary.value<glm::mat3>(KeyOrientation);
|
||||
}
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableRings"
|
||||
);
|
||||
|
||||
_size = dictionary.value<double>(KeySize);
|
||||
setBoundingSphere(PowerScaledScalar::CreatePSS(_size));
|
||||
addProperty(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
|
||||
_texturePath = absPath(dictionary.value<std::string>(KeyTexture));
|
||||
_textureFile = std::make_unique<File>(_texturePath);
|
||||
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyTexture)) {
|
||||
_texturePath = absPath(dictionary.value<std::string>(KeyTexture));
|
||||
_textureFile = std::make_unique<ghoul::filesystem::File>(_texturePath);
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<glm::vec2>(KeyOffset)) {
|
||||
glm::vec2 off = dictionary.value<glm::vec2>(KeyOffset);
|
||||
_offset = off;
|
||||
_offset = dictionary.value<glm::vec2>(KeyOffset);
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<float>(KeyNightFactor)) {
|
||||
float v = dictionary.value<float>(KeyNightFactor);
|
||||
_nightFactor = v;
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<float>(KeyTransparency)) {
|
||||
float v = dictionary.value<float>(KeyTransparency);
|
||||
_transparency = v;
|
||||
}
|
||||
|
||||
addProperty(_offset);
|
||||
|
||||
addProperty(_size);
|
||||
_size.onChange([&](){ _planeIsDirty = true; });
|
||||
|
||||
addProperty(_texturePath);
|
||||
_texturePath.onChange([&](){ loadTexture(); });
|
||||
|
||||
_textureFile->setCallback(
|
||||
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
|
||||
);
|
||||
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
|
||||
addProperty(_nightFactor);
|
||||
|
||||
addProperty(_transparency);
|
||||
|
||||
setBoundingSphere(_size.value());
|
||||
}
|
||||
|
||||
bool RenderableRings::isReady() const {
|
||||
@@ -132,18 +138,14 @@ bool RenderableRings::initialize() {
|
||||
"${MODULE_BASE}/shaders/rings_vs.glsl",
|
||||
"${MODULE_BASE}/shaders/rings_fs.glsl"
|
||||
);
|
||||
if (!_shader)
|
||||
return false;
|
||||
|
||||
_shader->setIgnoreUniformLocationError(
|
||||
ghoul::opengl::ProgramObject::IgnoreError::Yes
|
||||
);
|
||||
}
|
||||
|
||||
glGenVertexArrays(1, &_quad); // generate array
|
||||
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
|
||||
glGenVertexArrays(1, &_quad);
|
||||
glGenBuffers(1, &_vertexPositionBuffer);
|
||||
createPlane();
|
||||
|
||||
loadTexture();
|
||||
|
||||
return isReady();
|
||||
@@ -159,11 +161,8 @@ bool RenderableRings::deinitialize() {
|
||||
_textureFile = nullptr;
|
||||
_texture = nullptr;
|
||||
|
||||
RenderEngine& renderEngine = OsEng.renderEngine();
|
||||
if (_shader) {
|
||||
renderEngine.removeRenderProgram(_shader);
|
||||
_shader = nullptr;
|
||||
}
|
||||
OsEng.renderEngine().removeRenderProgram(_shader);
|
||||
_shader = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -171,18 +170,27 @@ bool RenderableRings::deinitialize() {
|
||||
void RenderableRings::render(const RenderData& data) {
|
||||
_shader->activate();
|
||||
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", glm::mat4(_orientation * _state));
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
|
||||
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
_shader->setUniform(
|
||||
"modelViewProjectionTransform",
|
||||
data.camera.projectionMatrix() * glm::mat4(modelViewTransform)
|
||||
);
|
||||
_shader->setUniform("textureOffset", _offset);
|
||||
_shader->setUniform("transparency", _transparency);
|
||||
|
||||
_shader->setUniform("hasSunPosition", _hasSunPosition);
|
||||
if (_hasSunPosition) {
|
||||
_shader->setUniform("_nightFactor", _nightFactor);
|
||||
_shader->setUniform("sunPosition", _sunPosition);
|
||||
}
|
||||
_shader->setUniform("_nightFactor", _nightFactor);
|
||||
_shader->setUniform(
|
||||
"sunPosition",
|
||||
_sunPosition
|
||||
);
|
||||
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
setPscUniforms(*_shader, data.camera, data.position);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
@@ -212,37 +220,26 @@ void RenderableRings::update(const UpdateData& data) {
|
||||
loadTexture();
|
||||
_textureIsDirty = false;
|
||||
}
|
||||
|
||||
if (!_frame.empty()) {
|
||||
_state = SpiceManager::ref().positionTransformMatrix(_frame, "GALACTIC", data.time);
|
||||
}
|
||||
|
||||
if (!_body.empty()) {
|
||||
double lt;
|
||||
_sunPosition = SpiceManager::ref().targetPosition(
|
||||
"SUN",
|
||||
_body,
|
||||
"GALACTIC",
|
||||
{},
|
||||
data.time,
|
||||
lt
|
||||
);
|
||||
}
|
||||
|
||||
_sunPosition = OsEng.renderEngine().scene()->sceneGraphNode("Sun")->worldPosition() -
|
||||
data.modelTransform.translation;
|
||||
}
|
||||
|
||||
void RenderableRings::loadTexture() {
|
||||
if (_texturePath.value() != "") {
|
||||
std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath));
|
||||
std::unique_ptr<ghoul::opengl::Texture> texture =
|
||||
ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath));
|
||||
|
||||
if (texture) {
|
||||
LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'");
|
||||
LDEBUGC(
|
||||
"RenderableRings",
|
||||
"Loaded texture from '" << absPath(_texturePath) << "'"
|
||||
);
|
||||
_texture = std::move(texture);
|
||||
|
||||
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
|
||||
// _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
_texture->uploadTexture();
|
||||
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
|
||||
|
||||
_textureFile = std::make_unique<ghoul::filesystem::File>(_texturePath);
|
||||
_textureFile->setCallback(
|
||||
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
|
||||
@@ -252,28 +249,45 @@ void RenderableRings::loadTexture() {
|
||||
}
|
||||
|
||||
void RenderableRings::createPlane() {
|
||||
// ============================
|
||||
// GEOMETRY (quad)
|
||||
// ============================
|
||||
const GLfloat size = _size.value()[0];
|
||||
const GLfloat w = _size.value()[1];
|
||||
const GLfloat vertex_data[] = {
|
||||
// x y z w s t
|
||||
-size, -size, 0.f, w, 0.f, 0.f,
|
||||
size, size, 0.f, w, 1.f, 1.f,
|
||||
-size, size, 0.f, w, 0.f, 1.f,
|
||||
-size, -size, 0.f, w, 0.f, 0.f,
|
||||
size, -size, 0.f, w, 1.f, 0.f,
|
||||
size, size, 0.f, w, 1.f, 1.f,
|
||||
const GLfloat size = _size.value();
|
||||
|
||||
struct VertexData {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
GLfloat s;
|
||||
GLfloat t;
|
||||
};
|
||||
|
||||
VertexData data[] = {
|
||||
-size, -size, 0.f, 0.f,
|
||||
size, size, 1.f, 1.f,
|
||||
-size, size, 0.f, 1.f,
|
||||
-size, -size, 0.f, 0.f,
|
||||
size, -size, 1.f, 0.f,
|
||||
size, size, 1.f, 1.f,
|
||||
};
|
||||
|
||||
glBindVertexArray(_quad); // bind array
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glBindVertexArray(_quad);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(VertexData),
|
||||
reinterpret_cast<void*>(0)
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(VertexData),
|
||||
reinterpret_cast<void*>(offsetof(VertexData, s))
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
@@ -54,12 +55,14 @@ public:
|
||||
void render(const RenderData& data) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
private:
|
||||
void loadTexture();
|
||||
void createPlane();
|
||||
|
||||
properties::StringProperty _texturePath;
|
||||
properties::Vec2Property _size;
|
||||
properties::FloatProperty _size;
|
||||
properties::Vec2Property _offset;
|
||||
properties::FloatProperty _nightFactor;
|
||||
properties::FloatProperty _transparency;
|
||||
@@ -72,14 +75,8 @@ private:
|
||||
GLuint _quad;
|
||||
GLuint _vertexPositionBuffer;
|
||||
bool _planeIsDirty;
|
||||
|
||||
std::string _frame;
|
||||
glm::mat3 _orientation;
|
||||
glm::mat3 _state;
|
||||
|
||||
std::string _body;
|
||||
|
||||
glm::vec3 _sunPosition;
|
||||
bool _hasSunPosition;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#include <modules/base/rendering/renderablesphere.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
@@ -122,7 +121,7 @@ bool RenderableSphere::initialize() {
|
||||
RenderEngine& renderEngine = OsEng.renderEngine();
|
||||
_shader = renderEngine.buildRenderProgram("Sphere",
|
||||
"${MODULE_BASE}/shaders/sphere_vs.glsl",
|
||||
"${MODULES}/base/shaders/sphere_fs.glsl");
|
||||
"${MODULE_BASE}/shaders/sphere_fs.glsl");
|
||||
if (!_shader)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -205,6 +205,7 @@ void RenderableStars::render(const RenderData& data) {
|
||||
_program->setUniform("alphaValue", _alphaValue);
|
||||
_program->setUniform("scaleFactor", _scaleFactor);
|
||||
_program->setUniform("minBillboardSize", _minBillboardSize);
|
||||
_program->setUniform("screenSize", glm::vec2(OsEng.renderEngine().renderingResolution()));
|
||||
|
||||
setPscUniforms(*_program.get(), data.camera, data.position);
|
||||
_program->setUniform("scaling", scaling);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <modules/base/rotation/spicerotation.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
@@ -38,56 +40,93 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
|
||||
: _sourceFrame("")
|
||||
, _destinationFrame("")
|
||||
, _rotationMatrix(1.0)
|
||||
, _kernelsLoadedSuccessfully(true)
|
||||
{
|
||||
const bool hasSourceFrame = dictionary.getValue(KeySourceFrame, _sourceFrame);
|
||||
if (!hasSourceFrame)
|
||||
LERROR("SpiceRotation does not contain the key '" << KeySourceFrame << "'");
|
||||
|
||||
const bool hasDestinationFrame = dictionary.getValue(KeyDestinationFrame, _destinationFrame);
|
||||
if (!hasDestinationFrame)
|
||||
LERROR("SpiceRotation does not contain the key '" << KeyDestinationFrame << "'");
|
||||
|
||||
ghoul::Dictionary kernels;
|
||||
dictionary.getValue(KeyKernels, kernels);
|
||||
for (size_t i = 1; i <= kernels.size(); ++i) {
|
||||
std::string kernel;
|
||||
bool success = kernels.getValue(std::to_string(i), kernel);
|
||||
if (!success)
|
||||
LERROR("'" << KeyKernels << "' has to be an array-style table");
|
||||
|
||||
try {
|
||||
SpiceManager::ref().loadKernel(kernel);
|
||||
_kernelsLoadedSuccessfully = true;
|
||||
Documentation SpiceRotation::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
return {
|
||||
"Spice Rotation",
|
||||
"base_transform_rotation_spice",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("SpiceRotation"),
|
||||
"",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeySourceFrame,
|
||||
new StringAnnotationVerifier("A valid SPICE NAIF name or integer"),
|
||||
"The source frame that is used as the basis for the coordinate "
|
||||
"transformation. This has to be a valid SPICE name.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyDestinationFrame,
|
||||
new StringAnnotationVerifier("A valid SPICE NAIF name or integer"),
|
||||
"The destination frame that is used for the coordinate transformation. "
|
||||
"This has to be a valid SPICE name.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyKernels,
|
||||
new OrVerifier(
|
||||
new TableVerifier({
|
||||
{ "*", new StringVerifier }
|
||||
}),
|
||||
new StringVerifier
|
||||
),
|
||||
"A single kernel or list of kernels that this SpiceTranslation depends "
|
||||
"on. All provided kernels will be loaded before any other operation is "
|
||||
"performed.",
|
||||
Optional::Yes
|
||||
}
|
||||
}
|
||||
catch (const SpiceManager::SpiceException& e) {
|
||||
LERROR("Could not load SPICE kernel: " << e.what());
|
||||
_kernelsLoadedSuccessfully = false;
|
||||
};
|
||||
}
|
||||
|
||||
SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
|
||||
: _sourceFrame("source", "Source", "")
|
||||
, _destinationFrame("destination", "Destination", "")
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"SpiceRotation"
|
||||
);
|
||||
|
||||
_sourceFrame = dictionary.value<std::string>(KeySourceFrame);
|
||||
_destinationFrame = dictionary.value<std::string>(KeyDestinationFrame);
|
||||
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyKernels)) {
|
||||
SpiceManager::ref().loadKernel(dictionary.value<std::string>(KeyKernels));
|
||||
}
|
||||
else if (dictionary.hasKeyAndValue<ghoul::Dictionary>(KeyKernels)) {
|
||||
ghoul::Dictionary kernels = dictionary.value<ghoul::Dictionary>(KeyKernels);
|
||||
for (size_t i = 1; i <= kernels.size(); ++i) {
|
||||
if (!kernels.hasKeyAndValue<std::string>(std::to_string(i))) {
|
||||
throw ghoul::RuntimeError("Kernels has to be an array-style table");
|
||||
}
|
||||
|
||||
std::string kernel = kernels.value<std::string>(std::to_string(i));
|
||||
SpiceManager::ref().loadKernel(kernel);
|
||||
}
|
||||
}
|
||||
|
||||
addProperty(_sourceFrame);
|
||||
addProperty(_destinationFrame);
|
||||
}
|
||||
|
||||
const glm::dmat3& SpiceRotation::matrix() const {
|
||||
return _rotationMatrix;
|
||||
}
|
||||
|
||||
void SpiceRotation::update(const UpdateData& data) {
|
||||
if (!_kernelsLoadedSuccessfully)
|
||||
return;
|
||||
try {
|
||||
_rotationMatrix = SpiceManager::ref().positionTransformMatrix(
|
||||
_matrix = SpiceManager::ref().positionTransformMatrix(
|
||||
_sourceFrame,
|
||||
_destinationFrame,
|
||||
data.time);
|
||||
data.time
|
||||
);
|
||||
}
|
||||
catch (const ghoul::RuntimeError&) {
|
||||
// In case of missing coverage
|
||||
_rotationMatrix = glm::dmat3(1);
|
||||
_matrix = glm::dmat3(1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
@@ -26,20 +26,22 @@
|
||||
#define __SPICEROTATION_H__
|
||||
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class SpiceRotation : public Rotation {
|
||||
public:
|
||||
SpiceRotation(const ghoul::Dictionary& dictionary);
|
||||
virtual const glm::dmat3& matrix() const;
|
||||
const glm::dmat3& matrix() const;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
private:
|
||||
std::string _sourceFrame;
|
||||
std::string _destinationFrame;
|
||||
glm::dmat3 _rotationMatrix;
|
||||
bool _kernelsLoadedSuccessfully;
|
||||
properties::StringProperty _sourceFrame;
|
||||
properties::StringProperty _destinationFrame;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -24,29 +24,67 @@
|
||||
|
||||
#include <modules/base/rotation/staticrotation.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
namespace {
|
||||
const std::string KeyEulerAngles = "EulerAngles";
|
||||
const std::string KeyRotation = "Rotation";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Documentation StaticRotation::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
return {
|
||||
"Static Rotation",
|
||||
"base_transform_rotation_static",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("StaticRotation"),
|
||||
"",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyRotation,
|
||||
new OrVerifier(
|
||||
new DoubleVector3Verifier(),
|
||||
new DoubleMatrix3Verifier()
|
||||
),
|
||||
"Stores the static rotation as either a vector containing Euler angles "
|
||||
"or by specifiying the 3x3 rotation matrix directly",
|
||||
Optional::No
|
||||
}
|
||||
},
|
||||
Exhaustive::Yes
|
||||
};
|
||||
}
|
||||
|
||||
StaticRotation::StaticRotation()
|
||||
: _rotationMatrix("rotation", "Rotation", glm::dmat3(1.0))
|
||||
{}
|
||||
|
||||
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary)
|
||||
: _rotationMatrix(1.0)
|
||||
: StaticRotation()
|
||||
{
|
||||
const bool hasEulerAngles = dictionary.hasKeyAndValue<glm::dvec3>(KeyEulerAngles);
|
||||
if (hasEulerAngles) {
|
||||
glm::dvec3 tmp;
|
||||
dictionary.getValue(KeyEulerAngles, tmp);
|
||||
_rotationMatrix = glm::mat3_cast(glm::dquat(tmp));
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"StaticRotation"
|
||||
);
|
||||
|
||||
|
||||
if (dictionary.hasKeyAndValue<glm::dvec3>(KeyRotation)) {
|
||||
_rotationMatrix = glm::mat3_cast(
|
||||
glm::dquat(dictionary.value<glm::dvec3>(KeyRotation))
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Must be glm::dmat3 due to specification restriction
|
||||
_rotationMatrix = dictionary.value<glm::dmat3>(KeyRotation);
|
||||
}
|
||||
|
||||
addProperty(_rotationMatrix);
|
||||
_rotationMatrix.onChange([this]() { _matrix = _rotationMatrix; });
|
||||
}
|
||||
|
||||
StaticRotation::~StaticRotation() {}
|
||||
|
||||
const glm::dmat3& StaticRotation::matrix() const {
|
||||
return _rotationMatrix;
|
||||
}
|
||||
|
||||
void StaticRotation::update(const UpdateData&) {}
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
@@ -27,17 +27,20 @@
|
||||
|
||||
#include <openspace/scene/rotation.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/matrixproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class StaticRotation: public Rotation {
|
||||
class StaticRotation : public Rotation {
|
||||
public:
|
||||
StaticRotation(const ghoul::Dictionary& dictionary
|
||||
= ghoul::Dictionary());
|
||||
virtual ~StaticRotation();
|
||||
virtual const glm::dmat3& matrix() const;
|
||||
virtual void update(const UpdateData& data) override;
|
||||
StaticRotation();
|
||||
StaticRotation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
private:
|
||||
glm::dmat3 _rotationMatrix;
|
||||
properties::DMat3Property _rotationMatrix;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
// Atmosphere Rendering Parameters
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float AverageGroundReflectance;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieScattering;
|
||||
uniform vec3 betaMieExtinction;
|
||||
uniform float mieG;
|
||||
uniform float sunRadiance;
|
||||
|
||||
const float ATM_EPSILON = 1.0;
|
||||
// const float RL = Rt + 1.0;
|
||||
|
||||
// const float Rg = 6360.0;
|
||||
// const float Rt = 6420.0;
|
||||
// const float RL = 6421.0;
|
||||
// const float ATM_EPSILON = 1.0;
|
||||
|
||||
// const float AVERAGE_GROUND_REFLECTANCE = 0.1;
|
||||
|
||||
// // Rayleigh
|
||||
// const float HR = 8.0;
|
||||
// const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2);
|
||||
|
||||
// // Mie
|
||||
// // DEFAULT
|
||||
// const float HM = 1.2;
|
||||
// const vec3 betaMSca = vec3(4e-3);
|
||||
// //const vec3 betaMSca = vec3(2e-5);
|
||||
// const vec3 betaMEx = betaMSca / 0.9;
|
||||
// const float mieG = 1.0;
|
||||
|
||||
// Integration steps
|
||||
const int TRANSMITTANCE_STEPS = 500;
|
||||
const int INSCATTER_INTEGRAL_SAMPLES = 50;
|
||||
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
|
||||
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
|
||||
|
||||
// The next values crash NVIDIA driver for Quadro K620 -- JCC
|
||||
// const int TRANSMITTANCE_INTEGRAL_SAMPLES = 1000;
|
||||
// const int INSCATTER_INTEGRAL_SAMPLES = 100;
|
||||
// const int IRRADIANCE_INTEGRAL_SAMPLES = 64;
|
||||
// const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 32;
|
||||
|
||||
const float M_PI = 3.141592657;
|
||||
|
||||
const int TRANSMITTANCE_W = 256;
|
||||
const int TRANSMITTANCE_H = 64;
|
||||
|
||||
const int SKY_W = 64;
|
||||
const int SKY_H = 16;
|
||||
|
||||
const int OTHER_TEXTURES_W = 64;
|
||||
const int OTHER_TEXTURES_H = 16;
|
||||
|
||||
|
||||
const int RES_R = 32;
|
||||
const int RES_MU = 128;
|
||||
const int RES_MU_S = 32;
|
||||
const int RES_NU = 8;
|
||||
@@ -1,629 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#define EPSILON 0.0001f
|
||||
|
||||
// Sun Irradiance
|
||||
const float ISun = 40.0;
|
||||
|
||||
uniform dmat4 object2WorldKMMatrix;
|
||||
uniform dmat4 object2WorldMatrix;
|
||||
uniform dmat4 scaleTransformKMMatrix;
|
||||
uniform dmat4 scaleTransformMatrix;
|
||||
uniform dmat4 completeTransfKMInverse;
|
||||
uniform dmat4 completeTransfInverse;
|
||||
uniform dmat4 sgctProjectionMatrix;
|
||||
uniform dmat4 inverseSgctProjectionMatrix;
|
||||
uniform dmat4 sgctViewMatrix;
|
||||
uniform dmat4 inverseSgctViewMatrix;
|
||||
uniform dmat4 cameraRotationMatrix;
|
||||
uniform dmat4 inverseCameraRotationMatrix;
|
||||
uniform dmat4 world2ObjectKMMatrix;
|
||||
uniform dmat4 world2ObjectMatrix;
|
||||
uniform dvec4 cameraPositionKMObject;
|
||||
uniform dvec4 cameraPositionKMWorld;
|
||||
uniform dvec4 cameraPositionObject;
|
||||
uniform dvec4 cameraPositionWorld;
|
||||
uniform dvec4 planetPositionObjKM;
|
||||
uniform dvec4 planetPositionWorldKM;
|
||||
uniform dvec4 planetPositionObj;
|
||||
uniform dvec4 planetPositionWorld;
|
||||
uniform dvec4 sunPositionObjKM;
|
||||
uniform dvec4 sunPositionObj;
|
||||
|
||||
//uniform vec4 campos;
|
||||
//uniform vec4 objpos;
|
||||
//uniform vec3 sun_pos;
|
||||
|
||||
uniform bool _performShading = true;
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform float screenX;
|
||||
uniform float screenY;
|
||||
uniform float screenWIDTH;
|
||||
uniform float screenHEIGHT;
|
||||
|
||||
uniform float time;
|
||||
|
||||
uniform sampler2D reflectanceTexture;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler2D irradianceTexture;
|
||||
uniform sampler3D inscatterTexture;
|
||||
|
||||
#include "hdr.glsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
|
||||
layout(location = 1) out vec4 renderTarget;
|
||||
|
||||
in vec3 viewDirectionVS;
|
||||
in vec4 vertexPosObjVS;
|
||||
|
||||
/*******************************************************************************
|
||||
****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ******
|
||||
*******************************************************************************/
|
||||
|
||||
/* Calculates the intersection of the view ray direction with the atmosphere and
|
||||
* returns the first intersection (0.0 when inside atmosphere): offset
|
||||
* and the second intersection: maxLength
|
||||
*/
|
||||
|
||||
struct Ray {
|
||||
dvec4 origin;
|
||||
dvec4 direction;
|
||||
};
|
||||
|
||||
struct Ellipsoid {
|
||||
dvec4 center;
|
||||
dvec4 size;
|
||||
};
|
||||
|
||||
bool algebraicIntersecSphere(const Ray ray, const float SphereRadius, const dvec4 SphereCenter,
|
||||
out double offset, out double maxLength)
|
||||
{
|
||||
dvec3 L = ray.origin.xyz - SphereCenter.xyz;
|
||||
double B = 2 * dot(ray.direction.xyz, L);
|
||||
double C = dot(L, L) - (SphereRadius*SphereRadius);
|
||||
double delta = B*B - 4*C;
|
||||
|
||||
if ( delta < 0.0 ) { // no intersection
|
||||
return false;
|
||||
}
|
||||
else if ( delta == 0.0 ) { // one intersection;
|
||||
offset = maxLength = -B/2.0;
|
||||
return true;
|
||||
} else {
|
||||
double inv2 = 1.0/2.0;
|
||||
double tmpB = -B*inv2;
|
||||
double root = sqrt(delta);
|
||||
double t0 = tmpB - root*inv2;
|
||||
double t1 = tmpB + root*inv2;
|
||||
|
||||
if ( t0 < t1 ) {
|
||||
offset = t0;
|
||||
maxLength = t1;
|
||||
} else {
|
||||
offset = t1;
|
||||
maxLength = t0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool geometricIntersecSphere(const Ray ray, const float SphereRadius, const dvec4 SphereCenter,
|
||||
out double offset, out double maxLength) {
|
||||
// Ray's direction must be normalized.
|
||||
dvec4 OC = SphereCenter - ray.origin;
|
||||
double L2 = dot(OC.xyz, OC.xyz);
|
||||
double Sr2 = SphereRadius * SphereRadius;
|
||||
|
||||
if ( L2 < Sr2 ) // Ray origin inside sphere.
|
||||
return false; // TODO: Bust be handled later
|
||||
|
||||
double t_ca = dot(OC.xyz, ray.direction.xyz);
|
||||
|
||||
if ( t_ca < 0.0 ) // Sphere's center lies behind the rays origin.
|
||||
return false; // TODO: Handle inside sphere.
|
||||
|
||||
double t_2hc = Sr2 - L2 + (t_ca * t_ca);
|
||||
|
||||
if ( t_2hc < 0.0 ) // Ray misses the sphere
|
||||
return false;
|
||||
|
||||
double t_hc = sqrt(t_2hc);
|
||||
|
||||
offset = t_ca - t_hc;
|
||||
maxLength = t_ca + t_hc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out double offset, out double maxLength) {
|
||||
dvec4 O_C = ray.origin-ellipsoid.center;
|
||||
dvec4 dir = normalize(ray.direction);
|
||||
|
||||
offset = 0.0f;
|
||||
maxLength = 0.0f;
|
||||
|
||||
double a =
|
||||
((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
|
||||
double b =
|
||||
((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
|
||||
double c =
|
||||
((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z))
|
||||
- 1.f;
|
||||
|
||||
double d = ((b*b)-(4.f*a*c));
|
||||
if ( d<0.f || a==0.f || b==0.f || c==0.f )
|
||||
return false;
|
||||
|
||||
d = sqrt(d);
|
||||
|
||||
double t1 = (-b+d)/(2.f*a);
|
||||
double t2 = (-b-d)/(2.f*a);
|
||||
|
||||
if( t1<=EPSILON && t2<=EPSILON )
|
||||
return false; // both intersections are behind the ray origin
|
||||
|
||||
bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid
|
||||
double t=0.f;
|
||||
if( t1<=EPSILON )
|
||||
t = t2;
|
||||
else
|
||||
if( t2<=EPSILON )
|
||||
t = t1;
|
||||
else
|
||||
t=(t1<t2) ? t1 : t2;
|
||||
|
||||
if( t<EPSILON ) return false; // Too close to intersection
|
||||
|
||||
dvec4 intersection = ray.origin + t*dir;
|
||||
dvec4 normal = intersection-ellipsoid.center;
|
||||
normal.x = 2.f*normal.x/(ellipsoid.size.x*ellipsoid.size.x);
|
||||
normal.y = 2.f*normal.y/(ellipsoid.size.y*ellipsoid.size.y);
|
||||
normal.z = 2.f*normal.z/(ellipsoid.size.z*ellipsoid.size.z);
|
||||
|
||||
normal.w = 0.f;
|
||||
normal *= (back) ? -1.f : 1.f;
|
||||
normal = normalize(normal);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersectAtmosphere(const dvec4 planetPos, const dvec3 rayDirection, const double sphereRadius,
|
||||
out double offset, out double maxLength) {
|
||||
offset = 0.0f;
|
||||
maxLength = 0.0f;
|
||||
|
||||
dvec3 l = planetPos.xyz - cameraPositionObject.xyz;
|
||||
double s = dot(l, rayDirection);
|
||||
double l2 = dot(l, l);
|
||||
|
||||
// sphereRadius in Km
|
||||
double r = sphereRadius - EPSILON; // EPSILON to avoid surface acne
|
||||
double r2 = r * r;
|
||||
|
||||
if (l2 <= r2) {
|
||||
// ray origin inside sphere
|
||||
double m2 = l2 - (s*s);
|
||||
double q = sqrt(r2 - m2);
|
||||
maxLength = s + q;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (s >= 0.0) {
|
||||
// ray outside sphere
|
||||
double m2 = l2 - (s*s);
|
||||
if (m2 <= r2) {
|
||||
// ray hits atmosphere
|
||||
double q = sqrt(r2 - m2);
|
||||
offset = s-q;
|
||||
maxLength = (s+q)-offset;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rayleigh phase function
|
||||
float phaseFunctionR(float mu) {
|
||||
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// Mie phase function
|
||||
float phaseFunctionM(float mu) {
|
||||
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
|
||||
}
|
||||
|
||||
float opticalDepth(float H, float r, float mu, float d) {
|
||||
float a = sqrt((0.5/H)*r);
|
||||
vec2 a01 = a*vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01*a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
|
||||
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
}
|
||||
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
|
||||
{
|
||||
float H = sqrt(Rt * Rt - Rg * Rg);
|
||||
float rho = sqrt(r * r - Rg * Rg);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r * r + Rg * Rg;
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
|
||||
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
|
||||
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
|
||||
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
|
||||
float uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
|
||||
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
|
||||
}
|
||||
|
||||
vec3 analyticTransmittance(float r, float mu, float d) {
|
||||
return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
}
|
||||
|
||||
vec3 getMie(vec4 rayMie) {
|
||||
return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaRayleigh.r / betaRayleigh);
|
||||
}
|
||||
|
||||
vec2 getTransmittanceUV(float r, float mu) {
|
||||
float uR, uMu;
|
||||
uR = sqrt((r - Rg) / (Rt - Rg));
|
||||
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
return vec2(uMu, uR);
|
||||
}
|
||||
|
||||
vec3 transmittanceFromTexture(float r, float mu) {
|
||||
vec2 uv = getTransmittanceUV(r, mu);
|
||||
return texture(transmittanceTexture, uv).rgb;
|
||||
}
|
||||
|
||||
vec3 transmittanceWithShadow(float r, float mu) {
|
||||
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu);
|
||||
}
|
||||
|
||||
vec3 transmittance(float r, float mu, vec3 v, vec3 x0) {
|
||||
vec3 result;
|
||||
float r1 = length(x0);
|
||||
float mu1 = dot(x0, v) / r;
|
||||
if (mu > 0.0) {
|
||||
result = min(transmittanceFromTexture(r, mu) /
|
||||
transmittanceFromTexture(r1, mu1), 1.0);
|
||||
} else {
|
||||
result = min(transmittanceFromTexture(r1, -mu1) /
|
||||
transmittanceFromTexture(r, -mu), 1.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec2 getIrradianceUV(float r, float muS) {
|
||||
float uR = (r - Rg) / (Rt - Rg);
|
||||
float uMuS = (muS + 0.2) / (1.0 + 0.2);
|
||||
return vec2(uMuS, uR);
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D sampler, float r, float muS) {
|
||||
vec2 uv = getIrradianceUV(r, muS);
|
||||
return texture(sampler, uv).rgb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the light scattering in the view direction comming from other
|
||||
* light rays scattered in the atmosphere.
|
||||
* The view direction here is the ray: x + tv, s is the sun direction,
|
||||
* r and mu the position and zenith cossine angle as in the paper.
|
||||
*/
|
||||
vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s,
|
||||
out float r, out float mu, out vec3 attenuation) {
|
||||
vec3 result;
|
||||
r = length(x);
|
||||
mu = dot(x, v) / r;
|
||||
float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
|
||||
if (d > 0.0) {
|
||||
x += d * v;
|
||||
t -= d;
|
||||
mu = (r * mu + d) / Rt;
|
||||
r = Rt;
|
||||
}
|
||||
// Intersects atmosphere?
|
||||
if (r <= Rt) {
|
||||
float nu = dot(v, s);
|
||||
float muS = dot(x, s) / r;
|
||||
float phaseR = phaseFunctionR(nu);
|
||||
float phaseM = phaseFunctionM(nu);
|
||||
vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0);
|
||||
if (t > 0.0) {
|
||||
vec3 x0 = x + t * v;
|
||||
float r0 = length(x0);
|
||||
float rMu0 = dot(x0, v);
|
||||
float mu0 = rMu0 / r0;
|
||||
float muS0 = dot(x0, s) / r0;
|
||||
|
||||
attenuation = analyticTransmittance(r, mu, t);
|
||||
//attenuation = transmittance(r, mu, v, x+t*v);
|
||||
|
||||
//The following Code is generating surface acne on atmosphere. JCC
|
||||
// We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x
|
||||
if (r0 > Rg + 0.1*r) {
|
||||
inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0);
|
||||
const float EPS = 0.004;
|
||||
float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
|
||||
if (abs(mu - muHoriz) < EPS) {
|
||||
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
|
||||
|
||||
mu = muHoriz - EPS;
|
||||
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
|
||||
mu0 = (r * mu + t) / r0;
|
||||
vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
|
||||
vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
|
||||
vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
|
||||
|
||||
mu = muHoriz + EPS;
|
||||
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
|
||||
mu0 = (r * mu + t) / r0;
|
||||
inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
|
||||
inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
|
||||
vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
|
||||
|
||||
inscatter = mix(inScatterA, inScatterB, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
inscatter.w *= smoothstep(0.00, 0.02, muS);
|
||||
result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0);
|
||||
|
||||
} else {
|
||||
// No intersection with earth
|
||||
result = vec3(0.0);
|
||||
}
|
||||
return result * ISun;
|
||||
}
|
||||
|
||||
vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation)
|
||||
{
|
||||
vec3 result;
|
||||
// Ray hits ground
|
||||
if (t > 0.0) {
|
||||
vec3 x0 = x + t * v;
|
||||
float r0 = length(x0);
|
||||
vec3 n = x0 / r0;
|
||||
|
||||
// Old deferred:
|
||||
vec2 coords = vec2(atan(n.y, n.x), acos(n.z)) * vec2(0.5, 1.0) / M_PI + vec2(0.5, 0.0);
|
||||
vec4 reflectance = texture2D(reflectanceTexture, coords) * vec4(0.2, 0.2, 0.2, 1.0);
|
||||
if (r0 > Rg + 0.01) {
|
||||
reflectance = vec4(0.4, 0.4, 0.4, 0.0);
|
||||
}
|
||||
|
||||
// New non-deferred
|
||||
// // Fixing texture coordinates:
|
||||
// vec4 reflectance = vec4(0.2, 0.2, 0.2, 1.0);
|
||||
|
||||
// // The following code is generating surface acne in ground.
|
||||
// // It is only necessary inside atmosphere rendering. JCC
|
||||
// if (r0 > Rg + 0.01) {
|
||||
// reflectance = vec4(0.4, 0.4, 0.4, 0.0);
|
||||
// }
|
||||
|
||||
float muS = dot(n, s);
|
||||
vec3 sunLight = transmittanceWithShadow(r0, muS);
|
||||
|
||||
vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS);
|
||||
|
||||
//vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st);
|
||||
vec3 groundColor = (reflectance.rgb) *
|
||||
(max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI;
|
||||
|
||||
// Yellowish reflection from sun on oceans and rivers
|
||||
if (reflectance.w > 0.0) {
|
||||
vec3 h = normalize(s - v);
|
||||
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
|
||||
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
|
||||
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun;
|
||||
}
|
||||
|
||||
result = attenuation * groundColor;
|
||||
} else {
|
||||
// No hit
|
||||
result = vec3(0.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) {
|
||||
if (t > 0.0) {
|
||||
return vec3(0.0);
|
||||
} else {
|
||||
vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0);
|
||||
float isun = step(cos(M_PI / 180.0), dot(v, s)) * ISun;
|
||||
return transmittance * isun;
|
||||
}
|
||||
}
|
||||
|
||||
Fragment getFragment() {
|
||||
//vec4 position = vs_position;
|
||||
float depth = 0.0;
|
||||
// vec4 diffuse = texture(texture1, vs_st);
|
||||
// vec4 diffuse2 = texture(nightTex, vs_st);
|
||||
// vec4 clouds = texture(cloudsTexture, vs_st);
|
||||
vec4 diffuse = vec4(0.0);
|
||||
|
||||
Fragment frag;
|
||||
if (_performShading) {
|
||||
// // Fragment to window coordinates
|
||||
// dvec4 windowCoords = vec4(0.0);
|
||||
// windowCoords.xy = gl_FragCoord.xy + 0.5;
|
||||
// windowCoords.z = gl_FragCoord.z; // z can be 0.0 or 1.0. We chose 1.0 to avoid math problems.
|
||||
// windowCoords.w = 1.0 / gl_FragCoord.w;
|
||||
|
||||
// // Window to NDC coordinates
|
||||
// dvec4 viewPort = vec4(screenX, screenY, screenWIDTH, screenHEIGHT);
|
||||
// dvec4 ndcCoords = vec4(0.0);
|
||||
// ndcCoords.x = (2.0/screenWIDTH) * (windowCoords.x - (screenX + screenWIDTH/2.0));
|
||||
// ndcCoords.y = (2.0/screenHEIGHT) * (windowCoords.y - (screenY + screenHEIGHT/2.0));
|
||||
// double f_plus_n = gl_DepthRange.far + gl_DepthRange.near;
|
||||
// double f_minus_n = gl_DepthRange.far - gl_DepthRange.near;
|
||||
// ndcCoords.z = (2.0/f_minus_n) * windowCoords.z - (f_plus_n/f_minus_n);
|
||||
// ndcCoords.w = windowCoords.w;
|
||||
|
||||
// // NDC to clip coordinates
|
||||
// dvec4 clipCoords = vec4(0.0);
|
||||
// clipCoords.xyz = ndcCoords.xyz * ndcCoords.w;
|
||||
// clipCoords.w = 1.0 / ndcCoords.w;
|
||||
|
||||
// //now we transform back from clip space to world space using the complete inverse transformation.
|
||||
// dvec4 projCoords = projInverse * clipCoords;
|
||||
|
||||
// Because this is a vector and not a point, we do not need to reverse the perspective division here,
|
||||
// a vetor doesn't have intrinsic depth:
|
||||
dvec4 vVSTmp = vertexPosObjVS;
|
||||
//vVSTmp.z = -1.0;
|
||||
//vVSTmp.w = 0.0;
|
||||
dvec4 projCoords = inverseSgctProjectionMatrix * vVSTmp;
|
||||
//projCoords.z = -1.0;
|
||||
//projCoords.w = 0.0;
|
||||
|
||||
|
||||
/*
|
||||
uniform dmat4 object2WorldKMMatrix;
|
||||
uniform dmat4 object2WorldMatrix;
|
||||
uniform dmat4 scaleTransformKMMatrix;
|
||||
uniform dmat4 scaleTransformMatrix;
|
||||
uniform dmat4 completeTransfKMInverse;
|
||||
uniform dmat4 completeTransfInverse;
|
||||
uniform dmat4 sgctProjectionMatrix;
|
||||
uniform dmat4 inverseSgctProjectionMatrix;
|
||||
uniform dmat4 sgctViewMatrix;
|
||||
uniform dmat4 inverseSgctViewMatrix;
|
||||
uniform dmat4 cameraRotationMatrix;
|
||||
uniform dmat4 inverseCameraRotationMatrix;
|
||||
uniform dmat4 world2ObjecKMMatrix;
|
||||
uniform dmat4 world2ObjecMatrix;
|
||||
uniform dvec4 cameraPositionKMObject;
|
||||
uniform dvec4 cameraPositionKMWorld;
|
||||
uniform dvec4 cameraPositionObject;
|
||||
uniform dvec4 cameraPositionWorld;
|
||||
uniform dvec4 planetPositionObjKM;
|
||||
uniform dvec4 planetPositionWorldKM;
|
||||
uniform dvec4 planetPositionObj;
|
||||
uniform dvec4 planetPositionWorld;
|
||||
uniform dvec4 sunPositionObjKM;
|
||||
uniform dvec4 sunPositionObj;
|
||||
*/
|
||||
|
||||
|
||||
double offset = 0.0, maxLength = 0.0;
|
||||
vec4 ppos = vec4(0.0);
|
||||
|
||||
//View direction is in object space.
|
||||
dvec4 viewDirection = completeTransfInverse * vVSTmp;
|
||||
|
||||
Ray ray;
|
||||
ray.origin = cameraPositionObject;
|
||||
ray.direction = vec4(normalize((viewDirection - cameraPositionObject).xyz), 0.0);
|
||||
|
||||
//diffuse = vec4(normalize(ray.direction.xyz), 1.0);
|
||||
diffuse = vec4(normalize(planetPositionObj.xyz), 1.0);
|
||||
// dvec4 zeroTest = vec4(0.0);
|
||||
//if ( algebraicIntersecSphere(ray, Rt, zeroTest, offset, maxLength) ) {
|
||||
//if ( algebraicIntersecSphere(ray, Rt, planetPositonTransfObject, offset, maxLength) ) {
|
||||
//if ( algebraicIntersecSphere(ray, Rt, planetPositionObj, offset, maxLength) ) {
|
||||
//if ( geometricIntersecSphere(ray, Rg, ppos, offset, maxLength) ) {
|
||||
//if ( geometricIntersecSphere(ray, Rt, planetPositionObj, offset, maxLength) ) {
|
||||
//if (intersectAtmosphere(planetPositionObj, v, Rg, offset, maxLength)) {
|
||||
//if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) {
|
||||
// // if ( offset < 0) // inside atmosphere
|
||||
// // t = maxLength;
|
||||
// // Following paper nomenclature
|
||||
// // float t = offset;
|
||||
// // vec3 x = cameraPosObj.xyz + (t * v) - planetPositionObj.xyz;
|
||||
// // // When using geometry
|
||||
// // //vec3 x = ray.origin.xyz + t * ray.direction.xyz - planetPositionObj.xyz;
|
||||
// // float r = length(x);
|
||||
// // float mu = (dot(x, v))/ r;
|
||||
// // //float mu = (dot(x, -v))/ r;
|
||||
// // vec3 s = normalize(sunPositionObj);
|
||||
|
||||
// // vec3 attenuation;
|
||||
// // vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation);
|
||||
// // vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation);
|
||||
// // vec3 sunColor = sunColor(x, t, v, s, r, mu);
|
||||
|
||||
// // diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0));
|
||||
// //diffuse = HDR(vec4(sunColor, 1.0));
|
||||
// //diffuse = HDR(vec4(groundColor, 1.0));
|
||||
// //diffuse = HDR(vec4(inscatterColor, 1.0));
|
||||
|
||||
// //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2);
|
||||
// // diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) *
|
||||
// // calcShadow(shadowDataArray, vs_posWorld.xyz) );
|
||||
|
||||
|
||||
|
||||
// float t = maxLength;
|
||||
// vec3 x = cameraPosObj.xyz + offset * v;
|
||||
// float r = length(x);
|
||||
// float mu = dot(x, v) / r;
|
||||
// vec3 s = normalize(sunPositionObj - x);
|
||||
|
||||
// vec3 attenuation;
|
||||
// vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation); //S[L]-T(x,xs)S[l]|xs
|
||||
// vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); //R[L0]+R[L*]
|
||||
// vec3 sunColor = sunColor(x, t, v, s, r, mu); //L0
|
||||
// diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); // Eq (16)
|
||||
|
||||
// diffuse = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// diffuse = HDR(diffuse);
|
||||
}
|
||||
|
||||
renderTarget = diffuse;
|
||||
|
||||
|
||||
diffuse[3] = transparency;
|
||||
frag.color = diffuse;
|
||||
frag.depth = 0.0;
|
||||
|
||||
return frag;
|
||||
}
|
||||
@@ -1,505 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#define EPSILON 0.0001f
|
||||
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
float xu, xp;
|
||||
float rs, rc;
|
||||
vec3 sourceCasterVec;
|
||||
vec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
|
||||
|
||||
uniform mat4 completeInverse;
|
||||
uniform mat4 projInverse;
|
||||
|
||||
uniform vec4 campos;
|
||||
uniform vec4 objpos;
|
||||
uniform vec3 sun_pos;
|
||||
|
||||
uniform vec4 cameraPosObj;
|
||||
uniform vec4 planetPositionObj;
|
||||
uniform vec3 sunPositionObj;
|
||||
|
||||
uniform bool _performShading = true;
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform float screenX;
|
||||
uniform float screenY;
|
||||
uniform float screenWIDTH;
|
||||
uniform float screenHEIGHT;
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D nightTex;
|
||||
uniform sampler2D cloudsTexture;
|
||||
|
||||
uniform sampler2D reflectanceTexture;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler2D irradianceTexture;
|
||||
uniform sampler3D inscatterTexture;
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec2 vs_nightTex;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_posWorld;
|
||||
|
||||
#include "hdr.glsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ******
|
||||
*******************************************************************************/
|
||||
|
||||
/* Calculates the intersection of the view ray direction with the atmosphere and
|
||||
* returns the first intersection (0.0 when inside atmosphere): offset
|
||||
* and the second intersection: maxLength
|
||||
*/
|
||||
|
||||
struct Ray {
|
||||
vec4 origin;
|
||||
vec4 direction;
|
||||
};
|
||||
|
||||
struct Ellipsoid {
|
||||
vec4 center;
|
||||
vec4 size;
|
||||
};
|
||||
|
||||
bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out float offset, out float maxLength) {
|
||||
vec4 O_C = ray.origin-ellipsoid.center;
|
||||
vec4 dir = normalize(ray.direction);
|
||||
|
||||
offset = 0.0f;
|
||||
maxLength = 0.0f;
|
||||
|
||||
float a =
|
||||
((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
|
||||
float b =
|
||||
((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
|
||||
float c =
|
||||
((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x))
|
||||
+ ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y))
|
||||
+ ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z))
|
||||
- 1.f;
|
||||
|
||||
float d = ((b*b)-(4.f*a*c));
|
||||
if ( d<0.f || a==0.f || b==0.f || c==0.f )
|
||||
return false;
|
||||
|
||||
d = sqrt(d);
|
||||
|
||||
float t1 = (-b+d)/(2.f*a);
|
||||
float t2 = (-b-d)/(2.f*a);
|
||||
|
||||
if( t1<=EPSILON && t2<=EPSILON )
|
||||
return false; // both intersections are behind the ray origin
|
||||
|
||||
bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid
|
||||
float t=0.f;
|
||||
if( t1<=EPSILON )
|
||||
t = t2;
|
||||
else
|
||||
if( t2<=EPSILON )
|
||||
t = t1;
|
||||
else
|
||||
t=(t1<t2) ? t1 : t2;
|
||||
|
||||
if( t<EPSILON ) return false; // Too close to intersection
|
||||
|
||||
vec4 intersection = ray.origin + t*dir;
|
||||
vec4 normal = intersection-ellipsoid.center;
|
||||
normal.x = 2.f*normal.x/(ellipsoid.size.x*ellipsoid.size.x);
|
||||
normal.y = 2.f*normal.y/(ellipsoid.size.y*ellipsoid.size.y);
|
||||
normal.z = 2.f*normal.z/(ellipsoid.size.z*ellipsoid.size.z);
|
||||
|
||||
normal.w = 0.f;
|
||||
normal *= (back) ? -1.f : 1.f;
|
||||
normal = normalize(normal);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const float sphereRadius,
|
||||
out float offset, out float maxLength) {
|
||||
offset = 0.0f;
|
||||
maxLength = 0.0f;
|
||||
|
||||
vec3 l = planetPos.xyz - cameraPosObj.xyz;
|
||||
float s = dot(l, rayDirection);
|
||||
float l2 = dot(l, l);
|
||||
|
||||
// sphereRadius in Km
|
||||
float r = sphereRadius - EPSILON; // EPSILON to avoid surface acne
|
||||
float r2 = r * r;
|
||||
|
||||
if (l2 <= r2) {
|
||||
// ray origin inside sphere
|
||||
float m2 = l2 - (s*s);
|
||||
float q = sqrt(r2 - m2);
|
||||
maxLength = s + q;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (s >= 0.0) {
|
||||
// ray outside sphere
|
||||
float m2 = l2 - (s*s);
|
||||
if (m2 <= r2) {
|
||||
// ray hits atmosphere
|
||||
float q = sqrt(r2 - m2);
|
||||
offset = s-q;
|
||||
maxLength = (s+q)-offset;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rayleigh phase function
|
||||
float phaseFunctionR(float mu) {
|
||||
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// Mie phase function
|
||||
float phaseFunctionM(float mu) {
|
||||
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
|
||||
}
|
||||
|
||||
float opticalDepth(float H, float r, float mu, float d) {
|
||||
float a = sqrt((0.5/H)*r);
|
||||
vec2 a01 = a*vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01*a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
|
||||
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
}
|
||||
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
|
||||
{
|
||||
float H = sqrt(Rt * Rt - Rg * Rg);
|
||||
float rho = sqrt(r * r - Rg * Rg);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r * r + Rg * Rg;
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
|
||||
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
|
||||
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
|
||||
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
|
||||
float uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
|
||||
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
|
||||
}
|
||||
|
||||
vec3 analyticTransmittance(float r, float mu, float d) {
|
||||
return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
}
|
||||
|
||||
vec3 getMie(vec4 rayMie) {
|
||||
return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaRayleigh.r / betaRayleigh);
|
||||
}
|
||||
|
||||
vec2 getTransmittanceUV(float r, float mu) {
|
||||
float uR, uMu;
|
||||
uR = sqrt((r - Rg) / (Rt - Rg));
|
||||
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
return vec2(uMu, uR);
|
||||
}
|
||||
|
||||
vec3 transmittanceFromTexture(float r, float mu) {
|
||||
vec2 uv = getTransmittanceUV(r, mu);
|
||||
return texture(transmittanceTexture, uv).rgb;
|
||||
}
|
||||
|
||||
vec3 transmittanceWithShadow(float r, float mu) {
|
||||
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu);
|
||||
}
|
||||
|
||||
vec3 transmittance(float r, float mu, vec3 v, vec3 x0) {
|
||||
vec3 result;
|
||||
float r1 = length(x0);
|
||||
float mu1 = dot(x0, v) / r;
|
||||
if (mu > 0.0) {
|
||||
result = min(transmittanceFromTexture(r, mu) /
|
||||
transmittanceFromTexture(r1, mu1), 1.0);
|
||||
} else {
|
||||
result = min(transmittanceFromTexture(r1, -mu1) /
|
||||
transmittanceFromTexture(r, -mu), 1.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec2 getIrradianceUV(float r, float muS) {
|
||||
float uR = (r - Rg) / (Rt - Rg);
|
||||
float uMuS = (muS + 0.2) / (1.0 + 0.2);
|
||||
return vec2(uMuS, uR);
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D sampler, float r, float muS) {
|
||||
vec2 uv = getIrradianceUV(r, muS);
|
||||
return texture(sampler, uv).rgb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the light scattering in the view direction comming from other
|
||||
* light rays scattered in the atmosphere.
|
||||
* The view direction here is the ray: x + tv, s is the sun direction,
|
||||
* r and mu the position and zenith cossine angle as in the paper.
|
||||
*/
|
||||
vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s,
|
||||
out float r, out float mu, out vec3 attenuation) {
|
||||
vec3 result;
|
||||
r = length(x);
|
||||
mu = dot(x, v) / r;
|
||||
float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
|
||||
if (d > 0.0) {
|
||||
x += d * v;
|
||||
t -= d;
|
||||
mu = (r * mu + d) / Rt;
|
||||
r = Rt;
|
||||
}
|
||||
// Intersects atmosphere?
|
||||
if (r <= Rt) {
|
||||
float nu = dot(v, s);
|
||||
float muS = dot(x, s) / r;
|
||||
float phaseR = phaseFunctionR(nu);
|
||||
float phaseM = phaseFunctionM(nu);
|
||||
vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0);
|
||||
if (t > 0.0) {
|
||||
vec3 x0 = x + t * v;
|
||||
float r0 = length(x0);
|
||||
float rMu0 = dot(x0, v);
|
||||
float mu0 = rMu0 / r0;
|
||||
float muS0 = dot(x0, s) / r0;
|
||||
|
||||
attenuation = analyticTransmittance(r, mu, t);
|
||||
//attenuation = transmittance(r, mu, v, x+t*v);
|
||||
|
||||
//The following Code is generating surface acne on atmosphere. JCC
|
||||
// We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x
|
||||
if (r0 > Rg + 0.1*r) {
|
||||
inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0);
|
||||
const float EPS = 0.004;
|
||||
float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
|
||||
if (abs(mu - muHoriz) < EPS) {
|
||||
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
|
||||
|
||||
mu = muHoriz - EPS;
|
||||
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
|
||||
mu0 = (r * mu + t) / r0;
|
||||
vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
|
||||
vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
|
||||
vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
|
||||
|
||||
mu = muHoriz + EPS;
|
||||
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
|
||||
mu0 = (r * mu + t) / r0;
|
||||
inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
|
||||
inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
|
||||
vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
|
||||
|
||||
inscatter = mix(inScatterA, inScatterB, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
inscatter.w *= smoothstep(0.00, 0.02, muS);
|
||||
result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0);
|
||||
|
||||
} else {
|
||||
// No intersection with earth
|
||||
result = vec3(0.0);
|
||||
}
|
||||
return result * sunRadiance;
|
||||
}
|
||||
|
||||
vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation)
|
||||
{
|
||||
vec3 result;
|
||||
// Ray hits ground
|
||||
if (t > 0.0) {
|
||||
vec3 x0 = x + t * v;
|
||||
float r0 = length(x0);
|
||||
vec3 n = x0 / r0;
|
||||
|
||||
// Fixing texture coordinates:
|
||||
vec4 reflectance = texture(reflectanceTexture, vs_st) * vec4(0.2, 0.2, 0.2, 1.0);
|
||||
|
||||
// The following code is generating surface acne in ground.
|
||||
// It is only necessary inside atmosphere rendering. JCC
|
||||
// if (r0 > Rg + 0.01) {
|
||||
// reflectance = vec4(0.4, 0.4, 0.4, 0.0);
|
||||
// }
|
||||
|
||||
float muS = dot(n, s);
|
||||
vec3 sunLight = transmittanceWithShadow(r0, muS);
|
||||
|
||||
vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS);
|
||||
|
||||
vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st);
|
||||
vec3 groundColor = (reflectance.rgb + clouds.rgb) *
|
||||
(max(muS, 0.0) * sunLight + groundSkyLight) * sunRadiance / M_PI;
|
||||
|
||||
// Yellowish reflection from sun on oceans and rivers
|
||||
if (reflectance.w > 0.0) {
|
||||
vec3 h = normalize(s - v);
|
||||
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
|
||||
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
|
||||
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * sunRadiance;
|
||||
}
|
||||
|
||||
result = attenuation * groundColor;
|
||||
} else {
|
||||
// No hit
|
||||
result = vec3(0.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) {
|
||||
if (t > 0.0) {
|
||||
return vec3(0.0);
|
||||
} else {
|
||||
vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0);
|
||||
float isun = step(cos(M_PI / 180.0), dot(v, s)) * sunRadiance;
|
||||
return transmittance * isun;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
******* CALCULATIONS FOR SHADOWS ARE IN WORLD SPACE IN METERS *********
|
||||
***********************************************************************/
|
||||
// TODO: Change calculations for view space in KM.
|
||||
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) {
|
||||
if (shadowInfoArray[0].isShadowing) {
|
||||
vec3 pc = shadowInfoArray[0].casterPositionVec - position;
|
||||
vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader
|
||||
vec3 pc_proj = dot(pc, sc_norm) * sc_norm;
|
||||
vec3 d = pc - pc_proj;
|
||||
|
||||
float length_d = length(d);
|
||||
float length_pc_proj = length(pc_proj);
|
||||
|
||||
float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp;
|
||||
|
||||
//float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu;
|
||||
float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu;
|
||||
|
||||
if ( length_d < r_u_pi ) { // umbra
|
||||
//return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
//return vec4(1.0, 0.0, 0.0, 1.0);
|
||||
return butterworthFunc(length_d, r_u_pi, 4.0);
|
||||
}
|
||||
else if ( length_d < r_p_pi ) {// penumbra
|
||||
//return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
//return vec4(0.0, 1.0, 0.0, 1.0);
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(1.0);
|
||||
}
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 position = vs_position;
|
||||
float depth = pscDepth(position);
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
vec4 diffuse2 = texture(nightTex, vs_st);
|
||||
vec4 clouds = texture(cloudsTexture, vs_st);
|
||||
|
||||
Fragment frag;
|
||||
if (_performShading) {
|
||||
// atmosphere
|
||||
vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT);
|
||||
vec4 ndcPos;
|
||||
ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
|
||||
//ndcPos.x = ((2.0f * gl_FragCoord.x) - (2.0f * viewport.x)) / viewport.z - 1.0f;
|
||||
//ndcPos.y = 1.0f - (2.0f * gl_FragCoord.y) / viewport.w;
|
||||
ndcPos.z = (2.0f * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
|
||||
(gl_DepthRange.far - gl_DepthRange.near);
|
||||
ndcPos.w = 1.0f;
|
||||
vec4 clipPos = ndcPos / gl_FragCoord.w;
|
||||
//vec4 clipPos = ndcPos;
|
||||
//clipPos.z = -1.0;
|
||||
//clipPos.w = 1.0;
|
||||
vec4 projCoords = projInverse * clipPos;
|
||||
vec4 viewDirection = normalize(completeInverse * vec4(projCoords.xyz, 0.0));
|
||||
vec3 v = normalize(viewDirection.xyz);
|
||||
|
||||
float offset, maxLength;
|
||||
vec4 ppos = vec4(0.0);
|
||||
//if (intersectAtmosphere(planetPositionObj, v, Rt, offset, maxLength)) {
|
||||
if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) {
|
||||
// Following paper nomenclature
|
||||
float t = offset;
|
||||
vec3 x = cameraPosObj.xyz;// + offset * v;
|
||||
float r = length(x);
|
||||
float mu = dot(x, v) / r;
|
||||
vec3 s = normalize(sunPositionObj);
|
||||
|
||||
vec3 attenuation;
|
||||
vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation);
|
||||
vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation);
|
||||
vec3 sunColor = sunColor(x, t, v, s, r, mu);
|
||||
|
||||
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0));
|
||||
//diffuse = HDR(vec4(sunColor, 1.0));
|
||||
//diffuse = HDR(vec4(groundColor, 1.0));
|
||||
//diffuse = HDR(vec4(inscatterColor, 1.0));
|
||||
|
||||
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2);
|
||||
diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) *
|
||||
calcShadow(shadowDataArray, vs_posWorld.xyz) );
|
||||
}
|
||||
// else
|
||||
// diffuse = HDR(diffuse);
|
||||
}
|
||||
|
||||
diffuse[3] = transparency;
|
||||
frag.color = diffuse;
|
||||
frag.depth = depth;
|
||||
|
||||
return frag;
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform mat4 NormalTransform;
|
||||
uniform sampler2D heightTex;
|
||||
uniform bool _hasHeightMap;
|
||||
uniform float _heightExaggeration;
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
layout(location = 2) in vec3 in_normal;
|
||||
//layout(location = 3) in vec2 in_nightTex;
|
||||
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out vec4 vs_posWorld;
|
||||
out float s;
|
||||
out vec4 ray;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
// set variables
|
||||
vs_st = in_st;
|
||||
vs_position = in_position;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
//vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
|
||||
// This is the wright transformation for the normals
|
||||
vs_normal = normalize(NormalTransform * vec4(in_normal,0));
|
||||
|
||||
// The position is not in world coordinates, it is in
|
||||
// regular view/eye coordinates.
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
// Vertex position in world coordinates in meters and
|
||||
// with no powerscalling coordiantes
|
||||
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
|
||||
vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
|
||||
vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0);
|
||||
vs_posWorld = conv;
|
||||
|
||||
vs_position = tmp;
|
||||
|
||||
if (_hasHeightMap) {
|
||||
float height = texture(heightTex, in_st).r;
|
||||
vec3 displacementDirection = abs(normalize(in_normal.xyz));
|
||||
float displacementFactor = height * _heightExaggeration;
|
||||
position.xyz = position.xyz + displacementDirection * displacementFactor;
|
||||
}
|
||||
|
||||
// Now the position is transformed from view coordinates to SGCT projection
|
||||
// coordinates.
|
||||
position = ViewProjection * position;
|
||||
gl_Position = z_normalization(position);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
// See paper algorithm
|
||||
uniform int line;
|
||||
uniform sampler2D deltaETexture;
|
||||
|
||||
void main(void) {
|
||||
if (line == 4)
|
||||
renderTableColor = vec4(0.0);
|
||||
else if (line == 10) {
|
||||
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H);
|
||||
renderTableColor = texture(deltaETexture, uv);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler2D deltaETexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
uniform float first;
|
||||
|
||||
const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
|
||||
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
|
||||
float x = gl_FragCoord.x - 0.5;
|
||||
float y = gl_FragCoord.y - 0.5;
|
||||
if (y < float(RES_MU) / 2.0) {
|
||||
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
|
||||
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
|
||||
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
|
||||
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
|
||||
} else {
|
||||
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
|
||||
}
|
||||
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
|
||||
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
|
||||
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
|
||||
}
|
||||
|
||||
vec3 transmittanceFromTexture(const float r, const float mu) {
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
vec3 transmittance(const float r, const float mu, float d) {
|
||||
vec3 result;
|
||||
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
|
||||
float mu1 = (r * mu + d) / r1;
|
||||
if (mu > 0.0) {
|
||||
result = min(transmittanceFromTexture(r, mu) /
|
||||
transmittanceFromTexture(r1, mu1), 1.0);
|
||||
} else {
|
||||
result = min(transmittanceFromTexture(r1, -mu1) /
|
||||
transmittanceFromTexture(r, -mu), 1.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rayleigh phase
|
||||
float phaseFunctionR(const float mu) {
|
||||
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// Mie phase
|
||||
float phaseFunctionM(const float mu) {
|
||||
return (3.0 / (8.0 * M_PI)) *
|
||||
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
|
||||
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D calcTexture, const float r, const float mu_s) {
|
||||
float u_r = (r - Rg) / (Rt - Rg);
|
||||
float u_mu_s = (mu_s + 0.2) / (1.0 + 0.2);
|
||||
return texture(calcTexture, vec2(u_mu_s, u_r)).rgb;
|
||||
}
|
||||
|
||||
vec4 texture4D(sampler3D table, const float r, const float mu,
|
||||
const float mu_s, const float nu)
|
||||
{
|
||||
float H = sqrt(Rt * Rt - Rg * Rg);
|
||||
float rho = sqrt(r * r - Rg * Rg);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r * r + Rg * Rg;
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
|
||||
float u_r = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
|
||||
float u_mu_s = 0.5 / float(RES_MU_S) + (atan(max(mu_s, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
|
||||
float uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return texture(table, vec3((uNu + u_mu_s) / float(RES_NU), u_mu, u_r)) * (1.0 - lerp) +
|
||||
texture(table, vec3((uNu + u_mu_s + 1.0) / float(RES_NU), u_mu, u_r)) * lerp;
|
||||
}
|
||||
|
||||
void inscatter(float r, float mu, float mu_s, float nu, out vec3 raymie) {
|
||||
r = clamp(r, Rg, Rt);
|
||||
mu = clamp(mu, -1.0, 1.0);
|
||||
mu_s = clamp(mu_s, -1.0, 1.0);
|
||||
float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - mu_s * mu_s);
|
||||
nu = clamp(nu, mu_s * mu - var, mu_s * mu + var);
|
||||
|
||||
float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r));
|
||||
|
||||
vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu);
|
||||
float sx = v.x == 0.0 ? 0.0 : (nu - mu_s * mu) / v.x;
|
||||
vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - mu_s * mu_s)), mu_s);
|
||||
|
||||
raymie = vec3(0.0);
|
||||
|
||||
for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) {
|
||||
float theta = (float(itheta) + 0.5) * dtheta;
|
||||
float ctheta = cos(theta);
|
||||
|
||||
float greflectance = 0.0;
|
||||
float dground = 0.0;
|
||||
vec3 gtransp = vec3(0.0);
|
||||
if (ctheta < cthetamin) {
|
||||
greflectance = AverageGroundReflectance / M_PI;
|
||||
dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg);
|
||||
gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground);
|
||||
}
|
||||
|
||||
for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) {
|
||||
float phi = (float(iphi) + 0.5) * dphi;
|
||||
float dw = dtheta * dphi * sin(theta);
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta);
|
||||
|
||||
float nu1 = dot(s, w);
|
||||
float nu2 = dot(v, w);
|
||||
float pr2 = phaseFunctionR(nu2);
|
||||
float pm2 = phaseFunctionM(nu2);
|
||||
|
||||
vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg;
|
||||
vec3 girradiance = irradiance(deltaETexture, Rg, dot(gnormal, s));
|
||||
|
||||
vec3 raymie1;
|
||||
|
||||
raymie1 = greflectance * girradiance * gtransp;
|
||||
|
||||
if (first == 1.0) {
|
||||
float pr1 = phaseFunctionR(nu1);
|
||||
float pm1 = phaseFunctionM(nu1);
|
||||
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
|
||||
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu1).rgb;
|
||||
raymie1 += ray1 * pr1 + mie1 * pm1;
|
||||
} else {
|
||||
raymie1 += texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
|
||||
}
|
||||
|
||||
raymie += raymie1 * (betaRayleigh * exp(-(r - Rg) / HR) * pr2 + betaMieScattering * exp(-(r - Rg) / HM) * pm2) * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 raymie;
|
||||
float mu, mu_s, nu;
|
||||
getMuMuSNu(r, dhdH, mu, mu_s, nu);
|
||||
inscatter(r, mu, mu_s, nu, raymie);
|
||||
|
||||
renderTarget1 = vec4(raymie, 1.0);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform int layer;
|
||||
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
void main(void) {
|
||||
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
|
||||
vec4 ray = texture(deltaSRTexture, uvw);
|
||||
vec4 mie = texture(deltaSMTexture, uvw);
|
||||
|
||||
// We are using only the red component of the Mie scattering
|
||||
// See the Precomputed Atmosphere Scattering paper for details about
|
||||
// the angular precision.
|
||||
renderTarget1 = vec4(ray.rgb, mie.r);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
uniform float exposure;
|
||||
|
||||
vec4 HDR(vec4 color) {
|
||||
color *= exposure;
|
||||
|
||||
color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.r);
|
||||
color.g = color.g < 1.413 ? pow(color.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.g);
|
||||
color.b = color.b < 1.413 ? pow(color.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.b);
|
||||
|
||||
return color;
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
layout(location = 0) out vec4 renderTarget1;
|
||||
layout(location = 1) out vec4 renderTarget2;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
// In the following shaders r (altitude) is the length of vector/position x in the
|
||||
// atmosphere (or on the top of it when considering an observer in space),
|
||||
// where the light is comming from the opposity direction of the view direction,
|
||||
// here the vector v or viewDirection.
|
||||
// Rg is the planet radius
|
||||
|
||||
void unmappingMuMuSunNu(const float r, vec4 dhdH, out float mu, out float muSun, out float nu) {
|
||||
float x = gl_FragCoord.x - 0.5f;
|
||||
float y = gl_FragCoord.y - 0.5f;
|
||||
if (y < (float(RES_MU) / 2.0f)) {
|
||||
float d = 1.0f - y / (float(RES_MU) / 2.0f - 1.0f);
|
||||
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
|
||||
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
|
||||
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
|
||||
} else {
|
||||
float d = (y - float(RES_MU) / 2.0f) / (float(RES_MU) / 2.0f - 1.0f);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
mu = (Rt * Rt - r * r - d * d) / (2.0f * r * d);
|
||||
}
|
||||
muSun = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0f);
|
||||
muSun = tan((2.0f * muSun - 1.0f + 0.26f) * 1.1f) / tan(1.26f * 1.1f);
|
||||
nu = -1.0f + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0f) * 2.0f;
|
||||
}
|
||||
|
||||
vec3 transmittanceLUT(const float r, const float mu) {
|
||||
// Given the position x (here the altitude r) and the view
|
||||
// angle v (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
vec3 transmittance(const float r, const float mu, const float d) {
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v)
|
||||
// to, given a distance d, calculates that transmittance along
|
||||
// that distance starting in x (hight r): T(x,d) = T(x,v)/T(d,v).
|
||||
//
|
||||
// From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab)
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
float mui = (d + r * mu) / ri;
|
||||
|
||||
// It's important to remember that we calculate the Transmittance
|
||||
// table only for zenith angles between 0 and pi/2+episilon.
|
||||
// Then, if mu < 0.0, we just need to invert the view direction
|
||||
// and the start and end points between them, i.e., if
|
||||
// x --> x0, then x0-->x.
|
||||
// Also, let's use the property: T(a,c) = T(a,b)*T(b,c)
|
||||
// Because T(a,c) and T(b,c) are already in the table T,
|
||||
// T(a,b) = T(a,c)/T(b,c).
|
||||
if (mu > 0.0f) {
|
||||
return min(transmittanceLUT(r, mu) /
|
||||
transmittanceLUT(ri, mui), 1.0f);
|
||||
} else {
|
||||
return min(transmittanceLUT(ri, -mui) /
|
||||
transmittanceLUT(r, -mu), 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void integrand(const float r, const float mu, const float muSun, const float nu,
|
||||
const float y, out vec3 S_R, out vec3 S_M) {
|
||||
// The integral's integrand is the single inscattering radiance:
|
||||
// S[L0] = P_M*S_M[L0] + P_R*S_R[L0]
|
||||
// where S_M[L0] = T*(betaMScattering * exp(-h/H_M))*L0 and
|
||||
// S_R[L0] = T*(betaRScattering * exp(-h/H_R))*L0.
|
||||
// T = transmittance.
|
||||
// One must remember that because the occlusion on L0, the integrand
|
||||
// here will be equal to 0 in that cases.
|
||||
// Also it is important to remember that the phase function for the
|
||||
// Rayleigh and Mie scattering are addded during the rendering time
|
||||
// to increase the angular precision
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
// cosine law
|
||||
float ri = sqrt(r * r + y * y + 2.0 * r * mu * y);
|
||||
// Approximate and interpolate muSun_i
|
||||
float muSun_i = (nu * y + muSun * r) / ri;
|
||||
|
||||
// ri >= Rg
|
||||
ri = max(Rg, ri);
|
||||
|
||||
// If the muSun_i is smaller than the angle to horizon (no sun radiance
|
||||
// hitting the point y), we return S_R = S_M = 0.0f.
|
||||
if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
|
||||
// It's the transmittance from the point y (ri) to the top of atmosphere
|
||||
// in direction of the sun (muSun_i) and the transmittance from the observer
|
||||
// at x (r) to y (ri).
|
||||
vec3 transmittanceY = transmittance(r, mu, y) * transmittanceLUT(ri, muSun_i);
|
||||
// exp(-h/H)*T(x,v)
|
||||
S_R = exp( -(ri - Rg) / HR ) * transmittanceY;
|
||||
S_M = exp( -(ri - Rg) / HM ) * transmittanceY;
|
||||
// The L0 (sun radiance) is added in real-time.
|
||||
}
|
||||
}
|
||||
|
||||
float rayDistance(const float r, const float mu) {
|
||||
// The light ray starting at the observer in/on the atmosphere can
|
||||
// have to possible end points: the top of the atmosphere or the
|
||||
// planet ground. So the shortest path is the one we are looking for,
|
||||
// otherwise we may be passing through the ground.
|
||||
|
||||
// cosine law
|
||||
float atmRadiusEps = Rt + ATM_EPSILON;
|
||||
float rayDistanceAtmosphere = -r * mu +
|
||||
sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps);
|
||||
float delta = r * r * (mu * mu - 1.0f) + Rg * Rg;
|
||||
// No imaginary numbers... :-)
|
||||
if (delta >= 0.0f) {
|
||||
float rayDistanceGround = -r * mu - sqrt(delta);
|
||||
if (rayDistanceGround >= 0.0f) {
|
||||
return min(rayDistanceAtmosphere, rayDistanceGround);
|
||||
}
|
||||
}
|
||||
return rayDistanceAtmosphere;
|
||||
}
|
||||
|
||||
void inscatter(const float r, const float mu, const float muSun, const float nu,
|
||||
out vec3 S_R, out vec3 S_M) {
|
||||
// Let's calculate S_M and S_R by integration along the eye ray path inside
|
||||
// the atmosphere, given a position r, a view angle (cosine) mu, a sun
|
||||
// position angle (cosine) muSun, and the angle (cosine) between the sun position
|
||||
// and the view direction, nu.
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
|
||||
S_R = vec3(0.0f);
|
||||
S_M = vec3(0.0f);
|
||||
float rayDist = rayDistance(r, mu);
|
||||
float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
float yi = 0.0f;
|
||||
vec3 S_Ri;
|
||||
vec3 S_Mi;
|
||||
integrand(r, mu, muSun, nu, 0.0, S_Ri, S_Mi);
|
||||
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
|
||||
float yj = float(i) * dy;
|
||||
vec3 S_Rj;
|
||||
vec3 S_Mj;
|
||||
integrand(r, mu, muSun, nu, yj, S_Rj, S_Mj);
|
||||
S_R += (S_Ri + S_Rj);
|
||||
S_M += (S_Mi + S_Mj);
|
||||
yi = yj;
|
||||
S_Ri = S_Rj;
|
||||
S_Mi = S_Mj;
|
||||
}
|
||||
S_R *= betaRayleigh * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
S_M *= betaMieScattering * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 S_R;
|
||||
vec3 S_M;
|
||||
float mu, muSun, nu;
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
// Here we calculate the single inScattered light.
|
||||
// Because this is a single inscattering, the light
|
||||
// that arrives at a point y in the path from the
|
||||
// eye to the infinity (top of atmosphere or planet's
|
||||
// ground), comes only from the light source, i.e., the
|
||||
// sun. So, the there is no need to integrate over the
|
||||
// whole solid angle (4pi), we need only to consider
|
||||
// the Sun position (cosine of sun pos = muSun).
|
||||
// Then, following the paper notation:
|
||||
// S[L] = P_R*S_R[L0] + P_M*S_M[L0] + S[L*]
|
||||
// For single inscattering only:
|
||||
// S[L0] = P_R*S_R[L0] + P_M*S_M[L0]
|
||||
// In order to save memory, we just store the red component
|
||||
// of S_M[L0], and later we use the proportionality rule
|
||||
// to calcule the other components.
|
||||
inscatter(r, mu, muSun, nu, S_R, S_M);
|
||||
renderTarget1 = vec4(S_R, 1.0);
|
||||
renderTarget2 = vec4(S_M, 1.0);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices=3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaJTexture;
|
||||
|
||||
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
|
||||
float x = gl_FragCoord.x - 0.5;
|
||||
float y = gl_FragCoord.y - 0.5;
|
||||
if (y < float(RES_MU) / 2.0) {
|
||||
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
|
||||
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
|
||||
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
|
||||
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
|
||||
} else {
|
||||
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
|
||||
}
|
||||
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
|
||||
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
|
||||
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
|
||||
}
|
||||
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
|
||||
{
|
||||
float H = sqrt(Rt * Rt - Rg * Rg);
|
||||
float rho = sqrt(r * r - Rg * Rg);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r * r + Rg * Rg;
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
|
||||
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
|
||||
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
|
||||
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
|
||||
float uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
|
||||
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
|
||||
}
|
||||
|
||||
float limit(float r, float mu) {
|
||||
float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + ((Rt+ATM_EPSILON) * (Rt+ATM_EPSILON)));
|
||||
float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg;
|
||||
if (delta2 >= 0.0) {
|
||||
float din = -r * mu - sqrt(delta2);
|
||||
if (din >= 0.0) {
|
||||
dout = min(dout, din);
|
||||
}
|
||||
}
|
||||
return dout;
|
||||
}
|
||||
|
||||
vec3 transmittanceFromTexture(const float r, const float mu) {
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
vec3 transmittance(const float r, const float mu, const float d) {
|
||||
vec3 result;
|
||||
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
|
||||
float mu1 = (r * mu + d) / r1;
|
||||
if (mu > 0.0) {
|
||||
result = min(transmittanceFromTexture(r, mu) /
|
||||
transmittanceFromTexture(r1, mu1), 1.0);
|
||||
} else {
|
||||
result = min(transmittanceFromTexture(r1, -mu1) /
|
||||
transmittanceFromTexture(r, -mu), 1.0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 integrand(float r, float mu, float muS, float nu, float t) {
|
||||
float ri = sqrt(r * r + t * t + 2.0 * r * mu * t);
|
||||
float mui = (r * mu + t) / ri;
|
||||
float muSi = (nu * t + muS * r) / ri;
|
||||
return texture4D(deltaJTexture, ri, mui, muSi, nu).rgb * transmittance(r, mu, t);
|
||||
}
|
||||
|
||||
float rayDistance(const float r, const float mu) {
|
||||
// cosine law
|
||||
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
|
||||
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
|
||||
float distance = distanceAtmosphereIntersect;
|
||||
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
|
||||
// No imaginary numbers... :-)
|
||||
if (delta >= 0.0) {
|
||||
float distanceEarthIntersect = -r * mu - sqrt(delta);
|
||||
if (distanceEarthIntersect >= 0.0) {
|
||||
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
|
||||
}
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
vec3 inscatter(float r, float mu, float muS, float nu) {
|
||||
vec3 raymie = vec3(0.0);
|
||||
float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
float xi = 0.0;
|
||||
vec3 raymiei = integrand(r, mu, muS, nu, 0.0);
|
||||
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
|
||||
float xj = float(i) * dx;
|
||||
vec3 raymiej = integrand(r, mu, muS, nu, xj);
|
||||
raymie += (raymiei + raymiej) / 2.0 * dx;
|
||||
xi = xj;
|
||||
raymiei = raymiej;
|
||||
}
|
||||
return raymie;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float mu, muS, nu;
|
||||
getMuMuSNu(r, dhdH, mu, muS, nu);
|
||||
|
||||
renderTarget1 = vec4(inscatter(r, mu, muS, nu), 1.0);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
void unmappingRAndMuSun(out float r, out float muSun) {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(OTHER_TEXTURES_W) - 1.0f) * (1.0f + 0.2f);
|
||||
r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) - 1.0f) * (Rt - Rg);
|
||||
}
|
||||
|
||||
vec3 transmittanceLUT(const float r, const float mu) {
|
||||
// Given the position x (here the altitude r) and the view
|
||||
// angle v (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15f) / (1.0f + 0.15f) * tan(1.5f)) / 1.5f;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float muSun, r;
|
||||
unmappingRAndMuSun(r, muSun);
|
||||
// We are calculating the Irradiance for L0, i.e.,
|
||||
// only the radiance comming from sun direction is accounted:
|
||||
// E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded).
|
||||
// Because we consider the Planet as a perfect sphere and we are
|
||||
// considering only single scattering here, the
|
||||
// dot product dot(w,n) is equal to dot(s,n) that is equal to
|
||||
// dot(s, r/||r||) = muSun.
|
||||
renderTableColor = vec4(transmittanceLUT(r, muSun) * clamp(muSun, 0.0, 1.0), 0.0);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform float first;
|
||||
|
||||
const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
// Rayleigh phase
|
||||
float phaseFunctionR(const float mu) {
|
||||
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// Mie phase
|
||||
float phaseFunctionM(const float mu) {
|
||||
return (3.0 / (8.0 * M_PI)) *
|
||||
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
|
||||
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
|
||||
}
|
||||
|
||||
vec4 texture4D(sampler3D table, const float r, const float mu,
|
||||
const float muS, const float nu)
|
||||
{
|
||||
float H = sqrt(Rt * Rt - Rg * Rg);
|
||||
float rho = sqrt(r * r - Rg * Rg);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r * r + Rg * Rg;
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
|
||||
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
|
||||
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
|
||||
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
|
||||
float uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
|
||||
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY_H) - 1.0) * (Rt - Rg);
|
||||
float mu_s = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY_W) - 1.0) * (1.0 + 0.2);
|
||||
vec3 s = vec3(max(sqrt(1.0 - mu_s * mu_s), 0.0), 0.0, mu_s);
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) {
|
||||
float phi = (float(iphi) + 0.5) * dphi;
|
||||
for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) {
|
||||
float theta = (float(itheta) + 0.5) * dtheta;
|
||||
float dw = dtheta * dphi * sin(theta);
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
float nu = dot(s, w);
|
||||
if (first == 1.0) {
|
||||
float pr1 = phaseFunctionR(nu);
|
||||
float pm1 = phaseFunctionM(nu);
|
||||
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb;
|
||||
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu).rgb;
|
||||
result += (ray1 * pr1 + mie1 * pm1) * w.z * dw;
|
||||
} else {
|
||||
result += texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb * w.z * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderTableColor = vec4(result, 0.0);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -45,8 +45,6 @@ in vec4 test;
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 position = vs_position;
|
||||
float depth = pscDepth(position);
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
vec4 diffuse2 = texture(nightTex, vs_st);
|
||||
|
||||
@@ -76,7 +74,7 @@ Fragment getFragment() {
|
||||
|
||||
diffuse[3] = transparency;
|
||||
frag.color = diffuse;
|
||||
frag.depth = depth;
|
||||
frag.depth = vs_position.w;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -36,27 +36,23 @@ out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
uniform sampler2D heightTex;
|
||||
uniform bool _hasHeightMap;
|
||||
uniform float _heightExaggeration;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
void main() {
|
||||
// set variables
|
||||
vs_st = in_st;
|
||||
vs_position = in_position;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
// vs_normal = vec4(in_normal, 0.0);
|
||||
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
vs_position = tmp;
|
||||
vec4 position = vec4(tmp.xyz * pow(10, tmp. w), 1.0);
|
||||
|
||||
if (_hasHeightMap) {
|
||||
float height = texture(heightTex, in_st).r;
|
||||
@@ -64,8 +60,9 @@ void main()
|
||||
float displacementFactor = height * _heightExaggeration;
|
||||
position.xyz = position.xyz + displacementDirection * displacementFactor;
|
||||
}
|
||||
//
|
||||
position = ViewProjection * position;
|
||||
|
||||
position = modelViewProjectionTransform * position;
|
||||
vs_position = z_normalization(position);
|
||||
|
||||
gl_Position = z_normalization(position);
|
||||
gl_Position = vs_position;
|
||||
}
|
||||
+19
-17
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
@@ -21,28 +21,30 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 330
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
uniform vec4 campos;
|
||||
uniform vec4 objpos;
|
||||
//uniform vec3 camdir; // add this for specular
|
||||
|
||||
out vec4 renderTarget1;
|
||||
uniform vec3 sun_pos;
|
||||
|
||||
uniform int layer;
|
||||
uniform bool _performShading = true;
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform sampler3D deltaSTexture;
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
// Rayleigh phase
|
||||
float phaseFunctionR(const float mu) {
|
||||
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
}
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
|
||||
void main(void) {
|
||||
float x = gl_FragCoord.x - 0.5;
|
||||
float y = gl_FragCoord.y - 0.5;
|
||||
#include "fragment.glsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
float nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
|
||||
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
|
||||
//#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
Fragment getFragment() {
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
|
||||
renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / phaseFunctionR(nu), 1.0);
|
||||
}
|
||||
}
|
||||
+25
-15
@@ -2,7 +2,7 @@
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
@@ -24,25 +24,35 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ModelTransform;
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
//in vec3 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
layout(location = 2) in vec3 in_normal;
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out float s;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
uniform dmat4 completeInverse;
|
||||
uniform dmat4 projInverse;
|
||||
uniform dvec4 cameraPosObj;
|
||||
void main() {
|
||||
// set variables
|
||||
vs_st = in_st;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
out vec3 viewDirectionVS;
|
||||
out vec4 vertexPosObjVS;
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
// vs_normal = vec4(in_normal, 0.0);
|
||||
|
||||
vec4 position = vec4(tmp.xyz * pow(10, tmp.w), 1.0);
|
||||
position = modelViewProjectionTransform * position;
|
||||
|
||||
vs_position = z_normalization(position);
|
||||
|
||||
void main()
|
||||
{
|
||||
//viewDirectionVS = normalize( (completeInverse * vec4((projInverse * in_position).xyz, 0.0)).xyz - cameraPosObj.xyz);
|
||||
|
||||
//viewDirectionVS = normalize( (completeInverse * vec4(projInverse * in_position) ).xyz );
|
||||
|
||||
//viewDirectionVS = (completeInverse * projInverse * in_position).xyz;
|
||||
|
||||
vertexPosObjVS = in_position;
|
||||
gl_Position = in_position;
|
||||
gl_Position = vs_position;
|
||||
}
|
||||
@@ -37,9 +37,6 @@ uniform vec3 sunPosition;
|
||||
uniform float _nightFactor;
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 position = vs_position;
|
||||
float depth = pscDepth(position);
|
||||
|
||||
// Moving the origin to the center
|
||||
vec2 st = (vs_st - vec2(0.5)) * 2.0;
|
||||
|
||||
@@ -66,28 +63,26 @@ Fragment getFragment() {
|
||||
diffuse.a = pow(colorValue / (3*transparency), 1);
|
||||
}
|
||||
|
||||
if (hasSunPosition) {
|
||||
// The normal for the one plane depends on whether we are dealing
|
||||
// with a front facing or back facing fragment
|
||||
vec3 normal;
|
||||
// The plane is oriented on the xz plane
|
||||
// WARNING: This might not be the case for Uranus
|
||||
if (gl_FrontFacing) {
|
||||
normal = vec3(-1.0, 0.0, 0.0);
|
||||
}
|
||||
else {
|
||||
normal = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// Reduce the color of the fragment by the user factor
|
||||
// if we are facing away from the Sun
|
||||
if (dot(sunPosition, normal) < 0)
|
||||
diffuse.xyz *= _nightFactor;
|
||||
// The normal for the one plane depends on whether we are dealing
|
||||
// with a front facing or back facing fragment
|
||||
vec3 normal;
|
||||
// The plane is oriented on the xz plane
|
||||
// WARNING: This might not be the case for Uranus
|
||||
if (gl_FrontFacing) {
|
||||
normal = vec3(-1.0, 0.0, 0.0);
|
||||
}
|
||||
else {
|
||||
normal = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// Reduce the color of the fragment by the user factor
|
||||
// if we are facing away from the Sun
|
||||
if (dot(sunPosition, normal) < 0)
|
||||
diffuse.xyz *= _nightFactor;
|
||||
|
||||
Fragment frag;
|
||||
frag.color = diffuse;
|
||||
frag.depth = depth;
|
||||
frag.depth = vs_position.w;
|
||||
return frag;
|
||||
|
||||
}
|
||||
|
||||
@@ -26,22 +26,30 @@
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
layout(location = 0) in vec2 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_position;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
void main() {
|
||||
vec4 tmp = in_position;
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
vs_position = tmp;
|
||||
vs_st = in_st;
|
||||
|
||||
vs_position = z_normalization(
|
||||
modelViewProjectionTransform * vec4(in_position.xy, 0.0, 1.0)
|
||||
);
|
||||
gl_Position = vs_position;
|
||||
|
||||
// vec4 tmp = in_position;
|
||||
|
||||
|
||||
// vec4 tmp = in_position;
|
||||
// vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
// vs_position = tmp;
|
||||
|
||||
position = ViewProjection * position;
|
||||
gl_Position = z_normalization(position);
|
||||
// position = ViewProjection * position;
|
||||
// gl_Position = z_normalization(position);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ uniform mat4 projection;
|
||||
|
||||
uniform float scaleFactor;
|
||||
uniform float minBillboardSize;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
void main() {
|
||||
if ((psc_position[0].x == 0.0) && (psc_position[0].y == 0.0) && (psc_position[0].z == 0.0))
|
||||
@@ -75,7 +76,6 @@ void main() {
|
||||
|
||||
// Calculate the positions of the lower left and upper right corners of the
|
||||
// billboard in screen-space
|
||||
const vec2 screenSize = vec2(#{rendererData.windowWidth}, #{rendererData.windowHeight});
|
||||
vec2 ll = (((projPos[1].xy / projPos[1].w) + 1) / 2) * screenSize;
|
||||
vec2 ur = (((projPos[2].xy / projPos[2].w) + 1) / 2) * screenSize;
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
//layout(location = 1) out vec4 renderTableColor;
|
||||
out vec4 renderTableColor;
|
||||
|
||||
// In the following shaders r (altitude) is the length of vector/position x in the
|
||||
// atmosphere (or on the top of it when considering an observer in space),
|
||||
// where the light is comming from the opposity direction of the view direction,
|
||||
// here the vector v or viewDirection.
|
||||
// Rg is the planet radius
|
||||
|
||||
float rayDistance(const float r, const float mu) {
|
||||
// The light ray starting at the observer in/on the atmosphere can
|
||||
// have to possible end points: the top of the atmosphere or the
|
||||
// planet ground. So the shortest path is the one we are looking for,
|
||||
// otherwise we may be passing through the ground.
|
||||
|
||||
// cosine law
|
||||
float atmRadiusEps = Rt + ATM_EPSILON;
|
||||
float rayDistanceAtmosphere = -r * mu +
|
||||
sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps);
|
||||
float delta = r * r * (mu * mu - 1.0f) + Rg * Rg;
|
||||
// No imaginary numbers... :-)
|
||||
if (delta >= 0.0f) {
|
||||
float rayDistanceGround = -r * mu - sqrt(delta);
|
||||
if (rayDistanceGround >= 0.0f) {
|
||||
return min(rayDistanceAtmosphere, rayDistanceGround);
|
||||
}
|
||||
}
|
||||
return rayDistanceAtmosphere;
|
||||
}
|
||||
|
||||
float opticalDepth(const float r, const float mu, const float H) {
|
||||
float r2 = r*r;
|
||||
// Is ray below horizon? The transmittance table will have only
|
||||
// the values for transmittance starting at r (x) until the
|
||||
// light ray touches the atmosphere or the ground and only for
|
||||
// view angles v between 0 and pi/2 + eps. That's because we
|
||||
// can calculate the transmittance for angles bigger than pi/2
|
||||
// just inverting the ray direction and starting and ending points.
|
||||
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
float cosZenithHorizon = -sqrt( 1.0f - ( ( Rg * Rg ) / r2 ) );
|
||||
if (mu < cosZenithHorizon)
|
||||
return 1e9;
|
||||
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
float b_a = rayDistance(r, mu);
|
||||
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
|
||||
// cosine law
|
||||
float y_i = exp(-(r - Rg) / H);
|
||||
|
||||
float x_step = 0.0f;
|
||||
float accumulation = 0.0f;
|
||||
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
|
||||
float x_i = float(i) * deltaStep;
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
// In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu
|
||||
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H);
|
||||
accumulation += (y_ii + y_i);
|
||||
//x_step = x_i;
|
||||
y_i = y_ii;
|
||||
}
|
||||
return accumulation * ( b_a / ( 2 * TRANSMITTANCE_STEPS ) );
|
||||
}
|
||||
|
||||
void unmappingRAndMu(out float r, out float mu) {
|
||||
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W);
|
||||
float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H);
|
||||
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
r = sqrt( Rg * Rg + (u_r * u_r) * (Rt * Rt - Rg * Rg) );
|
||||
|
||||
// In the paper the author suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Colliene.
|
||||
mu = -0.15f + tan(1.5f * u_mu) / tan(1.5f) * (1.0f + 0.15f);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float r, muSun;
|
||||
unmappingRAndMu(r, muSun);
|
||||
vec3 opDepth = betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
|
||||
renderTableColor = vec4( exp( -opDepth ), 0.0f );
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -130,6 +130,9 @@ SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addProperty(_target);
|
||||
addProperty(_origin);
|
||||
}
|
||||
|
||||
glm::dvec3 SpiceTranslation::position() const {
|
||||
|
||||
Reference in New Issue
Block a user