Removed unused files and started cleanup of atm module for future merging with master.

This commit is contained in:
Jonathas Costa
2017-06-14 15:45:42 -04:00
parent 14155f6322
commit 5742e09335
29 changed files with 578 additions and 4410 deletions

View File

@@ -34,7 +34,7 @@ return {
Body = "EARTH",
Geometry = {
Type = "SimpleSphere",
Radius = 6.371E6,
Radius = 6.3781365E6,
Segments = 100
},
Textures = {
@@ -49,7 +49,7 @@ return {
--AtmoshereRadius = 6420.0,
AtmoshereRadius = 6447.0,
--PlanetRadius = 6378.137,
PlanetRadius = 6377.0,
PlanetRadius = 6356.752,
--PlanetRadius = 6360.0,
PlanetAverageGroundReflectance = 0.1,
Rayleigh = {

View File

@@ -26,20 +26,48 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmospheredeferredcaster.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplanetatmosphere.h
)
source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmospheredeferredcaster.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplanetatmosphere.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
set(SHADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shaders/atmosphere_common.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deferred_test_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaE_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaE_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_gs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_gs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_gs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/hdr.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_gs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_gs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_final_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_final_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_sup_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_sup_calc_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/transmittance_calc_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/transmittance_calc_fs.glsl
)
source_group("Shader Files" FILES ${SHADER_FILES})
create_new_module(
"Atmosphere"
atmosphere_module
${HEADER_FILES} ${SOURCE_FILES}
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)

View File

@@ -23,12 +23,11 @@
****************************************************************************************/
#include <modules/atmosphere/atmospheremodule.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <modules/atmosphere/rendering/renderableplanetatmosphere.h>
#include <openspace/rendering/renderable.h>
//#include <modules/atmosphere/rendering/renderableplanetatmosphere.h>
namespace openspace {
@@ -37,7 +36,7 @@ AtmosphereModule::AtmosphereModule() : OpenSpaceModule("Atmosphere") {}
void AtmosphereModule::internalInitialize() {
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "No renderable factory existed");
fRenderable->registerClass<RenderablePlanetAtmosphere>("RenderablePlanetAtmosphere");
//fRenderable->registerClass<RenderablePlanetAtmosphere>("RenderablePlanetAtmosphere");
}
} // namespace openspace

View File

@@ -50,8 +50,8 @@
namespace {
const std::string _loggerCat = "AtmosphereDeferredcaster";
const char* GlslDeferredcastPath = "${MODULES}/atmosphere/shaders/deferred_test_fs.glsl";
const char* GlslDeferredcastFSPath = "${MODULES}/atmosphere/shaders/deferred_test_fs.glsl";
const char* GlslDeferredcastPath = "${MODULES}/atmosphere/shaders/atmosphere_deferred_fs.glsl";
const char* GlslDeferredcastFSPath = "${MODULES}/atmosphere/shaders/atmosphere_deferred_fs.glsl";
const char* GlslDeferredcastVsPath = "${MODULES}/atmosphere/shaders/atmosphere_deferred_vs.glsl";
}

View File

@@ -1,131 +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. *
****************************************************************************************/
#include <modules/atmosphere/rendering/atmosphereraycaster.h>
#include <glm/glm.hpp>
#include <ghoul/opengl/ghoul_gl.h>
#include <sstream>
#include <ghoul/opengl/programobject.h>
#include <openspace/util/powerscaledcoordinate.h>
#include <openspace/util/updatestructures.h>
#include <openspace/rendering/renderable.h>
namespace {
const std::string GlslRaycastPath = "${MODULES}/atmosphere/shaders/raycast.glsl";
const std::string GlslBoundsVsPath = "${MODULES}/atmosphere/shaders/boundsvs.glsl";
const std::string GlslBoundsFsPath = "${MODULES}/atmosphere/shaders/boundsfs.glsl";
}
namespace openspace {
AtmosphereRaycaster::AtmosphereRaycaster(glm::vec4 color)
: _boundingBox(glm::vec3(1.0))
, _color(color) {}
AtmosphereRaycaster::~AtmosphereRaycaster() {}
void AtmosphereRaycaster::initialize() {
_boundingBox.initialize();
}
void AtmosphereRaycaster::deinitialize() {
}
void AtmosphereRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
program.setUniform("modelTransform", _modelTransform);
program.setUniform("viewProjection", data.camera.viewProjectionMatrix());
Renderable::setPscUniforms(program, data.camera, data.position);
// Cull back face
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// Render bounding geometry
_boundingBox.render();
}
void AtmosphereRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
// Uniforms
program.setUniform("modelTransform", _modelTransform);
program.setUniform("viewProjection", data.camera.viewProjectionMatrix());
Renderable::setPscUniforms(program, data.camera, data.position);
// Cull front face
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
// Render bounding geometry
_boundingBox.render();
// Restore defaults
glCullFace(GL_BACK);
}
void AtmosphereRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
std::string colorUniformName = "color" + std::to_string(data.id);
std::string timeUniformName = "time" + std::to_string(data.id);
std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id);
program.setUniform(colorUniformName, _color);
program.setUniform(stepSizeUniformName, _stepSize);
program.setUniform(timeUniformName, static_cast<float>(std::fmod(_time, 3600.0)));
}
void AtmosphereRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
// For example: release texture units
}
std::string AtmosphereRaycaster::getBoundsVsPath() const {
return GlslBoundsVsPath;
}
std::string AtmosphereRaycaster::getBoundsFsPath() const {
return GlslBoundsFsPath;
}
std::string AtmosphereRaycaster::getRaycastPath() const {
return GlslRaycastPath;
}
std::string AtmosphereRaycaster::getHelperPath() const {
return ""; // no helper file
}
void AtmosphereRaycaster::setColor(glm::vec4 color) {
_color = color;
}
void AtmosphereRaycaster::setModelTransform(glm::mat4 transform) {
_modelTransform = transform;
}
void AtmosphereRaycaster::setTime(double time) {
_time = time;
}
void AtmosphereRaycaster::setStepSize(float stepSize) {
_stepSize = stepSize;
}
}

View File

@@ -1,80 +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. *
****************************************************************************************/
#ifndef __ATMOSPHERERAYCASTER_H__
#define __ATMOSPHERERAYCASTER_H__
#include <ghoul/glm.h>
#include <string>
#include <vector>
#include <openspace/rendering/volumeraycaster.h>
#include <openspace/util/boxgeometry.h>
#include <openspace/util/blockplaneintersectiongeometry.h>
namespace ghoul {
namespace opengl {
class Texture;
class ProgramObject;
}
}
namespace openspace {
struct RenderData;
struct RaycastData;
class AtmosphereRaycaster : public VolumeRaycaster {
public:
AtmosphereRaycaster(glm::vec4 color);
virtual ~AtmosphereRaycaster();
void initialize();
void deinitialize();
void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
std::string getBoundsVsPath() const override;
std::string getBoundsFsPath() const override;
std::string getRaycastPath() const override;
std::string getHelperPath() const override;
void setColor(glm::vec4 color);
void setModelTransform(glm::mat4 transform);
void setTime(double time);
void setStepSize(float time);
private:
BoxGeometry _boundingBox;
glm::vec4 _color;
glm::mat4 _modelTransform;
float _stepSize;
double _time;
}; // AtmosphereRaycaster
} // openspace
#endif // __ATMOSPHERERAYCASTER_H__

View File

@@ -1,133 +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. *
****************************************************************************************/
#include <modules/atmosphere/rendering/renderableatmosphere.h>
#include <modules/atmosphere/rendering/atmosphereraycaster.h>
#include <openspace/rendering/renderable.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/raycastermanager.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <ghoul/opengl/ghoul_gl.h>
namespace openspace {
RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _scalingExponent("scalingExponent", "Scaling Exponent", 1, -10, 20)
, _stepSize("stepSize", "Step Size", 0.02, 0.01, 1)
, _scaling("scaling", "Scaling", glm::vec3(1.0, 1.0, 1.0), glm::vec3(0.0), glm::vec3(10.0))
, _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0))
, _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28))
, _color("color", "Color", glm::vec4(1.0, 0.0, 0.0, 0.1), glm::vec4(0.0), glm::vec4(1.0)) {
float scalingExponent, stepSize;
glm::vec3 scaling, translation, rotation;
glm::vec4 color;
if (dictionary.getValue("ScalingExponent", scalingExponent)) {
_scalingExponent = scalingExponent;
}
if (dictionary.getValue("Scaling", scaling)) {
_scaling = scaling;
}
if (dictionary.getValue("Translation", translation)) {
_translation = translation;
}
if (dictionary.getValue("Rotation", rotation)) {
_rotation = rotation;
}
if (dictionary.getValue("Color", color)) {
_color = color;
}
if (dictionary.getValue("StepSize", stepSize)) {
_stepSize = stepSize;
}
}
RenderableAtmosphere::~RenderableAtmosphere() {}
bool RenderableAtmosphere::initialize() {
_raycaster = std::make_unique<AtmosphereRaycaster>(_color);
_raycaster->initialize();
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
std::function<void(bool)> onChange = [&](bool enabled) {
if (enabled) {
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
}
else {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
}
};
onEnabledChange(onChange);
addProperty(_scaling);
addProperty(_scalingExponent);
addProperty(_stepSize);
addProperty(_translation);
addProperty(_rotation);
addProperty(_color);
return true;
}
bool RenderableAtmosphere::deinitialize() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
}
return true;
}
bool RenderableAtmosphere::isReady() const {
return true;
}
void RenderableAtmosphere::update(const UpdateData& data) {
if (_raycaster) {
glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast<glm::vec3>(_translation) * std::pow(10.0f, static_cast<float>(_scalingExponent)));
glm::vec3 eulerRotation = static_cast<glm::vec3>(_rotation);
transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0));
transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0));
transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1));
transform = glm::scale(transform, static_cast<glm::vec3>(_scaling) * std::pow(10.0f, static_cast<float>(_scalingExponent)));
_raycaster->setColor(_color);
_raycaster->setStepSize(_stepSize);
_raycaster->setModelTransform(transform);
_raycaster->setTime(data.time.j2000Seconds());
}
}
void RenderableAtmosphere::render(const RenderData& data, RendererTasks& tasks) {
RaycasterTask task{ _raycaster.get(), data };
tasks.raycasterTasks.push_back(task);
}
}

View File

@@ -1,63 +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. *
****************************************************************************************/
#ifndef __RENDERABLEATMOSPHERE_H__
#define __RENDERABLEATMOSPHERE_H__
#include <openspace/properties/vectorproperty.h>
#include <openspace/util/boxgeometry.h>
#include <openspace/util/blockplaneintersectiongeometry.h>
#include <openspace/rendering/renderable.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <modules/atmosphere/rendering/atmosphereraycaster.h>
namespace openspace {
struct RenderData;
class RenderableAtmosphere : public Renderable {
public:
RenderableAtmosphere(const ghoul::Dictionary& dictionary);
~RenderableAtmosphere();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
private:
properties::Vec3Property _scaling;
properties::IntProperty _scalingExponent;
properties::FloatProperty _stepSize;
properties::Vec3Property _translation;
properties::Vec3Property _rotation;
properties::Vec4Property _color;
std::unique_ptr<AtmosphereRaycaster> _raycaster;
};
}
#endif // __RENDERABLEATMOSPHERE_H__

View File

