mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 00:38:33 -05:00
Atmosphere frustum culling and distance culling enabled.
This commit is contained in:
@@ -99,8 +99,8 @@ return {
|
||||
--"moon",
|
||||
|
||||
"lodglobes/earth",
|
||||
--"lodglobes/mars",
|
||||
--"lodglobes/moon",
|
||||
"lodglobes/mars",
|
||||
"lodglobes/moon",
|
||||
--"satellites",
|
||||
--"mars-satellites",
|
||||
--"toyvolume",
|
||||
|
||||
@@ -217,90 +217,105 @@ void AtmosphereDeferredcaster::deinitialize()
|
||||
void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program)
|
||||
{
|
||||
program.setUniform("Rg", _atmospherePlanetRadius);
|
||||
program.setUniform("Rt", _atmosphereRadius);
|
||||
program.setUniform("AverageGroundReflectance", _planetAverageGroundReflectance);
|
||||
program.setUniform("HR", _rayleighHeightScale);
|
||||
program.setUniform("betaRayleigh", _rayleighScatteringCoeff);
|
||||
program.setUniform("HM", _mieHeightScale);
|
||||
program.setUniform("betaMieScattering", _mieScatteringCoeff);
|
||||
program.setUniform("betaMieExtinction", _mieExtinctionCoeff);
|
||||
program.setUniform("mieG", _miePhaseConstant);
|
||||
program.setUniform("sunRadiance", _sunRadianceIntensity);
|
||||
program.setUniform("ozoneLayerEnabled", (bool)_ozoneEnabled);
|
||||
program.setUniform("HO", _ozoneHeightScale);
|
||||
program.setUniform("betaOzoneExtinction", _ozoneExtinctionCoeff);
|
||||
// Atmosphere Frustum Culling
|
||||
glm::dvec3 tPlanetPosWorld = glm::dvec3(_modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
program.setUniform("exposure", _exposureConstant);
|
||||
program.setUniform("backgroundExposure", _exposureBackgroundConstant);
|
||||
program.setUniform("gamma", _gammaConstant);
|
||||
program.setUniform("RenderableClass", static_cast<int>(_renderableClass));
|
||||
|
||||
program.setUniform("TRANSMITTANCE_W", (int)_transmittance_table_width);
|
||||
program.setUniform("TRANSMITTANCE_H", (int)_transmittance_table_height);
|
||||
program.setUniform("SKY_W", (int)_irradiance_table_width);
|
||||
program.setUniform("SKY_H", (int)_irradiance_table_height);
|
||||
program.setUniform("OTHER_TEXTURES_W", (int)_delta_e_table_width);
|
||||
program.setUniform("OTHER_TEXTURES_H", (int)_delta_e_table_height);
|
||||
program.setUniform("SAMPLES_R", (int)_r_samples);
|
||||
program.setUniform("SAMPLES_MU", (int)_mu_samples);
|
||||
program.setUniform("SAMPLES_MU_S", (int)_mu_s_samples);
|
||||
program.setUniform("SAMPLES_NU", (int)_nu_samples);
|
||||
|
||||
program.setUniform("ModelTransformMatrix", _modelTransform);
|
||||
|
||||
// Object Space
|
||||
glm::dmat4 inverseModelMatrix = glm::inverse(_modelTransform);
|
||||
program.setUniform("dInverseModelTransformMatrix", inverseModelMatrix);
|
||||
|
||||
// The following scale comes from PSC transformations.
|
||||
float fScaleFactor = renderData.camera.scaling().x * pow(10.0, renderData.camera.scaling().y);
|
||||
glm::dmat4 dfScaleCamTransf = glm::scale(glm::dvec3(fScaleFactor));
|
||||
program.setUniform("dInverseScaleTransformMatrix", glm::inverse(dfScaleCamTransf));
|
||||
|
||||
// World to Eye Space in OS
|
||||
program.setUniform("dInverseCamRotTransform", glm::mat4_cast((glm::dquat)renderData.camera.rotationQuaternion()));
|
||||
|
||||
program.setUniform("dInverseSgctEyeToWorldTranform", glm::inverse(renderData.camera.combinedViewMatrix()));
|
||||
|
||||
// Eye Space in OS to Eye Space in SGCT
|
||||
glm::dmat4 dOsEye2SGCTEye = glm::dmat4(renderData.camera.viewMatrix());
|
||||
glm::dmat4 dSgctEye2OSEye = glm::inverse(dOsEye2SGCTEye);
|
||||
program.setUniform("dSgctEyeToOSEyeTranform", dSgctEye2OSEye);
|
||||
|
||||
// Eye Space in SGCT to Projection (Clip) Space in SGCT
|
||||
glm::dmat4 dSgctEye2Clip = glm::dmat4(renderData.camera.projectionMatrix());
|
||||
glm::dmat4 dInverseProjection = glm::inverse(dSgctEye2Clip);
|
||||
|
||||
program.setUniform("dInverseSgctProjectionMatrix", dInverseProjection);
|
||||
|
||||
program.setUniform("dObjpos", glm::dvec4(renderData.position.dvec3(), 1.0));
|
||||
program.setUniform("dCampos", renderData.camera.positionVec3());
|
||||
|
||||
double lt;
|
||||
glm::dvec3 sunPosWorld = SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt);
|
||||
glm::dvec4 sunPosObj = glm::dvec4(0.0);
|
||||
|
||||
// Sun following camera position
|
||||
if (_sunFollowingCameraEnabled) {
|
||||
sunPosObj = inverseModelMatrix * glm::dvec4(renderData.camera.positionVec3(), 1.0);
|
||||
if (glm::distance(tPlanetPosWorld, renderData.camera.positionVec3()) > DISTANCE_CULLING) {
|
||||
program.setUniform("cullAtmosphere", 1);
|
||||
}
|
||||
else {
|
||||
if (_renderableClass == RenderablePlanet) {
|
||||
sunPosObj = inverseModelMatrix *
|
||||
glm::dvec4(sunPosWorld - renderData.position.dvec3(), 1.0);
|
||||
glm::dmat4 MV = glm::dmat4(renderData.camera.sgctInternal.projectionMatrix()) * renderData.camera.combinedViewMatrix();
|
||||
if (!isAtmosphereInFrustum(glm::value_ptr(MV), tPlanetPosWorld, (_atmosphereRadius + 2.0)*1000.0)) {
|
||||
program.setUniform("cullAtmosphere", 1);
|
||||
}
|
||||
else if (_renderableClass == RenderableGlobe) {
|
||||
sunPosObj = inverseModelMatrix *
|
||||
glm::dvec4(sunPosWorld - renderData.modelTransform.translation, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Sun Position in Object Space
|
||||
program.setUniform("sunDirectionObj", glm::normalize(glm::dvec3(sunPosObj)));
|
||||
|
||||
program.setUniform("ellipsoidRadii", _ellipsoidRadii);
|
||||
else {
|
||||
program.setUniform("cullAtmosphere", 0);
|
||||
program.setUniform("Rg", _atmospherePlanetRadius);
|
||||
program.setUniform("Rt", _atmosphereRadius);
|
||||
program.setUniform("AverageGroundReflectance", _planetAverageGroundReflectance);
|
||||
program.setUniform("HR", _rayleighHeightScale);
|
||||
program.setUniform("betaRayleigh", _rayleighScatteringCoeff);
|
||||
program.setUniform("HM", _mieHeightScale);
|
||||
program.setUniform("betaMieScattering", _mieScatteringCoeff);
|
||||
program.setUniform("betaMieExtinction", _mieExtinctionCoeff);
|
||||
program.setUniform("mieG", _miePhaseConstant);
|
||||
program.setUniform("sunRadiance", _sunRadianceIntensity);
|
||||
program.setUniform("ozoneLayerEnabled", (bool)_ozoneEnabled);
|
||||
program.setUniform("HO", _ozoneHeightScale);
|
||||
program.setUniform("betaOzoneExtinction", _ozoneExtinctionCoeff);
|
||||
|
||||
program.setUniform("exposure", _exposureConstant);
|
||||
program.setUniform("backgroundExposure", _exposureBackgroundConstant);
|
||||
program.setUniform("gamma", _gammaConstant);
|
||||
program.setUniform("RenderableClass", static_cast<int>(_renderableClass));
|
||||
|
||||
program.setUniform("TRANSMITTANCE_W", (int)_transmittance_table_width);
|
||||
program.setUniform("TRANSMITTANCE_H", (int)_transmittance_table_height);
|
||||
program.setUniform("SKY_W", (int)_irradiance_table_width);
|
||||
program.setUniform("SKY_H", (int)_irradiance_table_height);
|
||||
program.setUniform("OTHER_TEXTURES_W", (int)_delta_e_table_width);
|
||||
program.setUniform("OTHER_TEXTURES_H", (int)_delta_e_table_height);
|
||||
program.setUniform("SAMPLES_R", (int)_r_samples);
|
||||
program.setUniform("SAMPLES_MU", (int)_mu_samples);
|
||||
program.setUniform("SAMPLES_MU_S", (int)_mu_s_samples);
|
||||
program.setUniform("SAMPLES_NU", (int)_nu_samples);
|
||||
|
||||
program.setUniform("ModelTransformMatrix", _modelTransform);
|
||||
|
||||
// Object Space
|
||||
glm::dmat4 inverseModelMatrix = glm::inverse(_modelTransform);
|
||||
program.setUniform("dInverseModelTransformMatrix", inverseModelMatrix);
|
||||
|
||||
// The following scale comes from PSC transformations.
|
||||
float fScaleFactor = renderData.camera.scaling().x * pow(10.0, renderData.camera.scaling().y);
|
||||
glm::dmat4 dfScaleCamTransf = glm::scale(glm::dvec3(fScaleFactor));
|
||||
program.setUniform("dInverseScaleTransformMatrix", glm::inverse(dfScaleCamTransf));
|
||||
|
||||
// World to Eye Space in OS
|
||||
program.setUniform("dInverseCamRotTransform", glm::mat4_cast((glm::dquat)renderData.camera.rotationQuaternion()));
|
||||
|
||||
program.setUniform("dInverseSgctEyeToWorldTranform", glm::inverse(renderData.camera.combinedViewMatrix()));
|
||||
|
||||
// Eye Space in OS to Eye Space in SGCT
|
||||
glm::dmat4 dOsEye2SGCTEye = glm::dmat4(renderData.camera.viewMatrix());
|
||||
glm::dmat4 dSgctEye2OSEye = glm::inverse(dOsEye2SGCTEye);
|
||||
program.setUniform("dSgctEyeToOSEyeTranform", dSgctEye2OSEye);
|
||||
|
||||
// Eye Space in SGCT to Projection (Clip) Space in SGCT
|
||||
glm::dmat4 dSgctEye2Clip = glm::dmat4(renderData.camera.projectionMatrix());
|
||||
glm::dmat4 dInverseProjection = glm::inverse(dSgctEye2Clip);
|
||||
|
||||
program.setUniform("dInverseSgctProjectionMatrix", dInverseProjection);
|
||||
|
||||
program.setUniform("dObjpos", glm::dvec4(renderData.position.dvec3(), 1.0));
|
||||
program.setUniform("dCampos", renderData.camera.positionVec3());
|
||||
|
||||
double lt;
|
||||
glm::dvec3 sunPosWorld = SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt);
|
||||
glm::dvec4 sunPosObj = glm::dvec4(0.0);
|
||||
|
||||
// Sun following camera position
|
||||
if (_sunFollowingCameraEnabled) {
|
||||
sunPosObj = inverseModelMatrix * glm::dvec4(renderData.camera.positionVec3(), 1.0);
|
||||
}
|
||||
else {
|
||||
if (_renderableClass == RenderablePlanet) {
|
||||
sunPosObj = inverseModelMatrix *
|
||||
glm::dvec4(sunPosWorld - renderData.position.dvec3(), 1.0);
|
||||
}
|
||||
else if (_renderableClass == RenderableGlobe) {
|
||||
sunPosObj = inverseModelMatrix *
|
||||
glm::dvec4(sunPosWorld - renderData.modelTransform.translation, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Sun Position in Object Space
|
||||
program.setUniform("sunDirectionObj", glm::normalize(glm::dvec3(sunPosObj)));
|
||||
|
||||
program.setUniform("ellipsoidRadii", _ellipsoidRadii);
|
||||
|
||||
}
|
||||
}
|
||||
_transmittanceTableTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture);
|
||||
program.setUniform("transmittanceTexture", _transmittanceTableTextureUnit);
|
||||
@@ -311,16 +326,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const D
|
||||
|
||||
_inScatteringTableTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_3D, _inScatteringTableTexture);
|
||||
program.setUniform("inscatterTexture", _inScatteringTableTextureUnit);
|
||||
|
||||
// Atmosphere Frustum Culling
|
||||
glm::dmat4 MV = glm::dmat4(renderData.camera.sgctInternal.projectionMatrix()) * renderData.camera.combinedViewMatrix();
|
||||
glm::dvec3 tPlanetPosWorld = glm::dvec3(_modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
if (isAtmosphereInFrustum(glm::value_ptr(MV), tPlanetPosWorld, (_atmosphereRadius + 2.0)*1000.0))
|
||||
std::cout << "========= Inside Frustum ========" << std::endl;
|
||||
else
|
||||
std::cout << "--------- Outside Frustum -------" << std::endl;
|
||||
program.setUniform("inscatterTexture", _inScatteringTableTextureUnit);
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::postRaycast(const RenderData & renderData, const DeferredcastData& deferredData,
|
||||
@@ -1521,25 +1527,26 @@ void AtmosphereDeferredcaster::saveTextureToPPMFile(const GLenum color_buffer_at
|
||||
bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const double * MVMatrix, const glm::dvec3 position, const double radius) const {
|
||||
|
||||
// Frustum Planes
|
||||
glm::dvec3 col1(MVMatrix[0], MVMatrix[1], MVMatrix[2]);
|
||||
glm::dvec3 col2(MVMatrix[4], MVMatrix[5], MVMatrix[6]);
|
||||
glm::dvec3 col3(MVMatrix[8], MVMatrix[9], MVMatrix[10]);
|
||||
glm::dvec3 col4(MVMatrix[12], MVMatrix[13], MVMatrix[14]);
|
||||
glm::dvec3 col1(MVMatrix[0], MVMatrix[4], MVMatrix[8]);
|
||||
glm::dvec3 col2(MVMatrix[1], MVMatrix[5], MVMatrix[9]);
|
||||
glm::dvec3 col3(MVMatrix[2], MVMatrix[6], MVMatrix[10]);
|
||||
glm::dvec3 col4(MVMatrix[3], MVMatrix[7], MVMatrix[11]);
|
||||
|
||||
glm::dvec3 leftNormal = col4 + col1;
|
||||
glm::dvec3 rightNormal = col4 - col1;
|
||||
glm::dvec3 leftNormal = col4 + col1;
|
||||
glm::dvec3 rightNormal = col4 - col1;
|
||||
glm::dvec3 bottomNormal = col4 + col2;
|
||||
glm::dvec3 topNormal = col4 - col2;
|
||||
glm::dvec3 nearNormal = col3 + col4; // maybe only col3?
|
||||
glm::dvec3 farNormal = col4 - col3;
|
||||
glm::dvec3 topNormal = col4 - col2;
|
||||
glm::dvec3 nearNormal = col3 + col4;
|
||||
glm::dvec3 farNormal = col4 - col3;
|
||||
|
||||
|
||||
// Plane Distances
|
||||
double leftDistance = MVMatrix[15] + MVMatrix[3];
|
||||
double rightDistance = MVMatrix[15] - MVMatrix[3];
|
||||
double bottomDistance = MVMatrix[15] + MVMatrix[7];
|
||||
double topDistance = MVMatrix[15] - MVMatrix[7];
|
||||
double nearDistance = MVMatrix[15] + MVMatrix[11];
|
||||
double farDistance = MVMatrix[15] - MVMatrix[11];
|
||||
double leftDistance = MVMatrix[15] + MVMatrix[12];
|
||||
double rightDistance = MVMatrix[15] - MVMatrix[12];
|
||||
double bottomDistance = MVMatrix[15] + MVMatrix[13];
|
||||
double topDistance = MVMatrix[15] - MVMatrix[13];
|
||||
double nearDistance = MVMatrix[15] + MVMatrix[14];
|
||||
double farDistance = MVMatrix[15] - MVMatrix[14];
|
||||
|
||||
// Normalize Planes
|
||||
double invMag = 1.0 / glm::length(leftNormal);
|
||||
@@ -1565,7 +1572,7 @@ bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const double * MVMatrix, co
|
||||
invMag = 1.0 / glm::length(farNormal);
|
||||
farNormal *= invMag;
|
||||
farDistance *= invMag;
|
||||
|
||||
|
||||
if ((glm::dot(leftNormal, position) + leftDistance) < -radius) {
|
||||
return false;
|
||||
} else if ((glm::dot(rightNormal, position) + rightDistance) < -radius) {
|
||||
@@ -1576,9 +1583,9 @@ bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const double * MVMatrix, co
|
||||
return false;
|
||||
} else if ((glm::dot(nearNormal, position) + nearDistance) < -radius) {
|
||||
return false;
|
||||
} else if ((glm::dot(farNormal, position) + farDistance) < -radius) {
|
||||
} /*else if ((glm::dot(farNormal, position) + farDistance) < -radius) {
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,6 +120,9 @@ private:
|
||||
bool isAtmosphereInFrustum(const double * MVMatrix, const glm::dvec3 position, const double radius) const;
|
||||
|
||||
private:
|
||||
|
||||
const double DISTANCE_CULLING = 1e10;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceSupTermsProgramObject;
|
||||
|
||||
@@ -75,6 +75,7 @@ in vec3 interpolatedNDCPos;
|
||||
// a RenderableGlobe
|
||||
uniform int RenderableClass;
|
||||
uniform int nAaSamples;
|
||||
uniform int cullAtmosphere;
|
||||
|
||||
// Background exposure hack
|
||||
uniform float backgroundExposure;
|
||||
@@ -501,240 +502,242 @@ vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const flo
|
||||
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);
|
||||
}
|
||||
float invNaaSamples = 1.0/nAaSamples;
|
||||
meanColor *= invNaaSamples;
|
||||
meanNormal *= invNaaSamples;
|
||||
meanPosition *= invNaaSamples;
|
||||
meanOtherData *= invNaaSamples;
|
||||
//mainDepth /= nAaSamples;
|
||||
|
||||
meanColor.a = maxAlpha;
|
||||
|
||||
/*
|
||||
// Temporary:
|
||||
meanNormal += texelFetch(mainNormalTexture, ivec2(gl_FragCoord), 0);
|
||||
meanColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0);;
|
||||
meanPosition += texelFetch(mainPositionTexture, ivec2(gl_FragCoord), 0);
|
||||
meanOtherData += texelFetch(otherDataTexture, ivec2(gl_FragCoord), 0);
|
||||
*/
|
||||
// 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;
|
||||
void main() {
|
||||
if (cullAtmosphere == 0) {
|
||||
//float mainDepth = 0.0;
|
||||
vec4 meanColor = vec4(0.0);
|
||||
vec4 meanNormal = vec4(0.0);
|
||||
vec4 meanPosition = vec4(0.0);
|
||||
vec4 meanOtherData = vec4(0.0);
|
||||
|
||||
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt-10*EPSILON,
|
||||
insideATM, offset, maxLength );
|
||||
//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);
|
||||
}
|
||||
float invNaaSamples = 1.0/nAaSamples;
|
||||
meanColor *= invNaaSamples;
|
||||
meanNormal *= invNaaSamples;
|
||||
meanPosition *= invNaaSamples;
|
||||
meanOtherData *= invNaaSamples;
|
||||
//mainDepth /= nAaSamples;
|
||||
|
||||
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 = dInverseSgctEyeToWorldTranform * meanPosition;
|
||||
dvec4 fragObjectCoords = dInverseModelTransformMatrix * fragWorldCoords;
|
||||
//dvec4 fragObjectCoords = dInverseModelTransformMatrix * meanPosition;//fragWorldCoords;
|
||||
double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz);
|
||||
|
||||
// All calculations are done in Km:
|
||||
pixelDepth *= 0.001;
|
||||
fragObjectCoords.xyz *= 0.001;
|
||||
|
||||
// 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 * backgroundExposure), 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 if ( RenderableClass == RenderableGlobe) {
|
||||
// Get the ray from camera to atm in object space
|
||||
dCalculateRayRenderableGlobe(ray, planetPositionObjectCoords, cameraPositionInObject);
|
||||
meanColor.a = maxAlpha;
|
||||
|
||||
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
|
||||
/*
|
||||
// Temporary:
|
||||
meanNormal += texelFetch(mainNormalTexture, ivec2(gl_FragCoord), 0);
|
||||
meanColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0);;
|
||||
meanPosition += texelFetch(mainPositionTexture, ivec2(gl_FragCoord), 0);
|
||||
meanOtherData += texelFetch(otherDataTexture, ivec2(gl_FragCoord), 0);
|
||||
*/
|
||||
// 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;
|
||||
|
||||
// OS Eye to World coords
|
||||
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt-10*EPSILON,
|
||||
insideATM, offset, maxLength );
|
||||
|
||||
// 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];
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
dvec3 tmpPos = dmat3(dInverseCamRotTransform) * dvec3(dInverseScaleTransformMatrix * farthestPosition);
|
||||
*/
|
||||
dvec4 fragWorldCoords = dInverseSgctEyeToWorldTranform * meanPosition;
|
||||
dvec4 fragObjectCoords = dInverseModelTransformMatrix * fragWorldCoords;
|
||||
//dvec4 fragObjectCoords = dInverseModelTransformMatrix * meanPosition;//fragWorldCoords;
|
||||
double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz);
|
||||
|
||||
// World to Object (Normal and Position in meters)
|
||||
dvec4 fragObjectCoords = dInverseModelTransformMatrix * 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 *= 0.001;
|
||||
fragObjectCoords.xyz *= 0.001;
|
||||
|
||||
if (meanPosition.xyz != vec3(0.0) && (pixelDepth < offset)) {
|
||||
renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), 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);
|
||||
// All calculations are done in Km:
|
||||
pixelDepth *= 0.001;
|
||||
fragObjectCoords.xyz *= 0.001;
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.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 * backgroundExposure), 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 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
|
||||
|
||||
renderTarget = finalRadiance;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 = dInverseModelTransformMatrix * 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 *= 0.001;
|
||||
fragObjectCoords.xyz *= 0.001;
|
||||
|
||||
if (meanPosition.xyz != vec3(0.0) && (pixelDepth < offset)) {
|
||||
renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), 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);
|
||||
|
||||
renderTarget = finalRadiance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user