Initial implementation of Atmosphere Effects. Use framebuffer to render it.

This commit is contained in:
Jonathas Costa
2016-06-07 10:35:18 -04:00
parent d6c9a65089
commit 388bb15461
40 changed files with 3993 additions and 62 deletions
File diff suppressed because it is too large Load Diff
+108
View File
@@ -31,6 +31,8 @@
#include <openspace/properties/stringproperty.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/textureunit.h>
#include <vector>
#include <string>
@@ -63,7 +65,39 @@ public:
glm::vec3 casterPositionVec;
bool isShadowing;
};
// See: Precomputed Atmospheric Scattering from Bruneton et al.
// for explanation of the following parameters.
const unsigned int TRANSMITTANCE_TABLE_WIDTH = 256;
const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 64;
const unsigned int IRRADIANCE_TABLE_WIDTH = 64;
const unsigned int IRRADIANCE_TABLE_HEIGHT = 16;
const unsigned int DELTA_E_TABLE_WIDTH = 64;
const unsigned int DELTA_E_TABLE_HEIGHT = 16;
/*const unsigned int TRANSMITTANCE_TABLE_WIDTH = 512;
const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 128;
const unsigned int IRRADIANCE_TABLE_WIDTH = 128;
const unsigned int IRRADIANCE_TABLE_HEIGHT = 32;
const unsigned int DELTA_E_TABLE_WIDTH = 128;
const unsigned int DELTA_E_TABLE_HEIGHT = 32;*/
const unsigned int R_SAMPLES = 32;
const unsigned int MU_SAMPLES = 128;
const unsigned int MU_S_SAMPLES = 32;
const unsigned int NU_SAMPLES = 8;
/*const unsigned int R_SAMPLES = 64;
const unsigned int MU_SAMPLES = 256;
const unsigned int MU_S_SAMPLES = 64;
const unsigned int NU_SAMPLES = 16;*/
public:
RenderablePlanet(const ghoul::Dictionary& dictionary);
~RenderablePlanet();
@@ -78,15 +112,69 @@ public:
protected:
void loadTexture();
private:
void loadComputationPrograms();
void unloadComputationPrograms();
void createComputationTextures();
void deleteComputationTextures();
void deleteUnusedComputationTextures();
void loadAtmosphereDataIntoShaderProgram(std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg);
void executeCalculations(const GLuint vao, const GLenum drawBuffers[2], const GLsizei vertexSize);
void preCalculateAtmosphereParam();
void createAtmosphereFBO();
void createRenderQuad(GLuint * vao, GLuint * vbo, const GLfloat size);
void renderQuadForCalc(const GLuint vao, const GLsizei size);
void step3DTexture(std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg,
const int layer, const bool doCalc = true);
void saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName,
const int width, const int height) const;
private:
properties::StringProperty _colorTexturePath;
properties::StringProperty _nightTexturePath;
properties::StringProperty _heightMapTexturePath;
properties::StringProperty _cloudsTexturePath;
properties::StringProperty _reflectanceTexturePath;
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceSupTermsProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringSupTermsProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaEProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSSupTermsProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaJProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _atmosphereProgramObject;
ghoul::opengl::TextureUnit _dummyTextureUnit;
ghoul::opengl::TextureUnit _dummy3DTextureUnit;
ghoul::opengl::TextureUnit _transmittanceTableTextureUnit;
ghoul::opengl::TextureUnit _irradianceTableTextureUnit;
ghoul::opengl::TextureUnit _inScatteringTableTextureUnit;
ghoul::opengl::TextureUnit _deltaETableTextureUnit;
ghoul::opengl::TextureUnit _deltaSRayleighTableTextureUnit;
ghoul::opengl::TextureUnit _deltaSMieTableTextureUnit;
ghoul::opengl::TextureUnit _deltaJTableTextureUnit;
ghoul::opengl::TextureUnit _atmosphereTextureUnit;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::unique_ptr<ghoul::opengl::Texture> _nightTexture;
std::unique_ptr<ghoul::opengl::Texture> _reflectanceTexture;
std::unique_ptr<ghoul::opengl::Texture> _heightMapTexture;
std::unique_ptr<ghoul::opengl::Texture> _cloudsTexture;
GLuint _transmittanceTableTexture;
GLuint _irradianceTableTexture;
GLuint _inScatteringTableTexture;
GLuint _deltaETableTexture;
GLuint _deltaSRayleighTableTexture;
GLuint _deltaSMieTableTexture;
GLuint _deltaJTableTexture;
GLuint _dummyTexture;
GLuint _dummy3DTexture;
GLuint _atmosphereTexture;
GLuint _atmosphereFBO;
GLuint _atmosphereRenderVAO;
GLuint _atmosphereRenderVBO;
properties::FloatProperty _heightExaggeration;
@@ -101,9 +189,29 @@ private:
std::string _frame;
std::string _target;
bool _hasNightTexture;
bool _hasReflectanceTexture;
bool _hasHeightTexture;
bool _hasCloudsTexture;
bool _shadowEnabled;
double _time;
// Atmosphere Data
bool _atmosphereCalculated;
bool _atmosphereEnabled;
float _atmosphereRadius;
float _atmospherePlanetRadius;
float _planetAverageGroundReflectance;
float _rayleighHeightScale;
float _mieHeightScale;
float _miePhaseConstant;
glm::vec3 _mieExtinctionCoeff;
glm::vec3 _rayleighScatteringCoeff;
glm::vec3 _mieScatteringCoeff;
bool tempPic;
unsigned int count;
};
} // namespace openspace
@@ -0,0 +1,85 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
// Atmosphere Rendering Parameters
uniform float Rg;
uniform float Rt;
uniform float AVERAGE_GROUND_REFLECTANCE;
uniform float HR;
uniform vec3 betaR;
uniform float HM;
uniform vec3 betaMSca;
uniform vec3 betaMEx;
uniform float mieG;
const float ATM_EPSILON = 1.0;
// const float RL = Rt + 1.0;
// const float Rg = 6360.0;
// const float Rt = 6420.0;
// const float RL = 6421.0;
// const float ATM_EPSILON = 1.0;
// const float AVERAGE_GROUND_REFLECTANCE = 0.1;
// // Rayleigh
// const float HR = 8.0;
// const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2);
// // Mie
// // DEFAULT
// const float HM = 1.2;
// const vec3 betaMSca = vec3(4e-3);
// //const vec3 betaMSca = vec3(2e-5);
// const vec3 betaMEx = betaMSca / 0.9;
// const float mieG = 1.0;
// Integration steps
const int TRANSMITTANCE_STEPS = 500;
const int INSCATTER_INTEGRAL_SAMPLES = 50;
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
// The next values crash NVIDIA driver for Quadro K620 -- JCC
// const int TRANSMITTANCE_INTEGRAL_SAMPLES = 1000;
// const int INSCATTER_INTEGRAL_SAMPLES = 100;
// const int IRRADIANCE_INTEGRAL_SAMPLES = 64;
// const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 32;
const float M_PI = 3.141592657;
const int TRANSMITTANCE_W = 256;
const int TRANSMITTANCE_H = 64;
const int SKY_W = 64;
const int SKY_H = 16;
const int OTHER_TEXTURES_W = 64;
const int OTHER_TEXTURES_H = 16;
const int RES_R = 32;
const int RES_MU = 128;
const int RES_MU_S = 32;
const int RES_NU = 8;
+437
View File
@@ -0,0 +1,437 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#define EPSILON 0.0001f
// Sun Irradiance
const float ISun = 50.0;
const uint numberOfShadows = 1;
struct ShadowRenderingStruct {
float xu, xp;
float rs, rc;
vec3 sourceCasterVec;
vec3 casterPositionVec;
bool isShadowing;
};
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
uniform mat4 completeInverse;
uniform mat4 projInverse;
uniform vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform vec4 cameraPosObj;
uniform vec4 planetPositionObj;
uniform vec3 sunPositionObj;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float screenX;
uniform float screenY;
uniform float screenWIDTH;
uniform float screenHEIGHT;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D nightTex;
uniform sampler2D cloudsTexture;
uniform sampler2D reflectanceTexture;
uniform sampler2D transmittanceTexture;
uniform sampler2D irradianceTexture;
uniform sampler3D inscatterTexture;
// TODO: Remove from there!
// the transmittance sampler is in scatteringinclude.glsl
//layout(origin_upper_left) in vec4 gl_FragCoord;
in vec2 vs_st;
in vec2 vs_nightTex;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 vs_posWorld;
#include "hdr.glsl"
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
#include "atmosphere_common.glsl"
vec4 butterworthFunc(const float d, const float r, const float n) {
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
}
/*******************************************************************************
****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ******
*******************************************************************************/
/* Calculates the intersection of the view ray direction with the atmosphere and
* returns the first intersection (0.0 when inside atmosphere): offset
* and the second intersection: maxLength
*/
bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const float sphereRadius,
out float offset, out float maxLength) {
offset = 0.0f;
maxLength = 0.0f;
vec3 l = planetPos.xyz - cameraPosObj.xyz;
float s = dot(l, rayDirection);
float l2 = dot(l, l);
// sphereRadius in Km
float r = sphereRadius - EPSILON; // EPSILON to avoid surface acne
float r2 = r * r;
if (l2 <= r2) {
// ray origin inside sphere
float m2 = l2 - (s*s);
float q = sqrt(r2 - m2);
maxLength = s + q;
return true;
}
else if (s >= 0.0) {
// ray outside sphere
float m2 = l2 - (s*s);
if (m2 <= r2) {
// ray hits atmosphere
float q = sqrt(r2 - m2);
offset = s-q;
maxLength = (s+q)-offset;
return true;
}
}
return false;
}
// Rayleigh phase function
float phaseFunctionR(float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase function
float phaseFunctionM(float mu) {
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
}
float opticalDepth(float H, float r, float mu, float d) {
float a = sqrt((0.5/H)*r);
vec2 a01 = a*vec2(mu, mu + d / r);
vec2 a01s = sign(a01);
vec2 a01sq = a01*a01;
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0)));
}
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
vec3 analyticTransmittance(float r, float mu, float d) {
return exp(- betaR * opticalDepth(HR, r, mu, d) - betaMEx * opticalDepth(HM, r, mu, d));
}
vec3 getMie(vec4 rayMie) {
return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaR.r / betaR);
}
vec2 getTransmittanceUV(float r, float mu) {
float uR, uMu;
uR = sqrt((r - Rg) / (Rt - Rg));
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return vec2(uMu, uR);
}
vec3 transmittanceFromTexture(float r, float mu) {
vec2 uv = getTransmittanceUV(r, mu);
return texture(transmittanceTexture, uv).rgb;
}
vec3 transmittanceWithShadow(float r, float mu) {
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu);
}
vec3 transmittance(float r, float mu, vec3 v, vec3 x0) {
vec3 result;
float r1 = length(x0);
float mu1 = dot(x0, v) / r;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
vec2 getIrradianceUV(float r, float muS) {
float uR = (r - Rg) / (Rt - Rg);
float uMuS = (muS + 0.2) / (1.0 + 0.2);
return vec2(uMuS, uR);
}
vec3 irradiance(sampler2D sampler, float r, float muS) {
vec2 uv = getIrradianceUV(r, muS);
return texture(sampler, uv).rgb;
}
/*
* Calculates the light scattering in the view direction comming from other
* light rays scattered in the atmosphere.
* The view direction here is the ray: x + tv, s is the sun direction,
* r and mu the position and zenith cossine angle as in the paper.
*/
vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s,
out float r, out float mu, out vec3 attenuation) {
vec3 result;
r = length(x);
mu = dot(x, v) / r;
float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
if (d > 0.0) {
x += d * v;
t -= d;
mu = (r * mu + d) / Rt;
r = Rt;
}
// Intersects atmosphere?
if (r <= Rt) {
float nu = dot(v, s);
float muS = dot(x, s) / r;
float phaseR = phaseFunctionR(nu);
float phaseM = phaseFunctionM(nu);
vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0);
if (t > 0.0) {
vec3 x0 = x + t * v;
float r0 = length(x0);
float rMu0 = dot(x0, v);
float mu0 = rMu0 / r0;
float muS0 = dot(x0, s) / r0;
attenuation = analyticTransmittance(r, mu, t);
//attenuation = transmittance(r, mu, v, x+t*v);
//The following Code is generating surface acne on atmosphere. JCC
// We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x
if (r0 > Rg + 0.1*r) {
inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0);
const float EPS = 0.004;
float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
if (abs(mu - muHoriz) < EPS) {
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
mu = muHoriz - EPS;
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
mu = muHoriz + EPS;
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
inscatter = mix(inScatterA, inScatterB, a);
}
}
}
inscatter.w *= smoothstep(0.00, 0.02, muS);
result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0);
} else {
// No intersection with earth
result = vec3(0.0);
}
return result * ISun;
}
vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation)
{
vec3 result;
// Ray hits ground
if (t > 0.0) {
vec3 x0 = x + t * v;
float r0 = length(x0);
vec3 n = x0 / r0;
// Fixing texture coordinates:
vec4 reflectance = texture(reflectanceTexture, vs_st) * vec4(0.2, 0.2, 0.2, 1.0);
// The following code is generating surface acne in ground.
// It is only necessary inside atmosphere rendering. JCC
// if (r0 > Rg + 0.01) {
// reflectance = vec4(0.4, 0.4, 0.4, 0.0);
// }
float muS = dot(n, s);
vec3 sunLight = transmittanceWithShadow(r0, muS);
vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS);
vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st);
vec3 groundColor = (reflectance.rgb + clouds.rgb) *
(max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI;
// Yellowish reflection from sun on oceans and rivers
if (reflectance.w > 0.0) {
vec3 h = normalize(s - v);
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun;
}
result = attenuation * groundColor;
} else {
// No hit
result = vec3(0.0);
}
return result;
}
vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) {
if (t > 0.0) {
return vec3(0.0);
} else {
vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0);
float isun = step(cos(M_PI / 180.0), dot(v, s)) * ISun;
return transmittance * isun;
}
}
/***********************************************************************
******* CALCULATIONS FOR SHADOWS ARE IN WORLD SPACE IN METERS *********
***********************************************************************/
// TODO: Change calculations for view space in KM.
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) {
if (shadowInfoArray[0].isShadowing) {
vec3 pc = shadowInfoArray[0].casterPositionVec - position;
vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader
vec3 pc_proj = dot(pc, sc_norm) * sc_norm;
vec3 d = pc - pc_proj;
float length_d = length(d);
float length_pc_proj = length(pc_proj);
float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp;
//float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu;
float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu;
if ( length_d < r_u_pi ) { // umbra
//return vec4(0.0, 0.0, 0.0, 1.0);
//return vec4(1.0, 0.0, 0.0, 1.0);
return butterworthFunc(length_d, r_u_pi, 4.0);
}
else if ( length_d < r_p_pi ) {// penumbra
//return vec4(0.5, 0.5, 0.5, 1.0);
//return vec4(0.0, 1.0, 0.0, 1.0);
return vec4(vec3(length_d/r_p_pi), 1.0);
}
}
return vec4(1.0);
}
Fragment getFragment() {
vec4 position = vs_position;
float depth = pscDepth(position);
vec4 diffuse = texture(texture1, vs_st);
vec4 diffuse2 = texture(nightTex, vs_st);
vec4 clouds = texture(cloudsTexture, vs_st);
Fragment frag;
if (_performShading) {
// atmosphere
vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT);
vec4 ndcPos;
ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
(gl_DepthRange.far - gl_DepthRange.near);
ndcPos.w = 1.0;
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(planetPositionObj, v, Rt, offset, maxLength)) {
if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) {
// Following paper nomenclature
float t = offset;
vec3 x = cameraPosObj.xyz;// + offset * v;
float r = length(x);
float mu = dot(x, v) / r;
vec3 s = normalize(sunPositionObj);
vec3 attenuation;
vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation);
vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation);
vec3 sunColor = sunColor(x, t, v, s, r, mu);
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0));
//diffuse = HDR(vec4(sunColor, 1.0));
//diffuse = HDR(vec4(groundColor, 1.0));
//diffuse = HDR(vec4(inscatterColor, 1.0));
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2 + clouds);
diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) *
calcShadow(shadowDataArray, vs_posWorld.xyz) );
}
// else
// diffuse = HDR(diffuse);
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = depth;
return frag;
}
+76
View File
@@ -0,0 +1,76 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform mat4 NormalTransform;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
layout(location = 2) in vec3 in_normal;
//layout(location = 3) in vec2 in_nightTex;
out vec2 vs_st;
out vec4 vs_normal;
out vec4 vs_position;
out vec4 vs_posWorld;
out float s;
out vec4 ray;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
// set variables
vs_st = in_st;
vs_position = in_position;
vec4 tmp = in_position;
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
//vs_normal = normalize(ModelTransform * vec4(in_normal,0));
// This is the wright transformation for the normals
vs_normal = normalize(NormalTransform * vec4(in_normal,0));
// The position is not in world coordinates, it is in
// regular view/eye coordinates.
vec4 position = pscTransform(tmp, ModelTransform);
// Vertex position in world coordinates in meters and
// with no powerscalling coordiantes
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0);
vs_posWorld = conv;
vs_position = tmp;
// Now the position is transformed from view coordinates to SGCT projection
// coordinates.
position = ViewProjection * position;
gl_Position = z_normalization(position);
}
+48
View File
@@ -0,0 +1,48 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
// See paper algorithm
uniform int line;
uniform sampler2D deltaETexture;
Fragment getFragment() {
if (line == 4)
renderTableColor = vec4(0.0);
else if (line == 10) {
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H);
renderTableColor = texture(deltaETexture, uv);
}
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
+31
View File
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
+192
View File
@@ -0,0 +1,192 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
uniform sampler2D deltaETexture;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
uniform float first;
const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase
float phaseFunctionM(const float mu) {
return (3.0 / (8.0 * M_PI)) *
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
}
vec3 irradiance(sampler2D calcTexture, const float r, const float mu_s) {
float u_r = (r - Rg) / (Rt - Rg);
float u_mu_s = (mu_s + 0.2) / (1.0 + 0.2);
return texture(calcTexture, vec2(u_mu_s, u_r)).rgb;
}
vec4 texture4D(sampler3D table, const float r, const float mu,
const float mu_s, const float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float u_r = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float u_mu_s = 0.5 / float(RES_MU_S) + (atan(max(mu_s, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + u_mu_s) / float(RES_NU), u_mu, u_r)) * (1.0 - lerp) +
texture(table, vec3((uNu + u_mu_s + 1.0) / float(RES_NU), u_mu, u_r)) * lerp;
}
void inscatter(float r, float mu, float mu_s, float nu, out vec3 raymie) {
r = clamp(r, Rg, Rt);
mu = clamp(mu, -1.0, 1.0);
mu_s = clamp(mu_s, -1.0, 1.0);
float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - mu_s * mu_s);
nu = clamp(nu, mu_s * mu - var, mu_s * mu + var);
float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r));
vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu);
float sx = v.x == 0.0 ? 0.0 : (nu - mu_s * mu) / v.x;
vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - mu_s * mu_s)), mu_s);
raymie = vec3(0.0);
for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) {
float theta = (float(itheta) + 0.5) * dtheta;
float ctheta = cos(theta);
float greflectance = 0.0;
float dground = 0.0;
vec3 gtransp = vec3(0.0);
if (ctheta < cthetamin) {
greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI;
dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg);
gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground);
}
for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) {
float phi = (float(iphi) + 0.5) * dphi;
float dw = dtheta * dphi * sin(theta);
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta);
float nu1 = dot(s, w);
float nu2 = dot(v, w);
float pr2 = phaseFunctionR(nu2);
float pm2 = phaseFunctionM(nu2);
vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg;
vec3 girradiance = irradiance(deltaETexture, Rg, dot(gnormal, s));
vec3 raymie1;
raymie1 = greflectance * girradiance * gtransp;
if (first == 1.0) {
float pr1 = phaseFunctionR(nu1);
float pm1 = phaseFunctionM(nu1);
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu1).rgb;
raymie1 += ray1 * pr1 + mie1 * pm1;
} else {
raymie1 += texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
}
raymie += raymie1 * (betaR * exp(-(r - Rg) / HR) * pr2 + betaMSca * exp(-(r - Rg) / HM) * pm2) * dw;
}
}
}
Fragment getFragment() {
vec3 raymie;
float mu, mu_s, nu;
getMuMuSNu(r, dhdH, mu, mu_s, nu);
inscatter(r, mu, mu_s, nu, raymie);
renderTarget1 = vec4(raymie, 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
+41
View File
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}
+31
View File
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
+51
View File
@@ -0,0 +1,51 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform int layer;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
Fragment getFragment() {
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
vec4 ray = texture(deltaSRTexture, uvw);
vec4 mie = texture(deltaSMTexture, uvw);
// We are using only the red component of the Mie scattering
// See the Precomputed Atmosphere Scattering paper for details about
// the angular precision.
renderTarget1 = vec4(ray.rgb, mie.r);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
+41
View File
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}
+31
View File
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
@@ -0,0 +1,54 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform int layer;
uniform sampler3D deltaSTexture;
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
Fragment getFragment() {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
float nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / phaseFunctionR(nu), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}
+35
View File
@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
uniform float exposure;
vec4 HDR(vec4 color) {
color *= exposure;
color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.r);
color.g = color.g < 1.413 ? pow(color.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.g);
color.b = color.b < 1.413 ? pow(color.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.b);
return color;
}
@@ -0,0 +1,154 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
layout(location = 2) out vec4 renderTarget2;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
// In the following shaders r (altitude) is the length of vector/position x in the
// atmosphere (or on the top of it when considering an observer in space),
// where the light is comming from the opposity direction of the view direction,
// here the vector v or viewDirection.
// Rg is the planet radius
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
void integrand(const float r, const float mu, const float muS, const float nu,
const float t, out vec3 ray, out vec3 mie) {
ray = vec3(0.0);
mie = vec3(0.0);
float ri = sqrt(r * r + t * t + 2.0 * r * mu * t);
float muSi = (nu * t + muS * r) / ri;
ri = max(Rg, ri);
if (muSi >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
vec3 ti = transmittance(r, mu, t) * transmittanceFromTexture(ri, muSi);
ray = exp(-(ri - Rg) / HR) * ti;
mie = exp(-(ri - Rg) / HM) * ti;
}
}
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
void inscatter(float r, float mu, float muS, float nu, out vec3 ray, out vec3 mie) {
// Integrating using the Trapezoidal rule:
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
ray = vec3(0.0);
mie = vec3(0.0);
float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
float xi = 0.0;
vec3 rayi;
vec3 miei;
integrand(r, mu, muS, nu, 0.0, rayi, miei);
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
float xj = float(i) * dx;
vec3 rayj;
vec3 miej;
integrand(r, mu, muS, nu, xj, rayj, miej);
ray += (rayi + rayj) / 2.0 * dx;
mie += (miei + miej) / 2.0 * dx;
xi = xj;
rayi = rayj;
miei = miej;
}
ray *= betaR;
mie *= betaMSca;
}
Fragment getFragment() {
vec3 ray;
vec3 mie;
float mu, muS, nu;
getMuMuSNu(r, dhdH, mu, muS, nu);
inscatter(r, mu, muS, nu, ray, mie);
// store separately Rayleigh and Mie contributions, WITHOUT the phase function factor
// (cf "Angular precision")
renderTarget1 = vec4(ray, 1.0);
renderTarget2 = vec4(mie, 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
@@ -0,0 +1,155 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
uniform sampler3D deltaJTexture;
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
float limit(float r, float mu) {
float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + ((Rt+ATM_EPSILON) * (Rt+ATM_EPSILON)));
float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg;
if (delta2 >= 0.0) {
float din = -r * mu - sqrt(delta2);
if (din >= 0.0) {
dout = min(dout, din);
}
}
return dout;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, const float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
vec3 integrand(float r, float mu, float muS, float nu, float t) {
float ri = sqrt(r * r + t * t + 2.0 * r * mu * t);
float mui = (r * mu + t) / ri;
float muSi = (nu * t + muS * r) / ri;
return texture4D(deltaJTexture, ri, mui, muSi, nu).rgb * transmittance(r, mu, t);
}
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
vec3 inscatter(float r, float mu, float muS, float nu) {
vec3 raymie = vec3(0.0);
float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
float xi = 0.0;
vec3 raymiei = integrand(r, mu, muS, nu, 0.0);
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
float xj = float(i) * dx;
vec3 raymiej = integrand(r, mu, muS, nu, xj);
raymie += (raymiei + raymiej) / 2.0 * dx;
xi = xj;
raymiei = raymiej;
}
return raymie;
}
Fragment getFragment() {
float mu, muS, nu;
getMuMuSNu(r, dhdH, mu, muS, nu);
renderTarget1 = vec4(inscatter(r, mu, muS, nu), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
@@ -0,0 +1,57 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
uniform sampler2D transmittanceTexture;
void getRAndMu(out float r, out float mu) {
// See Bruneton and Colliene to understand the mapping.
mu = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES_W) - 1.0) * (1.0 + 0.2);
r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES_H) - 1.0) * (Rt - Rg);
}
vec3 transmittance(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture2D(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
Fragment getFragment() {
float mu, r;
getRAndMu(r, mu);
renderTableColor = vec4(transmittance(r, mu) * max(mu, 0.0), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
@@ -0,0 +1,101 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
uniform float first;
const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
uniform sampler2D transmittanceTexture;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase
float phaseFunctionM(const float mu) {
return (3.0 / (8.0 * M_PI)) *
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
}
vec4 texture4D(sampler3D table, const float r, const float mu,
const float muS, const float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
Fragment getFragment() {
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY_H) - 1.0) * (Rt - Rg);
float mu_s = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY_W) - 1.0) * (1.0 + 0.2);
vec3 s = vec3(max(sqrt(1.0 - mu_s * mu_s), 0.0), 0.0, mu_s);
vec3 result = vec3(0.0);
for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) {
float phi = (float(iphi) + 0.5) * dphi;
for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) {
float theta = (float(itheta) + 0.5) * dtheta;
float dw = dtheta * dphi * sin(theta);
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
float nu = dot(s, w);
if (first == 1.0) {
float pr1 = phaseFunctionR(nu);
float pm1 = phaseFunctionM(nu);
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb;
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu).rgb;
result += (ray1 * pr1 + mie1 * pm1) * w.z * dw;
} else {
result += texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb * w.z * dw;
}
}
}
renderTableColor = vec4(result, 0.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}
@@ -0,0 +1,109 @@
/*****************************************************************************************
* *
* 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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
// In the following shaders r (altitude) is the length of vector/position x in the
// atmosphere (or on the top of it when considering an observer in space),
// where the light is comming from the opposity direction of the view direction,
// here the vector v or viewDirection.
// Rg is the planet radius
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
float opticalDepth(const float r, const float mu, const float scaleHeight) {
float r2 = r*r;
// Is ray below horizon?
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
float cosZenithHorizon = -sqrt(1.0 - ((Rg*Rg)/r2));
if (mu < cosZenithHorizon)
return 1e9;
// Integrating using the Trapezoidal rule:
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
float b_a = rayDistance(r, mu);
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
// cosine law
float y_i = exp(-(r - Rg) / scaleHeight);
float x_step = 0.0;
float accumulation = 0.0;
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
float x_i = float(i) * deltaStep;
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
// In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / scaleHeight);
accumulation += (y_ii + y_i);
//x_step = x_i;
y_i = y_ii;
}
return accumulation * (b_a/(2*TRANSMITTANCE_STEPS));
}
void getRandMU(out float r, out float mu) {
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W);
float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H);
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
r = sqrt(Rg*Rg + (u_r * u_r) * (Rt*Rt - Rg*Rg));
// In the paper the author suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
// But the below one is better. See Colliene.
mu = -0.15 + tan(1.5 * u_mu) / tan(1.5) * (1.0 + 0.15);
}
Fragment getFragment() {
float r, mu;
getRandMU(r, mu);
vec3 depth = betaMEx * opticalDepth(r, mu, HM) + betaR * opticalDepth(r, mu, HR);
renderTableColor = vec4(exp(-depth), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* 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);
}