@@ -1,987 +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. *
****************************************************************************************/
// open space includes
#include <modules/atmosphere/rendering/renderableplanetatmosphere.h>
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/deferredcastermanager.h>
#include <modules/space/rendering/planetgeometry.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <openspace/scene/scenegraphnode.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/assert.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <glm/gtx/string_cast.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <memory>
#include <fstream>
#include <ostream>
#define _USE_MATH_DEFINES
#include <math.h>
#define _ATMOSPHERE_DEBUG
//#define _SAVE_ATMOSPHERE_TEXTURES
namespace {
const std::string _loggerCat = "RenderablePlanetAtmosphere";
const std::string keyFrame = "Frame";
const std::string keyGeometry = "Geometry";
const std::string keyDebug = "Debug";
const std::string keyRadius = "Radius";
const std::string keyShading = "PerformShading";
const std::string keyShadowGroup = "Shadow_Group";
const std::string keyShadowSource = "Source";
const std::string keyShadowCaster = "Caster";
const std::string keyAtmosphere = "Atmosphere";
const std::string keyAtmosphereRadius = "AtmoshereRadius";
const std::string keyPlanetRadius = "PlanetRadius";
const std::string keyAverageGroundReflectance = "PlanetAverageGroundReflectance";
const std::string keyRayleigh = "Rayleigh";
const std::string keyRayleighHeightScale = "H_R";
const std::string keyOzone = "Ozone";
const std::string keyOzoneHeightScale = "H_O";
const std::string keyMie = "Mie";
const std::string keyMieHeightScale = "H_M";
const std::string keyMiePhaseConstant = "G";
const std::string keyBody = "Body";
const std::string keyTextureScale = "PreCalculatedTextureScale";
const std::string keySaveTextures = "SaveCalculatedTextures";
}
namespace openspace {
RenderablePlanetAtmosphere::RenderablePlanetAtmosphere(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath("colorTexture", "Color Texture")
, _nightTexturePath("nightTexture", "Night Texture")
, _heightMapTexturePath("heightMap", "Heightmap Texture")
, _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 10.f)
, _programObject(nullptr)
, _texture(nullptr)
, _nightTexture(nullptr)
, _heightMapTexture(nullptr)
, _geometry(nullptr)
, _performShading("performShading", "Perform Shading", true)
, _rotation("rotation", "Rotation", 0, 0, 360)
, _alpha(1.f)
, _planetRadius(0.f)
, _atmosphereRadius(0.f)
, _atmospherePlanetRadius(0.f)
, _planetAverageGroundReflectance(0.f)
, _rayleighHeightScale(0.f)
, _mieHeightScale(0.f)
, _miePhaseConstant(0.f)
, _mieExtinctionCoeff(glm::vec3(0.f))
, _rayleighScatteringCoeff(glm::vec3(0.f))
, _mieScatteringCoeff(glm::vec3(0.f))
, _sunRadianceIntensity(50.0f)
, _hdrConstant(0.4f)
, _atmosphereEnabled(false)
, _hasNightTexture(false)
, _hasHeightTexture(false)
, _shadowEnabled(false)
, _atmosphereHeightP("atmmosphereHeight", "Atmosphere Height (KM)", 60.0f, 0.1f, 1000.0f)
, _groundAverageReflectanceP("averageGroundReflectance", "Average Ground Reflectance (%)", 0.1f, 0.0f, 1.0f)
, _rayleighHeightScaleP("rayleighHeightScale", "Rayleigh Height Scale (KM)", 8.0f, 0.1f, 20.0f)
, _rayleighScatteringCoeffXP("rayleighScatteringCoeffX", "Rayleigh Scattering Coeff X (x10e-3)", 1.0f, 0.01f, 100.0f)
, _rayleighScatteringCoeffYP("rayleighScatteringCoeffY", "Rayleigh Scattering Coeff Y (x10e-3)", 1.0f, 0.01f, 100.0f)
, _rayleighScatteringCoeffZP("rayleighScatteringCoeffZ", "Rayleigh Scattering Coeff Z (x10e-3)", 1.0f, 0.01f, 100.0f)
, _mieHeightScaleP("mieHeightScale", "Mie Height Scale (KM)", 1.2f, 0.1f, 20.0f)
, _mieScatteringCoefficientP("mieScatteringCoefficient", "Mie Scattering Coefficient (x10e-3)", 4.0f, 0.01f, 1000.0f)
, _mieScatteringExtinctionPropCoefficientP("mieScatteringExtinctionPropCoefficient",
"Mie Scattering/Extinction Proportion Coefficient (%)", 0.9f, 0.01f, 1.0f)
, _mieAsymmetricFactorGP("mieAsymmetricFactorG", "Mie Asymmetric Factor G", 0.85f, -1.0f, 1.0f)
, _sunIntensityP("sunIntensity", "Sun Intensity", 50.0f, 0.1f, 1000.0f)
, _hdrExpositionP("hdrExposition", "HDR", 0.4f, 0.01f, 5.0f)
, _saveCalculationsToTexture(false)
, _preCalculatedTexturesScale(1.0)
{
std::string name;
bool success = dictionary.getValue(SceneGraphNode::KeyName, name);
ghoul_assert(
success,
std::string("RenderablePlanetAtmosphere need the '") + SceneGraphNode::KeyName +
"' be specified"
);
//=======================================================
//======== Reads Geometry Entries in mod file =============
//=======================================================
ghoul::Dictionary geometryDictionary;
success = dictionary.getValue(keyGeometry, geometryDictionary);
glm::dvec3 radius;
bool accutareRadius = false;
try {
SpiceManager::ref().getValue(name, "RADII", radius);
accutareRadius = true;
}
catch (const SpiceManager::SpiceException& e) {
accutareRadius = false;
}
if (accutareRadius) {
radius *= 1000.0; // Spice gives radii in KM.
std::swap(radius[1], radius[2]); // z is equivalent to y in our coordinate system
geometryDictionary.setValue(keyRadius, radius);
}
if (success) {
_geometry = planetgeometry::PlanetGeometry::createFromDictionary(geometryDictionary);
float planetRadius;
if (accutareRadius) {
_planetRadius = (radius[0] + radius[1] + radius[2]) / 3.0;
}
else if (geometryDictionary.getValue(keyRadius, planetRadius)) {
_planetRadius = planetRadius;
}
else {
LWARNING("No Radius value specified for " << name << " planet.");
}
}
//===============================================================
//======== Reads Body and Frame Entries in mod file =============
//===============================================================
dictionary.getValue(keyFrame, _frame);
dictionary.getValue(keyBody, _target);
//============================================================
//======== Reads the Texture Entries in mod file =============
//============================================================
// TODO: textures need to be replaced by a good system similar to the geometry as soon
// as the requirements are fixed (ab)
std::string texturePath = "";
success = dictionary.getValue("Textures.Color", texturePath);
if (success)
_colorTexturePath = absPath(texturePath);
std::string nightTexturePath = "";
dictionary.getValue("Textures.Night", nightTexturePath);
if (nightTexturePath != "") {
_hasNightTexture = true;
_nightTexturePath = absPath(nightTexturePath);
}
std::string heightMapTexturePath = "";
dictionary.getValue("Textures.Height", heightMapTexturePath);
if (heightMapTexturePath != "") {
_hasHeightTexture = true;
_heightMapTexturePath = absPath(heightMapTexturePath);
}
//=======================================================
//=========== Adding Textures as Properties =============
//=======================================================
addPropertySubOwner(_geometry.get());
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderablePlanetAtmosphere::loadTexture, this));
addProperty(_nightTexturePath);
_nightTexturePath.onChange(std::bind(&RenderablePlanetAtmosphere::loadTexture, this));
addProperty(_heightMapTexturePath);
_heightMapTexturePath.onChange(std::bind(&RenderablePlanetAtmosphere::loadTexture, this));
addProperty(_heightExaggeration);
//=========================================================
//======== Shading and Rotation as Properties =============
//=========================================================
if (dictionary.hasKeyAndValue<bool>(keyShading)) {
bool shading;
dictionary.getValue(keyShading, shading);
_performShading = shading;
}
addProperty(_performShading);
// Mainly for debugging purposes @AA
addProperty(_rotation);
//================================================================
//======== Reads Shadow (Eclipses) Entries in mod file ===========
//================================================================
ghoul::Dictionary shadowDictionary;
success = dictionary.getValue(keyShadowGroup, shadowDictionary);
bool disableShadows = false;
if (success) {
std::vector< std::pair<std::string, float > > sourceArray;
unsigned int sourceCounter = 1;
while (success) {
std::string sourceName;
std::stringstream ss;
ss << keyShadowSource << sourceCounter << ".Name";
success = shadowDictionary.getValue(ss.str(), sourceName);
if (success) {
float sourceRadius;
ss.str(std::string());
ss << keyShadowSource << sourceCounter << ".Radius";
success = shadowDictionary.getValue(ss.str(), sourceRadius);
if (success) {
sourceArray.push_back(std::pair< std::string, float>(
sourceName, sourceRadius));
}
else {
LWARNING("No Radius value expecified for Shadow Source Name "
<< sourceName << " from " << name
<< " planet.\nDisabling shadows for this planet.");
disableShadows = true;
break;
}
}
sourceCounter++;
}
if (!disableShadows && !sourceArray.empty()) {
success = true;
std::vector< std::pair<std::string, float > > casterArray;
unsigned int casterCounter = 1;
while (success) {
std::string casterName;
std::stringstream ss;
ss << keyShadowCaster << casterCounter << ".Name";
success = shadowDictionary.getValue(ss.str(), casterName);
if (success) {
float casterRadius;
ss.str(std::string());
ss << keyShadowCaster << casterCounter << ".Radius";
success = shadowDictionary.getValue(ss.str(), casterRadius);
if (success) {
casterArray.push_back(std::pair< std::string, float>(
casterName, casterRadius));
}
else {
LWARNING("No Radius value expecified for Shadow Caster Name "
<< casterName << " from " << name
<< " planet.\nDisabling shadows for this planet.");
disableShadows = true;
break;
}
}
casterCounter++;
}
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
for (const auto & source : sourceArray)
for (const auto & caster : casterArray) {
ShadowConf sc;
sc.source = source;
sc.caster = caster;
_shadowConfArray.push_back(sc);
}
_shadowEnabled = true;
}
}
}
//================================================================
//========== Reads Atmosphere Entries from mod file ==============
//================================================================
bool errorReadingAtmosphereData = false;
ghoul::Dictionary atmosphereDictionary;
success = dictionary.getValue(keyAtmosphere, atmosphereDictionary);
if (success) {
if (!atmosphereDictionary.getValue(keyAtmosphereRadius, _atmosphereRadius)) {
errorReadingAtmosphereData = true;
LWARNING("No Atmosphere Radius value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!atmosphereDictionary.getValue(keyPlanetRadius, _atmospherePlanetRadius)) {
errorReadingAtmosphereData = true;
LWARNING("No Planet Radius value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!atmosphereDictionary.getValue(keyAverageGroundReflectance, _planetAverageGroundReflectance)) {
errorReadingAtmosphereData = true;
LWARNING("No Average Atmosphere Ground Reflectance value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
ghoul::Dictionary rayleighDictionary;
success = atmosphereDictionary.getValue(keyRayleigh, rayleighDictionary);
if (success) {
// Not using right now.
glm::vec3 rayleighWavelengths;
success = rayleighDictionary.getValue("Coefficients.Wavelengths", rayleighWavelengths);
if (!rayleighDictionary.getValue("Coefficients.Scattering", _rayleighScatteringCoeff)) {
errorReadingAtmosphereData = true;
LWARNING("No Rayleigh Scattering parameters expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!rayleighDictionary.getValue(keyRayleighHeightScale, _rayleighHeightScale)) {
errorReadingAtmosphereData = true;
LWARNING("No Rayleigh Height Scale value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
}
else {
errorReadingAtmosphereData = true;
LWARNING("No Rayleigh parameters expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
ghoul::Dictionary mieDictionary;
success = atmosphereDictionary.getValue(keyMie, mieDictionary);
if (success) {
if (!mieDictionary.getValue(keyMieHeightScale, _mieHeightScale)) {
errorReadingAtmosphereData = true;
LWARNING("No Mie Height Scale value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!mieDictionary.getValue("Coefficients.Scattering", _mieScatteringCoeff)) {
errorReadingAtmosphereData = true;
LWARNING("No Mie Scattering parameters expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!mieDictionary.getValue("Coefficients.Extinction", _mieExtinctionCoeff)) {
errorReadingAtmosphereData = true;
LWARNING("No Mie Extinction parameters expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
if (!mieDictionary.getValue(keyMiePhaseConstant, _miePhaseConstant)) {
errorReadingAtmosphereData = true;
LWARNING("No Mie Phase Constant value expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
}
else {
errorReadingAtmosphereData = true;
LWARNING("No Mie parameters expecified for Atmosphere Effects of "
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
ghoul::Dictionary debugDictionary;
success = atmosphereDictionary.getValue(keyDebug, debugDictionary);
if (success) {
if (debugDictionary.getValue(keyTextureScale, _preCalculatedTexturesScale)) {
LDEBUG("Atmosphere Texture Scaled to " << _preCalculatedTexturesScale);
}
if (debugDictionary.getValue(keySaveTextures, _saveCalculationsToTexture)) {
LDEBUG("Saving Precalculated Atmosphere Textures.");
}
}
if (!errorReadingAtmosphereData) {
_atmosphereEnabled = true;
//========================================================
//============== Atmosphere Properties ===================
//========================================================
_atmosphereHeightP.set(_atmosphereRadius - _atmospherePlanetRadius);
_atmosphereHeightP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_atmosphereHeightP);
_groundAverageReflectanceP.set(_planetAverageGroundReflectance);
_groundAverageReflectanceP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_groundAverageReflectanceP);
_rayleighHeightScaleP.set(_rayleighHeightScale);
_rayleighHeightScaleP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_rayleighHeightScaleP);
_rayleighScatteringCoeffXP.set(_rayleighScatteringCoeff.x * 1000.0f);
_rayleighScatteringCoeffXP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_rayleighScatteringCoeffXP);
_rayleighScatteringCoeffYP.set(_rayleighScatteringCoeff.y * 1000.0f);
_rayleighScatteringCoeffYP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_rayleighScatteringCoeffYP);
_rayleighScatteringCoeffZP.set(_rayleighScatteringCoeff.z * 1000.0f);
_rayleighScatteringCoeffZP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_rayleighScatteringCoeffZP);
_mieHeightScaleP.set(_mieHeightScale);
_mieHeightScaleP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_mieHeightScaleP);
_mieScatteringCoefficientP.set(_mieScatteringCoeff.r * 1000.0f);
_mieScatteringCoefficientP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_mieScatteringCoefficientP);
_mieScatteringExtinctionPropCoefficientP.set(_mieScatteringCoeff.r / _mieExtinctionCoeff.r);
_mieScatteringExtinctionPropCoefficientP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_mieScatteringExtinctionPropCoefficientP);
_mieAsymmetricFactorGP.set(_miePhaseConstant);
_mieAsymmetricFactorGP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_mieAsymmetricFactorGP);
_sunIntensityP.set(_sunRadianceIntensity);
_sunIntensityP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_sunIntensityP);
_hdrExpositionP.set(_hdrConstant);
_hdrExpositionP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this));
addProperty(_hdrExpositionP);
}
}
}
RenderablePlanetAtmosphere::~RenderablePlanetAtmosphere() {
}
bool RenderablePlanetAtmosphere::initialize() {
RenderEngine& renderEngine = OsEng.renderEngine();
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Checking System State before initialization. OpenGL error: " << errString);
}
//===================================================================
//=========== Defines the shading program to be executed ============
//===================================================================
if (_programObject == nullptr && _shadowEnabled && _hasNightTexture) {
// shadow program
_programObject = renderEngine.buildRenderProgram(
"shadowNightProgram",
"${MODULE_ATMOSPHERE}/shaders/shadow_nighttexture_vs.glsl",
"${MODULE_ATMOSPHERE}/shaders/shadow_nighttexture_fs.glsl");
if (!_programObject)
return false;
std::cout << "-- Running ShadowNightProgram --" << std::endl;
}
else if (_programObject == nullptr && _shadowEnabled) {
// shadow program
_programObject = renderEngine.buildRenderProgram(
"shadowProgram",
"${MODULE_ATMOSPHERE}/shaders/shadow_vs.glsl",
"${MODULE_ATMOSPHERE}/shaders/shadow_fs.glsl");
if (!_programObject)
return false;
std::cout << "-- Running ShadowProgram --" << std::endl;
}
else if (_programObject == nullptr && _hasNightTexture) {
// Night texture program
_programObject = renderEngine.buildRenderProgram(
"nightTextureProgram",
"${MODULE_ATMOSPHERE}/shaders/nighttexture_vs.glsl",
"${MODULE_ATMOSPHERE}/shaders/nighttexture_fs.glsl");
if (!_programObject)
return false;
std::cout << "-- Running NightTextureProgram --" << std::endl;
}
else if (_programObject == nullptr) {
// pscstandard
_programObject = renderEngine.buildRenderProgram(
"pscstandard",
"${MODULE_ATMOSPHERE}/shaders/renderableplanet_vs.glsl",
"${MODULE_ATMOSPHERE}/shaders/renderableplanet_fs.glsl");
if (!_programObject)
return false;
std::cout << "-- Running PSCStandard --" << std::endl;
}
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
_programObject->setIgnoreUniformLocationError(IgnoreError::Yes);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error after loading shading programs. OpenGL error: " << errString);
}
//========================================================================
//======== Initialize the current geometry (SimpleSphereGeometry) ========
//========================================================================
_geometry->initialize(this);
// Deactivate any previously activated shader program.
_programObject->deactivate();
//===================================================================
//=========== Load textures defined in mod file to GPU ==============
//===================================================================
loadTexture();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error loading textures. OpenGL error: " << errString);
}
// Testing Deferredcaster
_deferredcaster = std::make_unique<AtmosphereDeferredcaster>();
if (_deferredcaster) {
_deferredcaster->setAtmosphereRadius(_atmosphereRadius);
_deferredcaster->setPlanetRadius(_atmospherePlanetRadius);
_deferredcaster->setPlanetAverageGroundReflectance(_planetAverageGroundReflectance);
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
_deferredcaster->setMieHeightScale(_mieHeightScale);
_deferredcaster->setMiePhaseConstant(_miePhaseConstant);
_deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity);
_deferredcaster->setHDRConstant(_hdrConstant);
_deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff);
_deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff);
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
_deferredcaster->setRenderableClass(AtmosphereDeferredcaster::RenderablePlanet);
_deferredcaster->setPrecalculationTextureScale(_preCalculatedTexturesScale);
if (_saveCalculationsToTexture)
_deferredcaster->enablePrecalculationTexturesSaving();
_deferredcaster->initialize();
}
OsEng.renderEngine().deferredcasterManager().attachDeferredcaster(*_deferredcaster.get());
std::function<void(bool)> onChange = [&](bool enabled) {
if (enabled) {
OsEng.renderEngine().deferredcasterManager().attachDeferredcaster(*_deferredcaster.get());
}
else {
OsEng.renderEngine().deferredcasterManager().detachDeferredcaster(*_deferredcaster.get());
}
};
onEnabledChange(onChange);
return isReady();
}
bool RenderablePlanetAtmosphere::deinitialize() {
if (_geometry) {
_geometry->deinitialize();
_geometry = nullptr;
}
RenderEngine& renderEngine = OsEng.renderEngine();
if (_programObject) {
renderEngine.removeRenderProgram(_programObject);
_programObject = nullptr;
}
_geometry = nullptr;
_texture = nullptr;
_nightTexture = nullptr;
// Testing Deferredcaster
if (_deferredcaster) {
OsEng.renderEngine().deferredcasterManager().detachDeferredcaster(*_deferredcaster.get());
_deferredcaster = nullptr;
}
return true;
}
bool RenderablePlanetAtmosphere::isReady() const {
bool ready = true;
ready &= (_programObject != nullptr);
ready &= (_texture != nullptr);
ready &= (_geometry != nullptr);
return ready;
}
void RenderablePlanetAtmosphere::computeModelTransformMatrix(glm::mat4 * modelTransform) {
// scale the planet to appropriate size since the planet is a unit sphere
*modelTransform = glm::mat4(1);
//earth needs to be rotated for that to work.
glm::mat4 rot = glm::rotate(*modelTransform, static_cast<float>(M_PI_2), glm::vec3(1, 0, 0));
glm::mat4 roty = glm::rotate(*modelTransform, static_cast<float>(M_PI_2), glm::vec3(0, -1, 0));
glm::mat4 rotProp = glm::rotate(*modelTransform, glm::radians(static_cast<float>(_rotation)), glm::vec3(0, 1, 0));
// _stateMatrix is the Matrix transformation from _frame coordinate system (Earth in this case)
// to "GALATIC" coordinate system.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
(*modelTransform)[i][j] = static_cast<float>(_stateMatrix[i][j]);
}
}
*modelTransform = *modelTransform * rot * roty * rotProp;
}
void RenderablePlanetAtmosphere::computeModelTransformMatrix(glm::dmat4 * modelTransform) {
// scale the planet to appropriate size since the planet is a unit sphere
*modelTransform = glm::dmat4(1);
//earth needs to be rotated for that to work.
glm::dmat4 rot = glm::rotate(*modelTransform, static_cast<double>(M_PI_2), glm::dvec3(1, 0, 0));
glm::dmat4 roty = glm::rotate(*modelTransform, static_cast<double>(M_PI_2), glm::dvec3(0, -1, 0));
glm::dmat4 rotProp = glm::rotate(*modelTransform, glm::radians(static_cast<double>(_rotation)), glm::dvec3(0, 1, 0));
// _stateMatrix is the Matrix transformation from _frame coordinate system (Earth in this case)
// to "GALATIC" coordinate system.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
(*modelTransform)[i][j] = _stateMatrix[i][j];
}
}
*modelTransform = *modelTransform * rot * roty * rotProp;
}
void RenderablePlanetAtmosphere::render(const RenderData& data, RendererTasks& tasks) {
// activate shader
_programObject->activate();
// scale the planet to appropriate size since the planet is a unit sphere
glm::mat4 transform = glm::mat4(1);
//earth needs to be rotated for that to work.
computeModelTransformMatrix(&transform);
// setup the data to the shader
// double lt;
// glm::dvec3 sunPosFromPlanet =
// SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt);
// sunPosFromPlanet *= 1000.0; // from Km to m
// psc sunPosFromPlanetPSC = PowerScaledCoordinate::CreatePowerScaledCoordinate(
// sunPosFromPlanet.x, sunPosFromPlanet.y, sunPosFromPlanet.z);
// glm::dvec3 planetPosFromSun =
// SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, _time, lt);
// psc planetPosFronSunPSC = PowerScaledCoordinate::CreatePowerScaledCoordinate(
// planetPosFromSun.x, planetPosFromSun.y, planetPosFromSun.z);
// // Camera direction (vector)
// glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - planetPosFronSunPSC.vec3());
_programObject->setUniform("transparency", _alpha);
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
_programObject->setUniform("ModelTransform", transform);
// Normal Transformation
glm::mat4 translateObjTransf = glm::translate(glm::mat4(1.0), data.position.vec3());
glm::mat4 translateCamTransf = glm::translate(glm::mat4(1.0), -data.camera.position().vec3());
// The following scale comes from PSC transformations.
float scaleFactor = data.camera.scaling().x * powf(10.0, data.camera.scaling().y);
glm::mat4 scaleCamTransf = glm::scale(glm::mat4(1.0), glm::vec3(scaleFactor));
glm::mat4 ModelViewTransf = data.camera.viewMatrix() * scaleCamTransf *
translateCamTransf * translateObjTransf * transform;
if (_atmosphereEnabled)
_programObject->setUniform("NormalTransform",
glm::transpose(glm::inverse(ModelViewTransf)));
//=== Sets campos, objpos, camrot and scaling in PSC coords for PSC calc in shader file ===
setPscUniforms(*_programObject.get(), data.camera, data.position);
_programObject->setUniform("_performShading", _performShading);
_programObject->setUniform("_hasHeightMap", _hasHeightTexture);
_programObject->setUniform("_heightExaggeration", _heightExaggeration);
// Bind texture
ghoul::opengl::TextureUnit dayUnit;
dayUnit.activate();
_texture->bind();
_programObject->setUniform("texture1", dayUnit);
// Bind possible night texture
if (_hasNightTexture) {
ghoul::opengl::TextureUnit nightUnit;
nightUnit.activate();
_nightTexture->bind();
_programObject->setUniform("nightTex", nightUnit);
}
if (_hasHeightTexture) {
ghoul::opengl::TextureUnit heightUnit;
heightUnit.activate();
_heightMapTexture->bind();
_programObject->setUniform("heightTex", heightUnit);
}
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
//=============================================================================
//============= Eclipse Shadow Calculations and Uniforms Loading ==============
//=============================================================================
// TODO: Move Calculations to VIEW SPACE (let's avoid precision problems...)
double lt;
if (!_shadowConfArray.empty()) {
std::vector<ShadowRenderingStruct> shadowDataArray;
shadowDataArray.reserve(_shadowConfArray.size());
for (const auto & shadowConf : _shadowConfArray) {
// TO REMEMBER: all distances and lengths in world coordinates are in meters!!! We need to move this to view space...
// Getting source and caster:
glm::dvec3 sourcePos = SpiceManager::ref().targetPosition(shadowConf.source.first, "SUN", "GALACTIC", {}, _time, lt);
sourcePos *= 1000.0; // converting to meters
glm::dvec3 casterPos = SpiceManager::ref().targetPosition(shadowConf.caster.first, "SUN", "GALACTIC", {}, _time, lt);
casterPos *= 1000.0; // converting to meters
psc caster_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(casterPos.x, casterPos.y, casterPos.z);
// First we determine if the caster is shadowing the current planet (all calculations in World Coordinates):
glm::vec3 planetCasterVec = (caster_pos - data.position).vec3();
glm::vec3 sourceCasterVec = glm::vec3(casterPos - sourcePos);
float sc_length = glm::length(sourceCasterVec);
glm::vec3 planetCaster_proj = (glm::dot(planetCasterVec, sourceCasterVec) / (sc_length*sc_length)) * sourceCasterVec;
float d_test = glm::length(planetCasterVec - planetCaster_proj);
float xp_test = shadowConf.caster.second * sc_length / (shadowConf.source.second + shadowConf.caster.second);
float rp_test = shadowConf.caster.second * (glm::length(planetCaster_proj) + xp_test) / xp_test;
float casterDistSun = glm::length(casterPos);
float planetDistSun = glm::length(data.position.vec3());
ShadowRenderingStruct shadowData;
shadowData.isShadowing = false;
if (((d_test - rp_test) < _planetRadius) &&
(casterDistSun < planetDistSun)) {
// The current caster is shadowing the current planet
shadowData.isShadowing = true;
shadowData.rs = shadowConf.source.second;
shadowData.rc = shadowConf.caster.second;
shadowData.sourceCasterVec = sourceCasterVec;
shadowData.xp = xp_test;
shadowData.xu = shadowData.rc * sc_length / (shadowData.rs - shadowData.rc);
shadowData.casterPositionVec = glm::vec3(casterPos);
}
shadowDataArray.push_back(shadowData);
}
const std::string uniformVarName("shadowDataArray[");
unsigned int counter = 0;
for (const auto & sd : shadowDataArray) {
std::stringstream ss;
ss << uniformVarName << counter << "].isShadowing";
_programObject->setUniform(ss.str(), sd.isShadowing);
if (sd.isShadowing) {
ss.str(std::string());
ss << uniformVarName << counter << "].xp";
_programObject->setUniform(ss.str(), sd.xp);
ss.str(std::string());
ss << uniformVarName << counter << "].xu";
_programObject->setUniform(ss.str(), sd.xu);
/*ss.str(std::string());
ss << uniformVarName << counter << "].rs";
_programObject->setUniform(ss.str(), sd.rs);*/
ss.str(std::string());
ss << uniformVarName << counter << "].rc";
_programObject->setUniform(ss.str(), sd.rc);
ss.str(std::string());
ss << uniformVarName << counter << "].sourceCasterVec";
_programObject->setUniform(ss.str(), sd.sourceCasterVec);
ss.str(std::string());
ss << uniformVarName << counter << "].casterPositionVec";
_programObject->setUniform(ss.str(), sd.casterPositionVec);
}
counter++;
}
}
// render
_geometry->render();
// disable shader
_programObject->deactivate();
// Testing Deferredcaster
DeferredcasterTask task{ _deferredcaster.get(), data };
tasks.deferredcasterTasks.push_back(task);
}
void RenderablePlanetAtmosphere::update(const UpdateData& data) {
// set spice-orientation in accordance to timestamp
//_stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, "GALACTIC", data.time);
_stateMatrix = data.modelTransform.rotation;
_time = data.time.j2000Seconds();
if (_programObject && _programObject->isDirty())
_programObject->rebuildFromFile();
if (_deferredcaster) {
_deferredcaster->setTime(data.time.j2000Seconds());
glm::dmat4 modelTransform;
computeModelTransformMatrix(&modelTransform);
_deferredcaster->setModelTransform(modelTransform);
}
}
void RenderablePlanetAtmosphere::loadTexture() {
_texture = nullptr;
if (_colorTexturePath.value() != "") {
_texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)));
if (_texture) {
LDEBUG("Loaded texture from '" << _colorTexturePath << "'");
_texture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
}
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error after loading color texture. OpenGL error: " << errString);
}
if (_hasNightTexture) {
_nightTexture = nullptr;
if (_nightTexturePath.value() != "") {
_nightTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath)));
if (_nightTexture) {
LDEBUG("Loaded texture from '" << _nightTexturePath << "'");
_nightTexture->uploadTexture();
_nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
//_nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
}
}
}
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error after loading night texture. OpenGL error: " << errString);
}
if (_hasHeightTexture) {
_heightMapTexture = nullptr;
if (_heightMapTexturePath.value() != "") {
_heightMapTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_heightMapTexturePath)));
if (_heightMapTexture) {
LDEBUG("Loaded texture from '" << _heightMapTexturePath << "'");
_heightMapTexture->uploadTexture();
_heightMapTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
//_nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
}
}
}
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error after loading height texture. OpenGL error: " << errString);
}
}
void RenderablePlanetAtmosphere::updateAtmosphereParameters() {
bool executeComputation = true;
if (_sunRadianceIntensity != _sunIntensityP ||
_hdrConstant != _hdrExpositionP)
executeComputation = false;
_atmosphereRadius = _atmospherePlanetRadius + _atmosphereHeightP;
_planetAverageGroundReflectance = _groundAverageReflectanceP;
_rayleighHeightScale = _rayleighHeightScaleP;
_rayleighScatteringCoeff = glm::vec3(_rayleighScatteringCoeffXP * 0.001f, _rayleighScatteringCoeffYP * 0.001f,
_rayleighScatteringCoeffZP * 0.001f);
_mieHeightScale = _mieHeightScaleP;
_mieScatteringCoeff = glm::vec3(_mieScatteringCoefficientP * 0.001f);
_mieExtinctionCoeff = _mieScatteringCoeff * (1.0f / static_cast<float>(_mieScatteringExtinctionPropCoefficientP));
_miePhaseConstant = _mieAsymmetricFactorGP;
_sunRadianceIntensity = _sunIntensityP;
_hdrConstant = _hdrExpositionP;
if (_deferredcaster) {
_deferredcaster->setAtmosphereRadius(_atmosphereRadius);
_deferredcaster->setPlanetRadius(_atmospherePlanetRadius);
_deferredcaster->setPlanetAverageGroundReflectance(_planetAverageGroundReflectance);
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
_deferredcaster->setMieHeightScale(_mieHeightScale);
_deferredcaster->setMiePhaseConstant(_miePhaseConstant);
_deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity);
_deferredcaster->setHDRConstant(_hdrConstant);
_deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff);
_deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff);
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
_deferredcaster->setRenderableClass(AtmosphereDeferredcaster::RenderablePlanet);
if (executeComputation)
_deferredcaster->preCalculateAtmosphereParam();
}
}
void RenderablePlanetAtmosphere::checkFrameBufferState(const std::string & codePosition) const {
if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Framework not built. " + codePosition);
GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (fbErr) {
case GL_FRAMEBUFFER_UNDEFINED:
LERROR("Indefined framebuffer.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
LERROR("Incomplete, missing attachement.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
LERROR("Framebuffer doesn't have at least one image attached to it.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
LERROR("Returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE \
for any color attachment point(s) named by GL_DRAW_BUFFERi.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
LERROR("Returned if GL_READ_BUFFER is not GL_NONE and the value of \
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point \
named by GL_READ_BUFFER.");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
LERROR("Returned if the combination of internal formats of the attached images \
violates an implementation - dependent set of restrictions.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
LERROR("Returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all \
attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all \
attached textures; or , if the attached images are a mix of renderbuffers and textures, \
the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.");
LERROR("Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same \
for all attached textures; or , if the attached images are a mix of renderbuffers and \
textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
LERROR("Returned if any framebuffer attachment is layered, and any populated attachment \
is not layered, or if all populated color attachments are not from textures of the same target.");
break;
default:
LDEBUG("No error found checking framebuffer: " + codePosition);
break;
}
}
}
} // namespace openspace

View File

@@ -1,166 +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. *
****************************************************************************************/
#ifndef __RENDERABLEPLANETATMOSPHERE_H__
#define __RENDERABLEPLANETATMOSPHERE_H__
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/textureunit.h>
#include <vector>
#include <string>
// ghoul includes
namespace ghoul {
namespace opengl {
class ProgramObject;
class Texture;
}
}
namespace openspace {
namespace planetgeometry {
class PlanetGeometry;
}
class AtmosphereDeferredcaster;
struct RenderData;
class RenderablePlanetAtmosphere : public Renderable {
public:
// Shadow structure
typedef struct {
std::pair<std::string, float> source;
std::pair<std::string, float> caster;
} ShadowConf;
struct ShadowRenderingStruct {
float xu, xp;
float rs, rc;
glm::vec3 sourceCasterVec;
glm::vec3 casterPositionVec;
bool isShadowing;
};
public:
explicit RenderablePlanetAtmosphere(const ghoul::Dictionary& dictionary);
~RenderablePlanetAtmosphere();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
protected:
void loadTexture();
private:
void computeModelTransformMatrix(glm::mat4 * modelTransform);
void computeModelTransformMatrix(glm::dmat4 * modelTransform);
void updateAtmosphereParameters();
void resetAtmosphereTextures(const GLuint vao, const GLenum drawBuffers[1], const GLsizei vertexSize);
void checkFrameBufferState(const std::string & codePosition) const;
private:
properties::StringProperty _colorTexturePath;
properties::StringProperty _nightTexturePath;
properties::StringProperty _heightMapTexturePath;
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::unique_ptr<ghoul::opengl::Texture> _nightTexture;
std::unique_ptr<ghoul::opengl::Texture> _heightMapTexture;
properties::FloatProperty _heightExaggeration;
std::unique_ptr<planetgeometry::PlanetGeometry> _geometry;
properties::BoolProperty _performShading;
properties::IntProperty _rotation;
// ATMOSPHERE PROPERTIES
properties::FloatProperty _atmosphereHeightP;
properties::FloatProperty _groundAverageReflectanceP;
properties::FloatProperty _rayleighHeightScaleP;
properties::FloatProperty _rayleighScatteringCoeffXP;
properties::FloatProperty _rayleighScatteringCoeffYP;
properties::FloatProperty _rayleighScatteringCoeffZP;
properties::FloatProperty _mieHeightScaleP;
properties::FloatProperty _mieScatteringCoefficientP;
properties::FloatProperty _mieScatteringExtinctionPropCoefficientP;
properties::FloatProperty _mieAsymmetricFactorGP;
properties::FloatProperty _sunIntensityP;
properties::FloatProperty _hdrExpositionP;
float _alpha;
std::vector< ShadowConf > _shadowConfArray;
float _planetRadius;
glm::dmat3 _stateMatrix;
std::string _frame;
std::string _target;
bool _hasNightTexture;
bool _hasHeightTexture;
bool _shadowEnabled;
double _time;
// Atmosphere Data
bool _atmosphereEnabled;
float _atmosphereRadius;
float _atmospherePlanetRadius;
float _planetAverageGroundReflectance;
float _rayleighHeightScale;
float _mieHeightScale;
float _miePhaseConstant;
float _sunRadianceIntensity;
float _hdrConstant;
glm::vec3 _mieExtinctionCoeff;
glm::vec3 _rayleighScatteringCoeff;
glm::vec3 _mieScatteringCoeff;
// Atmosphere Debug
bool _saveCalculationsToTexture;
float _preCalculatedTexturesScale;
// Testing Deferredcast
std::unique_ptr<AtmosphereDeferredcaster> _deferredcaster;
};
} // namespace openspace
#endif // __RENDERABLEPLANETATMOSPHERE_H__

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,6 @@
****************************************************************************************/
#version __CONTEXT__
//#version 400
layout(location = 0) in vec4 in_position;

View File

@@ -1,524 +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 irradianceTexture;
uniform sampler3D inscatterTexture;
// Texture coordinates
in vec2 vs_st;
in vec4 vs_normal;
// vs_position is the object position in Eye space but in PSC coords.
in vec4 vs_position;
// Vertex position in world coordinates in meters (no powerscalling coors).
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 ******
*******************************************************************************/
// For the atmosphere being correctly rendered, one must use the planet's center
// as the center of the coordinate 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;
};
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;
}
/*
* Calculates the light scattering in the view direction comming from other
* light rays scattered in the atmosphere.
* Following the paper: S[L]|x - T(x,xs) * S[L]|xs
* The view direction here is the ray: x + tv, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* Arguments:
* x := camera position
* t := ray displacement variable after calculating the intersection with the
* atmosphere. It is the distance from the camera to the last intersection with
* the atmosphere
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := out of ||x|| inside atmosphere (or top of atmosphere)
* mu := out of cosine of the zenith view angle
* attenuation := out of transmittance T(x,x0). This will be used later when
* calculating the reflectance R[L].
*/
vec3 inscatterRadiance(inout vec3 x, inout float t, const vec3 v, const vec3 s,
out float r, out float mu, out vec3 attenuation) {
vec3 radiance;
r = length(x);
mu = dot(x, v) / r;
float mu2 = mu * mu;
float r2 = r * r;
float Rt2 = Rt * Rt;
float Rg2 = Rg * Rg;
// From the cosine law for x0 at top of atmosphere:
// Rt^2 = r^2 + dist^2 - 2*r*dist*cos(PI - theta)
float dist = -r * mu - sqrt(r2 * (mu2 - 1.0f) + Rt2);
// Dist stores the distance from the camera position
// to the first (the only in some cases) intersection of the
// light ray and the top of atmosphere.
// Are we at space?
if (dist > 0.0f) {
// Because we are at space, we must obtain the vector x,
// the correct cosine of between x and v and the right height r,
// with the x in top of atmosphere.
// What we do is to move from the starting point x (camera position)
// to the point on the atmosphere. So, because we have a new x,
// we must also calculate the new cosine between x and v. s is the
// same because we consider the Sun as a parallel ray light source.
x += dist * v;
t -= dist;
// mu(x0 and v)
// cos(theta') = (x0 dot v)/(||x0||*||v||) = ((x + dist*v) dot v)/(Rt * 1)
// cos(theta') = mu' = (r*mu + dist)/Rt
mu = (r * mu + dist) / Rt;
mu2 = mu * mu;
r = Rt;
r2 = r * r;
}
// Intersects atmosphere?
if (r <= Rt) {
float nu = dot(v, s);
float muSun = dot(x, s) / r;
float rayleighPhase = rayleighPhaseFunction(nu);
float miePhase = miePhaseFunction(nu);
// S[L](x,s,v)
vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0);
// After removing the initial path from camera pos to top of atmosphere or the
// current camera position if inside atmosphere, t > 0
if (t > 0.0) {
// Calculate the zenith angles for x0 and v, s:
vec3 x0 = x + t * v;
float r0 = length(x0);
float mu0 = dot(x0, v) / r0;
float muSun0 = dot(x0, s) / r0;
// Transmittance from point r, direction mu, distance t
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 avoidance constant (0.01). Done!! Adaptive from distance to x
if (r0 > Rg + (0.1f * r)) {
// It r0 > Rg it means the ray hits something inside the atmosphere. So we need to
// remove the inScattering contribution from the main ray from the hitting point
// to the end of the ray.
//if (r0 > Rg + (0.01f)) {
// Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s)
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muSun0, nu), 0.0);
// cos(PI-thetaH) = dist/r
// cos(thetaH) = - dist/r
// muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2)
float muHorizon = -sqrt(1.0f - (Rg2 / r2));
// In order to avoid imprecision problems near horizon,
// we interpolate between two points: above and below horizon
const float INTERPOLATION_EPS = 0.004f; // precision const
if (abs(mu - muHorizon) < INTERPOLATION_EPS) {
// We want an interpolation value close to 1/2, so the
// contribution of each radiance value is almost the same
// or it has a havey weight if from above or below horizon
float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS);
float t2 = t * t;
// Above Horizon
mu = muHorizon - INTERPOLATION_EPS;
//r0 = sqrt(r * r + t * t + 2.0f * r * t * mu);
// From cosine law where t = distance between x and x0
// r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta)
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
// From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||)
// mu0 = ((x + t) dot v) / r0
// mu0 = (x dot v + t dot v) / r0
// mu0 = (r*mu + t) / r0
mu0 = (r * mu + t) / r0;
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu);
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
// Attention for the attenuation.r value applied to the S_Mie
vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0f);
// Below Horizon
mu = muHorizon + INTERPOLATION_EPS;
//r0 = sqrt(r * r + t * t + 2.0f * r * t * mu);
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
mu0 = (r * mu + t) / r0;
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu);
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
// Attention for the attenuation.r value applied to the S_Mie
vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0);
// Interpolate between above and below inScattering radiance
inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue);
}
}
}
// The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0])
// So, we must reintroduce the Mie inscatter by the proximity rule as described in the
// paper by Bruneton and Neyret in "Angular precision" paragraph:
// Hermite interpolation between two values
// This step is done because imprecision problems happen when the Sun is slightly below
// the horizon. When this happen, we avoid the Mie scattering contribution.
inscatterRadiance.w *= smoothstep(0.0f, 0.02f, muSun);
vec3 inscatterMie = inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) *
(betaRayleigh.r / betaRayleigh);
radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0f);
} else {
// No intersection with atmosphere
// The ray is traveling on space
radiance = vec3(0.0f);
}
// Finally we add the Lsun (all calculations are done with no Lsun so
// we can change it on the fly with no precomputations)
return radiance * sunRadiance;
}
/*
* Calculates the light reflected in the view direction comming from other
* light rays integrated over the hemispehre plus the direct light (L0) from Sun.
* Following the paper: R[L]= R[L0]+R[L*]
* The the ray is x + tv, v the view direction, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* As for all calculations in the atmosphere, the center of the coordinate system
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
* Arguments:
* x := camera position
* t := ray displacement variable. Here, differently from the inScatter light calculation,
* the position of the camera is already offset (on top of atmosphere) or inside
* the atmosphere.
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
* mu := cosine of the zenith view angle
* attenuationXtoX0 := transmittance T(x,x0)
*/
vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r,
const float mu, const vec3 attenuationXtoX0)
{
vec3 reflectedRadiance = vec3(0.0f);
// Ray hits planet's surface
if (t > 0.0f) {
// First we obtain the ray's end point on the surface
vec3 x0 = x + t * v;
float r0 = length(x0);
// Normal of intersection point.
// TODO: Change it to globebrowser
vec3 n = x0 / r0;
// Initial ground radiance (the surface color)
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 + EPS (we are not intersecting the ground),
// we get a constant initial ground radiance
//if (r0 > Rg + 0.01) {
// reflectance = vec4(0.4, 0.4, 0.4, 0.0);
//}
// L0 is not included in the irradiance texture.
// We first calculate the light attenuation from the top of the atmosphere
// to x0.
float muSun = dot(n, s);
// Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed)
vec3 transmittanceL0 = muSun < -sqrt(1.0f - ((Rg * Rg) / (r0 * r0))) ? vec3(0.0f) : transmittanceLUT(r0, muSun);
// E[L*] at x0
vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun);
// Adding clouds texture
vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st);
// R[L0] + R[L*]
vec3 groundRadiance = (reflectance.rgb + clouds.rgb) *
(max(muSun, 0.0) * transmittanceL0 + irradianceReflected) * sunRadiance / M_PI;
// Yellowish specular reflection from sun on oceans and rivers
if (reflectance.w > 0.0) {
vec3 h = normalize(s - v);
// Fresnell Schlick's approximation
float fresnel = 0.02f + 0.98f * pow(1.0f - dot(-v, h), 5.0f);
// Walter BRDF approximation
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0f), 150.0f);
// Adding Fresnell and Water BRDFs approximation to the final surface color
// (After adding the sunRadiance and the attenuation of the Sun through atmosphere)
groundRadiance += reflectance.w * max(waterBrdf, 0.0) * transmittanceL0 * sunRadiance;
}
// Finally, we attenuate the surface Radiance from the the point x0 to the camera location.
reflectedRadiance = attenuationXtoX0 * groundRadiance;
}
// Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground.
return reflectedRadiance;
}
/*
* Calculates the Sun color.
* The the ray is x + tv, v the view direction, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* As for all calculations in the atmosphere, the center of the coordinate system
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
* Arguments:
* x := camera position
* t := ray displacement variable. Here, differently from the inScatter light calculation,
* the position of the camera is already offset (on top of atmosphere) or inside
* the atmosphere.
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
* mu := cosine of the zenith view angle
* attenuation := transmittance T(x,x0)
*/
vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r, const float mu) {
if (t > 0.0f) {
return vec3(0.0f);
} else {
vec3 transmittance = (r <= Rt) ? (mu < -sqrt(1.0f - (Rg*Rg)/(r*r)) ? vec3(0.0f) : transmittanceLUT(r, mu)) :
vec3(1.0f);
float sunRadiance = step(cos(M_PI / 180.0), dot(v, s)) * sunRadiance;
return transmittance * sunRadiance;
}
}
/***********************************************************************
******* 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() {
// Vertex position in PSC coordinates in Eye space
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;
// Shading is enabled
if (_performShading) {
// atmosphere
// vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT);
// vec4 ndcPos;
// ndcPos.xy = ((2.0f * gl_FragCoord.xy) - (2.0f * viewport.xy)) / (viewport.zw) - 1.0f;
// 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 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(ppos, v, Rg, offset, maxLength)) {
// // Following paper nomenclature
// float t = offset;
// vec3 x = cameraPosObj.xyz;
// float r = length(x);
// float mu = dot(x, v) / r;
// vec3 s = normalize(sunPositionObj);
// vec3 attenuation;
// vec3 inscatterColor = inscatterRadiance(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 = vec4(HDR(sunColor + groundColor + inscatterColor), 1.0));
// //diffuse = vec4(HDR(inscatterColor), 1.0));
// //diffuse = vec4(HDR(groundColor), 1.0);
// //diffuse = vec4(HDR(sunColor), 1.0));
// //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2);
// vec4 finalRadiance = calcShadow(shadowDataArray, vs_posWorld.xyz) *
// (vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2);
// diffuse = vec4(HDR(finalRadiance.xyz), finalRadiance.w);
// }
// directional lighting
vec3 origin = vec3(0.0);
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_normal.xyz);
//vec3 e = normalize(camdir);
vec3 l_pos = vec3(sun_pos); // sun.
vec3 l_dir = normalize(l_pos-objpos.xyz);
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1);
float shine = 0.0001;
vec4 specular = vec4(0.5);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
vec4 daytex = max(intensity * diffuse, ambient);
vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2);
diffuse = calcShadow(shadowDataArray, vs_posWorld.xyz) * (daytex*2 + mixtex)/3;
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = depth;
return frag;
}

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;
// Model Transformation: transforms the source frame of the planet to the GALACTIC frame, also adds the planet rotation
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;
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;
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 correct 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.
// tmp is the object position in Eye space but in PSC coords.
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 is the object position in Eye space but in PSC coords.
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);
}

View File

@@ -1,40 +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. *
****************************************************************************************/
in vec3 vPosition;
in vec4 worldPosition;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 fragColor = vec4(vPosition+0.5, 1.0);
vec4 position = worldPosition;
float depth = pscDepth(position);
Fragment frag;
frag.color = fragColor;
frag.depth = depth;
return frag;
}

