Merged develop in NewAtmosphere.

This commit is contained in:
Jonathas Costa
2016-11-11 14:46:14 -05:00
294 changed files with 16113 additions and 14867 deletions
+5 -1
View File
@@ -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()
};
}
+42 -30
View File
@@ -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
+3 -1
View File
@@ -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;
+31 -13
View File
@@ -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;
}
+5 -2
View File
@@ -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;
};
+1
View File
@@ -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
+5 -133
View File
@@ -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
+126 -112
View File
@@ -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
+5 -8
View File
@@ -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
+1 -2
View File
@@ -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);
+77 -38
View File
@@ -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
+7 -5
View File
@@ -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
+54 -16
View File
@@ -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
+10 -7
View File
@@ -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;
}
-505
View File
@@ -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;
}
-86
View File
@@ -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);
}
-41
View File
@@ -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);
}
}
-31
View File
@@ -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);
}
-186
View File
@@ -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);
}
-41
View File
@@ -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();
}
-31
View File
@@ -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
View File
@@ -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);
}
-41
View File
@@ -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();
}
-31
View File
@@ -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);
}
-35
View File
@@ -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);
}
+1 -3
View File
@@ -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;
}
+7 -10
View File
@@ -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;
}
@@ -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);
}
}
@@ -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;
}
+16 -21
View File
@@ -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;
}
+17 -9
View File
@@ -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);
}
+1 -1
View File
@@ -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 {