View File

@@ -1,47 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 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 vec4 vertPosition;
uniform mat4 viewProjection;
uniform mat4 modelTransform;
out vec3 vPosition;
out vec4 worldPosition;
#include "PowerScaling/powerScaling_vs.hglsl"
void main() {
vPosition = vertPosition.xyz;
worldPosition = modelTransform*vertPosition;
vec4 position = pscTransform(worldPosition, mat4(1.0));
// project the position to view space
gl_Position = viewProjection * position;
gl_Position.z = 1.0;
}

View File

@@ -1,795 +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__
//#version 400
const int RenderablePlanet = 1;
const int RenderableGlobe = 2;
#define EPSILON 0.0001f
#include "floatoperations.glsl"
#include "hdr.glsl"
#include "atmosphere_common.glsl"
// Atmosphere applied over a RenderablePlanet or
// a RenderableGlobe
uniform int RenderableClass;
uniform sampler2D irradianceTexture;
uniform sampler3D inscatterTexture;
uniform sampler2DMS mainPositionTexture;
uniform sampler2DMS mainNormalTexture;
uniform sampler2DMS mainColorTexture;
uniform sampler2DMS otherDataTexture;
uniform int nAaSamples;
//layout(location = 0) out vec4 renderTarget;
out vec4 renderTarget;
in vec3 interpolatedNDCPos;
// Model Transform Matrix Used for Globe Rendering
uniform dmat4 dInverseTransformMatrix;
uniform dmat4 dInverseSgctEyeToWorldTranform; // SGCT Eye to OS World
uniform dmat4 dSgctEyeToOSEyeTranform; // SGCT Eye to OS Eye *
uniform dmat4 dInverseSgctProjectionMatrix; // Clip to SGCT Eye *
uniform dmat4 dInverseCamRotTransform;
uniform dmat4 dInverseModelTransformMatrix;
uniform dmat4 dSGCTEyeToOSWorldTransformMatrix;
// Double Precision Versions:
uniform dvec4 dObjpos;
uniform dvec3 dCampos;
uniform dvec3 sunDirectionObj;
uniform dvec3 ellipsoidRadii;
/*******************************************************************************
****** 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 dRay {
dvec4 origin;
dvec4 direction;
};
struct Ellipsoid {
dvec4 center;
dvec3 size;
};
bool dIntersectEllipsoid(const dRay 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.0 * 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.0 * a);
double t2 = (-b-d) / (2.0 * a);
if ( t1 <= EPSILON && t2 <= EPSILON )
return false; // both intersections are behind the ray origin
// If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid
bool back = (t1 <= EPSILON || t2 <= EPSILON);
double t = 0.0;
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
offset = t;
// dvec4 intersection = ray.origin + t * dir;
// dvec4 normal = intersection - ellipsoid.center;
// normal.x = 2.0 * normal.x / (ellipsoid.size.x * ellipsoid.size.x);
// normal.y = 2.0 * normal.y / (ellipsoid.size.y * ellipsoid.size.y);
// normal.z = 2.0 * normal.z / (ellipsoid.size.z * ellipsoid.size.z);
// normal.w = 0.0;
// normal *= (back) ? -1.0 : 1.0;
// normal = normalize(normal);
return true;
}
/* Function to calculate the initial intersection of the eye (camera) ray
* with the atmosphere.
* In (all parameters in the same coordinate system and same units):
* - planet position
* - ray direction (normalized)
* - eye position
* - atmosphere radius
* Out: true if an intersection happens, false otherwise
* - inside: true if the ray origin is inside atmosphere, false otherwise
* - offset: the initial intersection distance from eye position when
* the eye is outside the atmosphere
* - maxLength : the second intersection distance from eye position when the
* eye is outside the atmosphere or the initial (and only)
* intersection of the ray with atmosphere when the eye position
* is inside atmosphere.
*/
bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const double atmRadius,
out bool inside, out double offset, out double maxLength ) {
dvec3 l = planetPosition - ray.origin.xyz;
double s = dot(l, ray.direction.xyz);
double l2 = dot(l, l);
double r2 = (atmRadius - EPSILON) * (atmRadius - EPSILON); // avoiding surface acne
// Ray origin (eye position) is behind sphere
if ((s < 0.0) && (l2 > r2)) {
inside = false;
offset = 0.0;
maxLength = 0.0;
return false;
}
double m2 = l2 - s*s;
// Ray misses atmospere
if (m2 > r2) {
inside = false;
offset = 0.0;
maxLength = 0.0;
return false;
}
// We already now the ray hits the atmosphere
// If q = 0.0f, there is only one intersection
double q = sqrt(r2 - m2);
// If l2 < r2, the ray origin is inside the sphere
if (l2 > r2) {
inside = false;
offset = s - q;
maxLength = s + q;
} else {
inside = true;
offset = 0.0;
maxLength = s + q;
}
return true;
}
/*
* Calculates Intersection Ray by walking through
* all the graphic pipile transformations in the
* opposite direction.
* Instead of passing through all the pipeline,
* it starts at NDC from the interpolated
* positions from the screen quad.
* This method avoids matrices multiplications
* wherever is possible.
*/
void dCalculateRayRenderableGlobe(out dRay ray, out dvec4 planetPositionObjectCoords,
out dvec4 cameraPositionInObject) {
// ======================================
// ======= Avoiding Some Matrices =======
// NDC to clip coordinates (gl_FragCoord.w = 1.0/w_clip)
// Using the interpolated coords:
// Assuming Red Book is right: z_ndc e [0, 1] and not [-1, 1]
dvec4 clipCoords = dvec4(interpolatedNDCPos, 1.0) / gl_FragCoord.w;
// This next line is needed because OS or SGCT is not inverting Y axis from
// window space.
//clipCoords.y = (-interpolatedNDCPos.y) / gl_FragCoord.w;
// Clip to SGCT Eye
dvec4 sgctEyeCoords = dInverseSgctProjectionMatrix * clipCoords;
//sgctEyeCoords /= sgctEyeCoords.w;
sgctEyeCoords.w = 1.0;
// SGCT Eye to OS Eye
dvec4 tOSEyeCoordsInv = dSgctEyeToOSEyeTranform * sgctEyeCoords;
// OS Eye to World coords
dvec4 tmpRInv = dInverseCamRotTransform * tOSEyeCoordsInv;
dvec4 worldCoords= dvec4(dvec3(tmpRInv) + dCampos, 1.0);
// World to Object
dvec4 objectCoords = dInverseTransformMatrix * worldCoords;
// Planet Position in Object Space
// JCC: Applying the inverse of the model transformation on the object postion in World
// space results in imprecision.
planetPositionObjectCoords = dvec4(0.0,0.0,0.0,1.0);//dInverseTransformMatrix * dvec4(dObjpos.xyz, 1.0);
// Camera Position in Object Space
cameraPositionInObject = dInverseTransformMatrix * dvec4(dCampos, 1.0);
// ============================
// ====== Building Ray ========
// Ray in object space (in KM)
ray.origin = cameraPositionInObject / dvec4(1000.0, 1000.0, 1000.0, 1.0);
ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0);
}
/*
* Calculates Intersection Ray by walking through
* all the graphic pipile transformations in the
* opposite direction.
* Instead of passing through all the pipeline,
* it starts at NDC from the interpolated
* positions from the screen quad.
* This method avoids matrices multiplications
* wherever is possible.
*/
void dCalculateRayRenderablePlanet(out dRay ray, out dvec4 planetPositionObjectCoords,
out dvec4 cameraPositionInObject) {
// ======================================
// ======= Avoiding Some Matrices =======
// NDC to clip coordinates (gl_FragCoord.w = 1.0/w_clip)
// Using the interpolated coords:
// Assuming Red Book is right: z_ndc e [0, 1] and not [-1, 1]
dvec4 clipCoords = dvec4(interpolatedNDCPos, 1.0) / gl_FragCoord.w;
// This next line is needed because OS or SGCT is not inverting Y axis from
// window space.
//clipCoords.y = (-interpolatedNDCPos.y) / gl_FragCoord.w;
// Clip to SGCT Eye
dvec4 sgctEyeCoords = dInverseSgctProjectionMatrix * clipCoords;
//sgctEyeCoords /= sgctEyeCoords.w;
sgctEyeCoords.w = 1.0;
// SGCT Eye to OS World
dvec4 worldCoords = dSGCTEyeToOSWorldTransformMatrix * sgctEyeCoords;
// World to Object
dvec4 objectCoords = dInverseModelTransformMatrix * worldCoords;
// Planet Position in Object Space
planetPositionObjectCoords = dvec4(0.0,0.0,0.0,1.0);//dInverseTransformMatrix * dvec4(-dObjpos.xyz + dObjpos.xyz, 1.0);
// Camera Position in Object Space
cameraPositionInObject = dInverseModelTransformMatrix * dvec4(dCampos, 1.0);
// ============================
// ====== Building Ray ========
// Ray in object space (in KM)
ray.origin = cameraPositionInObject / dvec4(1000.0, 1000.0, 1000.0, 1.0);
ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0);
}
/*
* Calculates the light scattering in the view direction comming from other
* light rays scattered in the atmosphere.
* Following the paper: S[L]|x - T(x,xs) * S[L]|xs
* The view direction here is the ray: x + tv, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* Arguments:
* x := camera position
* t := ray displacement variable after calculating the intersection with the
* atmosphere. It is the distance from the camera to the last intersection with
* the atmosphere. If the ray hits the ground, t is updated to the correct value
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := out of ||x|| inside atmosphere (or top of atmosphere)
* mu := out of cosine of the zenith view angle
* attenuation := out of transmittance T(x,x0). This will be used later when
* calculating the reflectance R[L].
*/
vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor,
const vec3 v, const vec3 s, out float r, out float mu,
out vec3 attenuation, const vec3 fragPosObj,
const double maxLength, const double pixelDepth,
const vec4 spaceColor) {
vec3 radiance;
r = length(x);
mu = dot(x, v) / r;
float mu2 = mu * mu;
float r2 = r * r;
float Rt2 = Rt * Rt;
float Rg2 = Rg * Rg;
float nu = dot(v, s);
float muSun = dot(x, s) / r;
float rayleighPhase = rayleighPhaseFunction(nu);
float miePhase = miePhaseFunction(nu);
// S[L](x,s,v)
// I.e. the next line has the scattering light for the "infinite" ray passing
// through the atmosphere. If this ray hits something inside the atmosphere,
// we will subtract the attenuated scattering light from that path in the
// current path.
vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0);
// After removing the initial path from camera pos to top of atmosphere (for an
// observer in the space) we test if the light ray is hitting the atmosphere
vec3 x0 = fragPosObj;
float r0 = length(fragPosObj);
float muSun0 = dot(fragPosObj, s) / r0;
//vec3 x0 = x + float(pixelDepth) * v;
float mu0 = dot(x0, v) / r0;
bool groundHit = false;
if ((pixelDepth > 0.0) && pixelDepth < maxLength) {
t = float(pixelDepth);
groundHit = true;
// Transmittance from point r, direction mu, distance t
// By Analytical calculation
attenuation = analyticTransmittance(r, mu, t);
// Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s)
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
// The "infinite" ray hist something inside the atmosphere, so we need to remove
// the unsused contribution to the final radiance.
vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * inscatterFromSurface, 0.0);
// We set the irradianceFactor to 1.0 so the reflected irradiance will be considered
// when calculating the reflected light on the ground.
irradianceFactor = 1.0;
} else {
attenuation = analyticTransmittance(r, mu, t);
}
// cos(PI-thetaH) = dist/r
// cos(thetaH) = - dist/r
// muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2)
float muHorizon = -sqrt(1.0f - (Rg2 / r2));
// In order to avoid imprecision problems near horizon,
// we interpolate between two points: above and below horizon
const float INTERPOLATION_EPS = 0.004f; // precision const from Brunetton
if (abs(mu - muHorizon) < INTERPOLATION_EPS) {
// We want an interpolation value close to 1/2, so the
// contribution of each radiance value is almost the same
// or it has a havey weight if from above or below horizon
float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS);
float t2 = t * t;
// Above Horizon
mu = muHorizon - INTERPOLATION_EPS;
//r0 = sqrt(r * r + t * t + 2.0f * r * t * mu);
// From cosine law where t = distance between x and x0
// r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta)
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
// From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||)
// mu0 = ((x + t) dot v) / r0
// mu0 = (x dot v + t dot v) / r0
// mu0 = (r*mu + t) / r0
mu0 = (r * mu + t) / r0;
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu);
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
// Attention for the attenuation.r value applied to the S_Mie
vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0f);
// Below Horizon
mu = muHorizon + INTERPOLATION_EPS;
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
mu0 = (r * mu + t) / r0;
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu);
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
// Attention for the attenuation.r value applied to the S_Mie
vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0);
// Interpolate between above and below inScattering radiance
inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue);
}
// The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0])
// So, we must reintroduce the Mie inscatter by the proximity rule as described in the
// paper by Bruneton and Neyret in "Angular precision" paragraph:
// Hermite interpolation between two values
// This step is done because imprecision problems happen when the Sun is slightly below
// the horizon. When this happen, we avoid the Mie scattering contribution.
inscatterRadiance.w *= smoothstep(0.0f, 0.02f, muSun);
vec3 inscatterMie = inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) *
(betaRayleigh.r / betaRayleigh);
radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0f);
// Finally we add the Lsun (all calculations are done with no Lsun so
// we can change it on the fly with no precomputations)
// return radiance * sunRadiance;
vec3 finalScatteringRadiance = radiance * sunRadiance;
if (groundHit) {
return finalScatteringRadiance;
} else {
return ((r-Rg)/(Rt-Rg))*spaceColor.rgb * 1.8 + finalScatteringRadiance;
}
}
/*
* Calculates the light reflected in the view direction comming from other
* light rays integrated over the hemispehre plus the direct light (L0) from Sun.
* Following the paper: R[L]= R[L0]+R[L*]
* The the ray is x + tv, v the view direction, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* As for all calculations in the atmosphere, the center of the coordinate system
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
* Arguments:
* x := camera position
* t := ray displacement variable. Here, differently from the inScatter light calculation,
* the position of the camera is already offset (on top of atmosphere) or inside
* the atmosphere.
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
* mu := cosine of the zenith view angle
* attenuationXtoX0 := transmittance T(x,x0)
*/
vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r,
const float mu, const vec3 attenuationXtoX0, const vec4 groundMeanColor,
const vec3 normal, const float irradianceFactor,
const float waterReflectance)
{
vec3 reflectedRadiance = vec3(0.0f);
// First we obtain the ray's end point on the surface
vec3 x0 = x + t * v;
float r0 = length(x0);
// Normal of intersection point.
vec3 n = normalize(normal);
//n = normalize(vec3(1.0, 1.0, 1.0));
vec4 groundReflectance = groundMeanColor * vec4(.37);
//reflectance.w = 1.0;
// L0 is not included in the irradiance texture.
// We first calculate the light attenuation from the top of the atmosphere
// to x0.
float muSun = max(dot(n, s), 0.0);
// Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed)
vec3 transmittanceL0 = muSun < -sqrt(1.0f - ((Rg * Rg) / (r0 * r0))) ? vec3(0.0f) : transmittanceLUT(r0, muSun);
// E[L*] at x0
vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor;
// R[L0] + R[L*]
vec3 groundRadiance = groundReflectance.rgb * (muSun * transmittanceL0 + irradianceReflected)
* sunRadiance / M_PI;
// Specular reflection from sun on oceans and rivers
if (waterReflectance > 0.1) {
vec3 h = normalize(s - v);
// Fresnell Schlick's approximation
float fresnel = 0.02f + 0.98f * pow(1.0f - dot(-v, h), 5.0f);
// Walter BRDF approximation
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0f), 150.0f);
// Adding Fresnell and Water BRDFs approximation to the final surface color
// (After adding the sunRadiance and the attenuation of the Sun through atmosphere)
groundRadiance += waterReflectance * max(waterBrdf, 0.0) * transmittanceL0 * sunRadiance;
}
// Finally, we attenuate the surface Radiance from the the point x0 to the camera location.
reflectedRadiance = attenuationXtoX0 * groundRadiance;
// Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground.
return reflectedRadiance;
}
/*
* Calculates the Sun color.
* The the ray is x + tv, v the view direction, s is the sun direction,
* r and mu the position and zenith cosine angle as in the paper.
* As for all calculations in the atmosphere, the center of the coordinate system
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
* Arguments:
* x := camera position
* t := ray displacement variable. Here, differently from the inScatter light calculation,
* the position of the camera is already offset (on top of atmosphere) or inside
* the atmosphere.
* v := view direction (ray's direction) (normalized)
* s := Sun direction (normalized)
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
* mu := cosine of the zenith view angle
* attenuation := transmittance T(x,x0)
*/
vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r,
const float mu, const float irradianceFactor) {
vec3 transmittance = (r <= Rt) ? ( mu < -sqrt(1.0f - (Rg*Rg)/(r*r)) ? vec3(0.0f) : transmittanceLUT(r, mu)) : vec3(1.0f);
float sunFinalColor = step(cos(M_PI / 180.0), dot(v, s)) * sunRadiance * (1.0 - irradianceFactor);
return transmittance * sunFinalColor;
}
void main() {
//float mainDepth = 0.0;
vec4 meanColor = vec4(0.0);
vec4 meanNormal = vec4(0.0);
vec4 meanPosition = vec4(0.0);
vec4 meanOtherData = vec4(0.0);
//vec4 positionArray[nAaSamples];
//vec4 positionArray[8];
float maxAlpha = -1.0;
for (int i = 0; i < nAaSamples; i++) {
meanNormal += texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i);
vec4 color = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
if ( color.a > maxAlpha )
maxAlpha = color.a;
meanColor += color;
meanPosition += texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i);
meanOtherData += texelFetch(otherDataTexture, ivec2(gl_FragCoord), i);
//positionArray[i] = texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i);
//mainDepth += denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x);
}
meanColor /= nAaSamples;
meanNormal /= nAaSamples;
meanPosition /= nAaSamples;
meanOtherData /= nAaSamples;
//mainDepth /= nAaSamples;
meanColor.a = maxAlpha;
// Ray in object space
dRay ray;
dvec4 planetPositionObjectCoords = dvec4(0.0);
dvec4 cameraPositionInObject = dvec4(0.0);
if (RenderableClass == RenderablePlanet) {
// Get the ray from camera to atm in object space
dCalculateRayRenderablePlanet(ray, planetPositionObjectCoords, cameraPositionInObject);
bool insideATM = false;
double offset = 0.0;
double maxLength = 0.0;
bool intersectATM = false;
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt-10*EPSILON,
insideATM, offset, maxLength );
if ( intersectATM ) {
/*
vec4 farthestPosition = vec4(0.0);
float farthest = -1.0;
for (int i = 0; i < nAaSamples; i++) {
float tmpDistance = float(distance(dCampos.xyz, dvec3(positionArray[i].xyz)));
if ( positionArray[i].w > 0.0 && tmpDistance >= farthest ) {
farthest = tmpDistance;
farthestPosition = positionArray[i];
}
}
dvec3 tmpPos = dmat3(dInverseCamRotTransform) * dvec3(dInverseScaleTransformMatrix * farthestPosition);
*/
dvec4 fragWorldCoords = dSGCTEyeToOSWorldTransformMatrix * meanPosition;
dvec4 fragObjectCoords = dInverseModelTransformMatrix * fragWorldCoords;
//dvec4 fragObjectCoords = dInverseModelTransformMatrix * meanPosition;//fragWorldCoords;
double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz);
// All calculations are done in Km:
pixelDepth /= 1000.0;
fragObjectCoords.xyz /= 1000.0;
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
// in the depth buffer is less than the distance to the atmosphere then the atmosphere
// is occluded
// Fragments positions into G-Buffer are written in OS Eye Space (Camera Rig Coords)
// when using their positions later, one must convert them to the planet's coords
if ((pixelDepth > 0.0) && pixelDepth < offset) {
renderTarget = vec4(HDR(meanColor.xyz), meanColor.a);
} else {
// Following paper nomenclature
double t = offset;
vec3 attenuation;
// Moving observer from camera location to top atmosphere
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
float r = 0.0;//length(x);
vec3 v = vec3(ray.direction.xyz);
float mu = 0.0;//dot(x, v) / r;
vec3 s = vec3(sunDirectionObj);
float tF = float(maxLength - t);
// Because we may move the camera origin to the top of atmosphere
// we also need to adjust the pixelDepth for this offset so the
// next comparison with the planet's ground make sense:
pixelDepth -= offset;
float irradianceFactor = 0.0;
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v,
s, r, mu, attenuation,
vec3(fragObjectCoords.xyz),
maxLength, pixelDepth,
meanColor);
vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation,
meanColor, meanNormal.xyz, irradianceFactor,
meanOtherData.r);
vec3 sunColor = sunColor(x, tF, v, s, r, mu, irradianceFactor);
vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0);
renderTarget = finalRadiance;
}
} else {
renderTarget = vec4(HDR(meanColor.xyz * 1.8), meanColor.a);
//renderTarget = vec4(1.0, 0.0, 0.0, 1.0);
}
} else if ( RenderableClass == RenderableGlobe) {
// Get the ray from camera to atm in object space
dCalculateRayRenderableGlobe(ray, planetPositionObjectCoords, cameraPositionInObject);
bool insideATM = false;
double offset = 0.0;
double maxLength = 0.0;
bool intersectATM = false;
// Instead of ray-ellipsoid intersection lets transform the ray to a sphere:
dRay transfRay;
transfRay.origin = ray.origin;
transfRay.direction = ray.direction;
// transfRay.origin.z *= 1000.0/ellipsoidRadii.x;
// transfRay.direction.z *= 1000.0/ellipsoidRadii.x;
// transfRay.origin.x *= 1000.0/ellipsoidRadii.y;
// transfRay.direction.x *= 1000.0/ellipsoidRadii.y;
// transfRay.origin.y *= 1000.0/ellipsoidRadii.z;
// transfRay.direction.y *= 1000.0/ellipsoidRadii.z;
// transfRay.direction.xyz = normalize(transfRay.direction.xyz);
// intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, 1.0,
// insideATM, offset, maxLength );
// intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, Rt+EPSILON,
// insideATM, offset, maxLength );
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay,
Rt-10*EPSILON, insideATM, offset, maxLength );
if ( intersectATM ) {
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
// in the depth buffer is less than the distance to the atmosphere then the atmosphere
// is occluded
// Fragments positions into G-Buffer are written in OS Eye Space (Camera Rig Coords)
// when using their positions later, one must convert them to the planet's coords
// OS Eye to World coords
// Version when no milkway is present (performance hit)
/*
vec4 farthestPosition = vec4(0.0);
float farthest = -1.0;
for (int i = 0; i < nAaSamples; i++) {
float tmpDistance = float(distance(dCampos.xyz, dvec3(positionArray[i].xyz)));
if ( positionArray[i].w > 0.0 && tmpDistance >= farthest ) {
farthest = tmpDistance;
farthestPosition = positionArray[i];
}
}
dvec4 tmpRInvPos = dInverseCamRotTransform * farthestPosition;
*/
// Version with milkway enabled
dvec4 tmpRInvPos = dInverseCamRotTransform * dSgctEyeToOSEyeTranform * meanPosition;
dvec4 fragWorldCoords = dvec4(dvec3(tmpRInvPos) + dCampos, 1.0);
//dvec4 tmpRInvNormal = dInverseCamRotTransform * meanNormal;
//dvec4 fragNormalWorldCoords = dvec4(dvec3(tmpRInvNormal) + dCampos, 1.0);
// World to Object (Normal and Position in meters)
dvec4 fragObjectCoords = dInverseTransformMatrix * fragWorldCoords;
//dvec4 fragNormalObjectCoords = dInverseTransformMatrix * fragNormalWorldCoords;
// Normal in Object Space already (changed 05/26/2017).
//dvec4 fragNormalObjectCoords = dvec4(normalize(meanNormal.xyz), 1.0);
// Distance of the pixel in the gBuffer to the observer
double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz);
// All calculations are done in Km:
pixelDepth /= 1000.0;
fragObjectCoords.xyz /= 1000.0;
if (meanPosition.xyz != vec3(0.0) && (pixelDepth < offset)) {
renderTarget = vec4(HDR(meanColor.xyz), meanColor.a);
} else {
// Following paper nomenclature
double t = offset;
vec3 attenuation;
// Moving observer from camera location to top atmosphere
// If the observer is already inside the atm, offset = 0.0
// and no changes at all.
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
float r = 0.0;//length(x);
vec3 v = vec3(ray.direction.xyz);
float mu = 0.0;//dot(x, v) / r;
vec3 s = vec3(sunDirectionObj);
float tF = float(maxLength - t);
// Because we may move the camera origin to the top of atmosphere
// we also need to adjust the pixelDepth for this offset so the
// next comparison with the planet's ground make sense:
pixelDepth -= offset;
float irradianceFactor = 0.0;
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v,
s, r, mu, attenuation,
vec3(fragObjectCoords.xyz),
maxLength, pixelDepth,
meanColor);
vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation,
meanColor, meanNormal.xyz, irradianceFactor,
meanOtherData.r);
vec3 sunColor = sunColor(x, tF, v, s, r, mu, irradianceFactor);
// Final Color of ATM plus terrain:
vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0);
//vec4 finalRadiance = vec4(HDR(inscatterColor + sunColor) + groundColor, 1.0);
// Debug:
//finalRadiance = vec4(HDR(inscatterColor + sunColor), 1.0);
//finalRadiance = mix(finalRadiance, meanColor);
//finalRadiance = vec4(inscatterColor, 1.0);
//finalRadiance = vec4(HDR(groundColor), 1.0);
//finalRadiance = vec4(HDR(inscatterColor), 1.0);
//finalRadiance = vec4(HDR(inscatterColor + meanColor.xyz), meanColor.w);
//finalRadiance = vec4(HDR(sunColor), 1.0);
//finalRadiance = vec4(sunColor, 1.0);
//finalRadiance = vec4(HDR(inscatterColor + groundColor), 1.0);
//finalRadiance = vec4(1.0 - HDR(vec3(pixelDepth/100)),1.0);
renderTarget = finalRadiance;
}
} else {
renderTarget = vec4(HDR(meanColor.xyz * 1.8), meanColor.a);
//renderTarget = meanColor;
}
}
}

View File

@@ -1,92 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D nightTex;
in vec2 vs_st;
in vec2 vs_nightTex;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 test;
in vec4 vs_gPosition;
in vec3 vs_gNormal;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 diffuse = texture(texture1, vs_st);
vec4 diffuse2 = texture(nightTex, vs_st);
Fragment frag;
if (_performShading) {
// directional lighting
vec3 origin = vec3(0.0);
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_normal.xyz);
//vec3 e = normalize(camdir);
vec3 l_pos = vec3(sun_pos); // sun.
vec3 l_dir = normalize(l_pos-objpos.xyz);
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1);
float shine = 0.0001;
vec4 specular = vec4(0.5);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
vec4 daytex = max(intensity * diffuse, ambient);
vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2);
diffuse = (daytex*2 + mixtex)/3;
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = vs_position.w;
// G-Buffer
// TODO: get the write reflectance from the texture
frag.gOtherData = vec4(diffuse.xyz, 1.0);
frag.gPosition = vs_gPosition;
frag.gNormal = vec4(vs_gNormal, 1.0);
return frag;
}

View File

@@ -1,82 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 "PowerScaling/powerScaling_vs.hglsl"
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_gPosition;
out vec3 vs_gNormal;
uniform mat4 ModelTransform;
uniform mat4 modelViewProjectionTransform;
uniform sampler2D heightTex;
uniform bool _hasHeightMap;
uniform float _heightExaggeration;
void main() {
// set variables
vs_st = in_st;
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));
// G-Buffer
vs_gNormal = in_normal;
// The tmp is now in the OS eye space (camera rig space)
// and wrtitten using PSC coords.
// position is in the same space, i.e., OS eye space but
// in meters (no PSC coords).
vec4 position = vec4(tmp.xyz * pow(10, tmp. w), 1.0);
// G-Buffer
vs_gPosition = position;
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;
}
position = modelViewProjectionTransform * position;
// The depth position will be handle later by the fragment shader,
// so the z coordinate here is set to 0 (zero) to avoid precision problems
vs_position = z_normalization(position);
gl_Position = vs_position;
}

View File

@@ -1,77 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 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 vec4 color#{id};
uniform float time#{id};
uniform float maxStepSize#{id} = 0.02;
void sample#{id}(vec3 samplePos,
vec3 dir,
inout vec3 accumulatedColor,
inout vec3 accumulatedAlpha,
inout float stepSize) {
// Generate a procedural placeholder volume.
// In real situations, the sample function would sample a
// 3D texture to retrieve the color contribution of a given point.
vec3 fromCenter = vec3(0.5, 0.5, 0.5) - samplePos;
float theta = atan(fromCenter.x, fromCenter.z);
float angularRatio = (theta + 3.1415) / 6.283;
angularRatio = mod(angularRatio + time#{id}*0.01, 1.0);
float timeWave = sin(mod(time#{id}*0.05, 2.0 * 3.1415));
float rDisplacement = 0.1 * timeWave;
vec4 c = color#{id};
float r = length(fromCenter);
c.a *= (1.0 - smoothstep(0.35 + rDisplacement, 0.40 + rDisplacement, r));
c.a *= (1.0 - smoothstep(0.30 + rDisplacement, 0.25 + rDisplacement, r));
c.a *= (1.0 - smoothstep(0.1, 0.2, abs(fromCenter.y) / angularRatio * 0.5));
c.a *= 1.0 - smoothstep(0.0, 1.0, clamp(angularRatio, 0.0, 1.0));
c.a *= smoothstep(0.0, 0.1, clamp(angularRatio, 0.0, 1.0));
vec3 backAlpha = c.aaa * 10.0;
vec3 backColor = c.rgb * backAlpha;
backColor *= stepSize;
backAlpha *= stepSize;
backColor = clamp(backColor, 0.0, 1.0);
backAlpha = clamp(backAlpha, 0.0, 1.0);
vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha;
accumulatedColor += oneMinusFrontAlpha * backColor;
accumulatedAlpha += oneMinusFrontAlpha * backAlpha;
stepSize = maxStepSize#{id};
}
float stepSize#{id}(vec3 samplePos, vec3 dir) {
return maxStepSize#{id};
}

View File

@@ -1,90 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 vec4 campos;
uniform vec4 objpos;
//uniform vec3 camdir; // add this for specular
uniform vec3 sun_pos;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float time;
uniform sampler2D texture1;
in vec2 vs_st;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 vs_gPosition;
in vec3 vs_gNormal;
#include "fragment.glsl"
#include "PowerScaling/powerScaling_fs.hglsl"
//#include "PowerScaling/powerScaling_vs.hglsl"
Fragment getFragment() {
vec4 diffuse = texture(texture1, vs_st);
Fragment frag;
if (_performShading) {
// directional lighting
vec3 origin = vec3(0.0);
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_normal.xyz);
//vec3 e = normalize(camdir);
vec3 l_pos = vec3(sun_pos); // sun.
vec3 l_dir = normalize(l_pos-objpos.xyz);
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
float shine = 0.0001;
vec4 specular = vec4(0.5);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
/*
if(intensity > 0.f){
// halfway vector
vec3 h = normalize(l_dir + e);
// specular factor
float intSpec = max(dot(h,n),0.0);
spec = specular * pow(intSpec, shine);
}
*/
diffuse = max(intensity * diffuse, ambient);
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = vs_position.w;
// TODO: get the write reflectance from the texture
frag.gOtherData = vec4(diffuse.xyz, 1.0);
frag.gPosition = vs_gPosition;
frag.gNormal = vec4(vs_gNormal, 1.0);
return frag;
}

View File

@@ -1,80 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 ModelTransform;
uniform mat4 ViewProjection;
layout(location = 0) in vec4 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 vec4 vs_posWorld;
out float s;
out vec4 vs_gPosition;
out vec3 vs_gNormal;
#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));
// G-Buffer
vs_gNormal = in_normal;
// The tmp is now in the OS eye space (camera rig space)
// and wrtitten using PSC coords.
// position is in the same space, i.e., OS eye space but
// in meters (no PSC coords).
vec4 position = pscTransform(tmp, ModelTransform);
// G-Buffer
vs_gPosition = position;
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;
// OS Eye space and PSC coords
vs_position = tmp;
// Now is transforming from view position to SGCT projection
// coordinates.
position = ViewProjection * position;
// The depth position will be handle later by the fragment shader,
// so the z coordinate here is set to 0 (zero) to avoid precision problems
gl_Position = z_normalization(position);
}

View File

@@ -1,136 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
const uint numberOfShadows = 1;
struct ShadowRenderingStruct {
float xu, xp;
float rs, rc;
vec3 sourceCasterVec;
vec3 casterPositionVec;
bool isShadowing;
};
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
uniform vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float time;
uniform sampler2D texture1;
in vec2 vs_st;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 vs_posWorld;
in vec4 vs_gPosition;
in vec3 vs_gNormal;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
vec4 butterworthFunc(const float d, const float r, const float n) {
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
}
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);
Fragment frag;
if (_performShading) {
// directional lighting
vec3 origin = vec3(0.0);
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_normal.xyz);
//vec3 e = normalize(camdir);
vec3 l_pos = vec3(sun_pos); // sun.
vec3 l_dir = normalize(l_pos-objpos.xyz);
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1);
float shine = 0.0001;
vec4 specular = vec4(0.5);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
vec4 daytex = max(intensity * diffuse, ambient);
//vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2);
//diffuse = (daytex*2 + mixtex)/3;
diffuse = daytex;
diffuse *= calcShadow(shadowDataArray, vs_posWorld.xyz);
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = depth;
frag.gOtherData = vec4(diffuse.xyz, 1.0);
frag.gPosition = vs_gPosition;
frag.gNormal = vec4(vs_gNormal, 1.0);
return frag;
}

View File

@@ -1,138 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
const uint numberOfShadows = 1;
struct ShadowRenderingStruct {
float xu, xp;
float rs, rc;
vec3 sourceCasterVec;
vec3 casterPositionVec;
bool isShadowing;
};
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
uniform vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D nightTex;
in vec2 vs_st;
in vec2 vs_nightTex;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 vs_posWorld;
in vec4 vs_gPosition;
in vec3 vs_gNormal;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
vec4 butterworthFunc(const float d, const float r, const float n) {
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
}
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);
Fragment frag;
if (_performShading) {
// directional lighting
vec3 origin = vec3(0.0);
vec4 spec = vec4(0.0);
vec3 n = normalize(vs_normal.xyz);
//vec3 e = normalize(camdir);
vec3 l_pos = vec3(sun_pos); // sun.
vec3 l_dir = normalize(l_pos-objpos.xyz);
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1);
float shine = 0.0001;
vec4 specular = vec4(0.5);
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
vec4 daytex = max(intensity * diffuse, ambient);
vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2);
diffuse = (daytex*2 + mixtex)/3;
diffuse *= calcShadow(shadowDataArray, vs_posWorld.xyz);
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = depth;
frag.gOtherData = vec4(diffuse.xyz, 1.0);
frag.gPosition = vs_gPosition;
frag.gNormal = vec4(vs_gNormal, 1.0);
return frag;
}

View File

@@ -1,94 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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;
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;
uniform sampler2D heightTex;
uniform bool _hasHeightMap;
uniform float _heightExaggeration;
out vec2 vs_st;
out vec4 vs_normal;
out vec4 vs_position;
out vec4 vs_posWorld;
out float s;
out vec4 vs_gPosition;
out vec3 vs_gNormal;
#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));
// G-Buffer
vs_gNormal = in_normal;
// The tmp is now in the OS eye space (camera rig space)
// and wrtitten using PSC coords.
// position is in the same space, i.e., OS eye space but
// in meters (no PSC coords).
vec4 position = pscTransform(tmp, ModelTransform);
vs_gPosition = position;
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;
}
// G-Buffer
//vs_gPosition = position;
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;
// OS Eye space and PSC coords
vs_position = tmp;
// Now is transforming from view position to SGCT projection
// coordinates.
position = ViewProjection * position;
// The depth position will be handle later by the fragment shader,
// so the z coordinate here is set to 0 (zero) to avoid precision problems
gl_Position = z_normalization(position);
}

View File

@@ -1,91 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 bool _hasHeightMap;
uniform float _heightExaggeration;
uniform sampler2D heightTex;
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 vs_gPosition;
out vec3 vs_gNormal;
#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));
// We are using the normal in Object (model) space in G-Buffer (because of atm).
vs_gNormal = in_normal;
// The tmp is now in the OS eye space (camera rig space)
// and wrtitten using PSC coords.
// position is in the same space, i.e., OS eye space but
// in meters (no PSC coords).
vec4 position = pscTransform(tmp, ModelTransform);
// G-Buffer
vs_gPosition = position;
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 is transforming from view position to SGCT projection
// coordinates.
position = ViewProjection * position;
// The depth position will be handle later by the fragment shader,
// so the z coordinate here is set to 0 (zero) to avoid precision problems
gl_Position = z_normalization(position);
}

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) out vec4 renderTableColor;
void main(void) {
renderTableColor = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
}

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);
}

View File

@@ -58,14 +58,14 @@ void main() {
vs_gNormal = in_normal;
vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1.0);
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;
}
// G-Buffer
vs_gPosition = vec4(modelViewTransform * position); // Must be in SGCT eye space