Added new debug system for ATM precalculated textures. Cleaned up some of the ATM shaders.

This commit is contained in:
Jonathas Costa
2017-05-24 18:38:47 -04:00
parent 0cd56d776c
commit 11679cc231
11 changed files with 257 additions and 128 deletions
@@ -100,7 +100,12 @@ return {
-- }
-- H_M = 3.0,
-- G = 0.65,
-- },
-- },
Debug = {
-- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
PreCalculatedTextureScale = 1.0,
SaveCalculatedTextures = false,
},
}
},
Transform = {
+6 -1
View File
@@ -104,7 +104,12 @@ return {
-- }
-- H_M = 3.0,
-- G = 0.65,
-- },
-- },
Debug = {
-- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
PreCalculatedTextureScale = 1.0,
SaveCalculatedTextures = false,
},
},
Layers = {
ColorLayers = {
+5
View File
@@ -64,6 +64,11 @@ return {
-- Mie Phase Function Value (G e [-1.0, 1.0]. If G = 1.0, Mie phase function = Rayleigh Phase Function)
G = 0.85,
},
Debug = {
-- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
PreCalculatedTextureScale = 1.0,
SaveCalculatedTextures = false,
},
},
Layers = {
ColorLayers = {
@@ -47,7 +47,6 @@
#define _USE_MATH_DEFINES
#include <math.h>
#define _SAVE_ATMOSPHERE_TEXTURES
namespace {
const std::string _loggerCat = "AtmosphereDeferredcaster";
@@ -83,6 +82,16 @@ AtmosphereDeferredcaster::AtmosphereDeferredcaster()
, _atmosphereFBO(0)
, _atmosphereRenderVAO(0)
, _atmosphereRenderVBO(0)
, _transmittance_table_width(256)
, _transmittance_table_height(64)
, _irradiance_table_width(64)
, _irradiance_table_height(16)
, _delta_e_table_width(64)
, _delta_e_table_height(16)
, _r_samples(32)
, _mu_samples(128)
, _mu_s_samples(32)
, _nu_samples(8)
, _atmosphereCalculated(false)
, _atmosphereEnabled(false)
, _atmosphereRadius(0.f)
@@ -98,6 +107,9 @@ AtmosphereDeferredcaster::AtmosphereDeferredcaster()
, _sunRadianceIntensity(50.0f)
, _hdrConstant(0.4f)
, _renderableClass(NoRenderableClass)
, _calculationTextureScale(1.0)
, _saveCalculationTextures(false)
{}
@@ -180,8 +192,20 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const D
program.setUniform("betaMieExtinction", _mieExtinctionCoeff);
program.setUniform("mieG", _miePhaseConstant);
program.setUniform("sunRadiance", _sunRadianceIntensity);
program.setUniform("exposure", _hdrConstant);
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);
@@ -459,6 +483,25 @@ void AtmosphereDeferredcaster::setRenderableClass(const AtmosphereDeferredcaster
_renderableClass = rc;
}
void AtmosphereDeferredcaster::setPrecalculationTextureScale(const float _preCalculatedTexturesScale) {
_calculationTextureScale = _preCalculatedTexturesScale;
_transmittance_table_width *= static_cast<unsigned int>(_calculationTextureScale);
_transmittance_table_height *= static_cast<unsigned int>(_calculationTextureScale);
_irradiance_table_width *= static_cast<unsigned int>(_calculationTextureScale);
_irradiance_table_height *= static_cast<unsigned int>(_calculationTextureScale);
_delta_e_table_width *= static_cast<unsigned int>(_calculationTextureScale);
_delta_e_table_height *= static_cast<unsigned int>(_calculationTextureScale);
_r_samples *= static_cast<unsigned int>(_calculationTextureScale);
_mu_samples *= static_cast<unsigned int>(_calculationTextureScale);
_mu_s_samples *= static_cast<unsigned int>(_calculationTextureScale);
_nu_samples *= static_cast<unsigned int>(_calculationTextureScale);
//preCalculateAtmosphereParam();
}
void AtmosphereDeferredcaster::enablePrecalculationTexturesSaving() {
_saveCalculationTextures = true;
}
void AtmosphereDeferredcaster::loadComputationPrograms() {
RenderEngine& renderEngine = OsEng.renderEngine();
@@ -900,8 +943,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Stopped using a buffer object for GL_PIXEL_UNPACK_BUFFER
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, TRANSMITTANCE_TABLE_WIDTH,
TRANSMITTANCE_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _transmittance_table_width,
_transmittance_table_height, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
LERROR("Error creating Transmittance T texture for Atmosphere computation. OpenGL error: " << errString);
@@ -918,8 +961,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, IRRADIANCE_TABLE_WIDTH,
IRRADIANCE_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _irradiance_table_width,
_irradiance_table_height, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -938,8 +981,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F_ARB, MU_S_SAMPLES * NU_SAMPLES,
MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F_ARB, _mu_s_samples * _nu_samples,
_mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -958,8 +1001,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, DELTA_E_TABLE_WIDTH,
DELTA_E_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, _delta_e_table_width,
_delta_e_table_height, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -978,8 +1021,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, MU_S_SAMPLES * NU_SAMPLES,
MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples,
_mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -997,8 +1040,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, MU_S_SAMPLES * NU_SAMPLES,
MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples,
_mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1017,8 +1060,8 @@ void AtmosphereDeferredcaster::createComputationTextures() {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, MU_S_SAMPLES * NU_SAMPLES,
MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _mu_s_samples * _nu_samples,
_mu_samples, _r_samples, 0, GL_RGB, GL_FLOAT, nullptr);
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1058,7 +1101,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
ghoul::opengl::TextureUnit deltaJTableTextureUnit;
// Saving current OpenGL state
bool blendEnabled = glIsEnabled(GL_BLEND);
GLboolean blendEnabled = glIsEnabled(GL_BLEND);
GLint blendEquationRGB;
GLint blendEquationAlpha;
GLint blendDestAlpha;
@@ -1080,17 +1123,17 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// ===========================================================
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _transmittanceTableTexture, 0);
checkFrameBufferState("_transmittanceTableTexture");
glViewport(0, 0, TRANSMITTANCE_TABLE_WIDTH, TRANSMITTANCE_TABLE_HEIGHT);
glViewport(0, 0, _transmittance_table_width, _transmittance_table_height);
_transmittanceProgramObject->activate();
loadAtmosphereDataIntoShaderProgram(_transmittanceProgramObject);
//glClear(GL_COLOR_BUFFER_BIT);
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
renderQuadForCalc(quadCalcVAO, vertexSize);
#ifdef _SAVE_ATMOSPHERE_TEXTURES
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("transmittance_texture.ppm"),
TRANSMITTANCE_TABLE_WIDTH, TRANSMITTANCE_TABLE_HEIGHT);
#endif
renderQuadForCalc(quadCalcVAO, vertexSize);
if (_saveCalculationTextures) {
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("transmittance_texture.ppm"),
_transmittance_table_width, _transmittance_table_height);
}
_transmittanceProgramObject->deactivate();
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR) {
@@ -1101,7 +1144,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 2 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _deltaETableTexture, 0);
checkFrameBufferState("_deltaETableTexture");
glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
glViewport(0, 0, _delta_e_table_width, _delta_e_table_height);
_irradianceProgramObject->activate();
transmittanceTableTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture);
@@ -1109,10 +1152,10 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
loadAtmosphereDataIntoShaderProgram(_irradianceProgramObject);
glClear(GL_COLOR_BUFFER_BIT);
renderQuadForCalc(quadCalcVAO, vertexSize);
#ifdef _SAVE_ATMOSPHERE_TEXTURES
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("deltaE_table_texture.ppm"),
DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
#endif
if (_saveCalculationTextures) {
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("deltaE_table_texture.ppm"),
_delta_e_table_width, _delta_e_table_height);
}
_irradianceProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1125,23 +1168,23 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
GLenum colorBuffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, colorBuffers);
checkFrameBufferState("_deltaSRay and _deltaSMie TableTexture");
glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples);
_inScatteringProgramObject->activate();
transmittanceTableTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture);
_inScatteringProgramObject->setUniform("transmittanceTexture", transmittanceTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_inScatteringProgramObject);
glClear(GL_COLOR_BUFFER_BIT);
for (int layer = 0; layer < R_SAMPLES; ++layer) {
for (int layer = 0; layer < static_cast<int>(_r_samples); ++layer) {
step3DTexture(_inScatteringProgramObject, layer);
renderQuadForCalc(quadCalcVAO, vertexSize);
}
#ifdef _SAVE_ATMOSPHERE_TEXTURES
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("deltaS_rayleigh_texture.ppm"),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("deltaS_mie_texture.ppm"),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
#endif
if (_saveCalculationTextures) {
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("deltaS_rayleigh_texture.ppm"),
_mu_s_samples * _nu_samples, _mu_samples);
saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("deltaS_mie_texture.ppm"),
_mu_s_samples * _nu_samples, _mu_samples);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
glDrawBuffers(1, drawBuffers);
@@ -1156,7 +1199,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
checkFrameBufferState("_irradianceTableTexture");
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
glViewport(0, 0, _delta_e_table_width, _delta_e_table_height);
_deltaEProgramObject->activate();
//_deltaEProgramObject->setUniform("line", 4);
deltaETableTextureUnit.activate();
@@ -1165,10 +1208,10 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
loadAtmosphereDataIntoShaderProgram(_deltaEProgramObject);
glClear(GL_COLOR_BUFFER_BIT);
renderQuadForCalc(quadCalcVAO, vertexSize);
#ifdef _SAVE_ATMOSPHERE_TEXTURES
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("irradiance_texture.ppm"),
DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
#endif
if (_saveCalculationTextures) {
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("irradiance_texture.ppm"),
_delta_e_table_width, _delta_e_table_height);
}
_deltaEProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1178,7 +1221,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 5 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _inScatteringTableTexture, 0);
checkFrameBufferState("_inScatteringTableTexture");
glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples);
_deltaSProgramObject->activate();
deltaSRayleighTableTextureUnit.activate();
glBindTexture(GL_TEXTURE_3D, _deltaSRayleighTableTexture);
@@ -1188,14 +1231,14 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
_deltaSProgramObject->setUniform("deltaSMTexture", deltaSMieTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_deltaSProgramObject);
glClear(GL_COLOR_BUFFER_BIT);
for (int layer = 0; layer < R_SAMPLES; ++layer) {
for (int layer = 0; layer < static_cast<int>(_r_samples); ++layer) {
step3DTexture(_deltaSProgramObject, layer, false);
renderQuadForCalc(quadCalcVAO, vertexSize);
}
#ifdef _SAVE_ATMOSPHERE_TEXTURES
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("S_texture.ppm"),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
#endif
if (_saveCalculationTextures) {
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, std::string("S_texture.ppm"),
_mu_s_samples * _nu_samples, _mu_samples);
}
_deltaSProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1208,7 +1251,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 7 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _deltaJTableTexture, 0);
checkFrameBufferState("_deltaJTableTexture");
glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples);
_deltaJProgramObject->activate();
if (scatteringOrder == 2)
_deltaJProgramObject->setUniform("firstIteraction", 1);
@@ -1227,16 +1270,16 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
glBindTexture(GL_TEXTURE_3D, _deltaSMieTableTexture);
_deltaJProgramObject->setUniform("deltaSMTexture", deltaSMieTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_deltaJProgramObject);
for (int layer = 0; layer < R_SAMPLES; ++layer) {
for (int layer = 0; layer < static_cast<int>(_r_samples); ++layer) {
step3DTexture(_deltaJProgramObject, layer);
renderQuadForCalc(quadCalcVAO, vertexSize);
}
#ifdef _SAVE_ATMOSPHERE_TEXTURES
std::stringstream sst;
sst << "deltaJ_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
#endif
if (_saveCalculationTextures) {
sst << "deltaJ_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
_mu_s_samples * _nu_samples, _mu_samples);
}
_deltaJProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1246,7 +1289,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 8 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _deltaETableTexture, 0);
checkFrameBufferState("_deltaETableTexture");
glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
glViewport(0, 0, _delta_e_table_width, _delta_e_table_height);
_irradianceSupTermsProgramObject->activate();
if (scatteringOrder == 2)
_irradianceSupTermsProgramObject->setUniform("firstIteraction", (int)1);
@@ -1263,12 +1306,12 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
_irradianceSupTermsProgramObject->setUniform("deltaSMTexture", deltaSMieTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_irradianceSupTermsProgramObject);
renderQuadForCalc(quadCalcVAO, vertexSize);
#ifdef _SAVE_ATMOSPHERE_TEXTURES
sst.str(std::string());
sst << "deltaE_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
#endif
if (_saveCalculationTextures) {
sst.str(std::string());
sst << "deltaE_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
_delta_e_table_width, _delta_e_table_height);
}
_irradianceSupTermsProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1278,7 +1321,7 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 9 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _deltaSRayleighTableTexture, 0);
checkFrameBufferState("_deltaSRayleighTableTexture");
glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples);
_inScatteringSupTermsProgramObject->activate();
/*if (scatteringOrder == 2)
_inScatteringSupTermsProgramObject->setUniform("firstIteraction", (int)1);
@@ -1291,16 +1334,16 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
glBindTexture(GL_TEXTURE_3D, _deltaJTableTexture);
_inScatteringSupTermsProgramObject->setUniform("deltaJTexture", deltaJTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_inScatteringSupTermsProgramObject);
for (int layer = 0; layer < R_SAMPLES; ++layer) {
for (int layer = 0; layer < static_cast<int>(_r_samples); ++layer) {
step3DTexture(_inScatteringSupTermsProgramObject, layer);
renderQuadForCalc(quadCalcVAO, vertexSize);
}
#ifdef _SAVE_ATMOSPHERE_TEXTURES
sst.str(std::string());
sst << "deltaS_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
#endif
if (_saveCalculationTextures) {
sst.str(std::string());
sst << "deltaS_texture-scattering_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
_mu_s_samples * _nu_samples, _mu_samples);
}
_inScatteringSupTermsProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1314,19 +1357,19 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 10 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _irradianceTableTexture, 0);
checkFrameBufferState("_irradianceTableTexture");
glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
glViewport(0, 0, _delta_e_table_width, _delta_e_table_height);
_irradianceFinalProgramObject->activate();
deltaETableTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _deltaETableTexture);
_irradianceFinalProgramObject->setUniform("deltaETexture", deltaETableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_irradianceFinalProgramObject);
renderQuadForCalc(quadCalcVAO, vertexSize);
#ifdef _SAVE_ATMOSPHERE_TEXTURES
sst.str(std::string());
sst << "irradianceTable_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);
#endif
if (_saveCalculationTextures) {
sst.str(std::string());
sst << "irradianceTable_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
_delta_e_table_width, _delta_e_table_height);
}
_irradianceFinalProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1336,22 +1379,22 @@ void AtmosphereDeferredcaster::executeCalculations(const GLuint quadCalcVAO,
// line 11 in algorithm 4.1
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _inScatteringTableTexture, 0);
checkFrameBufferState("_inScatteringTableTexture");
glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
glViewport(0, 0, _mu_s_samples * _nu_samples, _mu_samples);
_deltaSSupTermsProgramObject->activate();
deltaSRayleighTableTextureUnit.activate();
glBindTexture(GL_TEXTURE_3D, _deltaSRayleighTableTexture);
_deltaSSupTermsProgramObject->setUniform("deltaSTexture", deltaSRayleighTableTextureUnit);
loadAtmosphereDataIntoShaderProgram(_deltaSSupTermsProgramObject);
for (int layer = 0; layer < R_SAMPLES; ++layer) {
for (int layer = 0; layer < static_cast<int>(_r_samples); ++layer) {
step3DTexture(_deltaSSupTermsProgramObject, layer, false);
renderQuadForCalc(quadCalcVAO, vertexSize);
}
#ifdef _SAVE_ATMOSPHERE_TEXTURES
sst.str(std::string());
sst << "inscatteringTable_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);
#endif
if (_saveCalculationTextures) {
sst.str(std::string());
sst << "inscatteringTable_order-" << scatteringOrder << ".ppm";
saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, sst.str(),
_mu_s_samples * _nu_samples, _mu_samples);
}
_deltaSSupTermsProgramObject->deactivate();
while ((err = glGetError()) != GL_NO_ERROR) {
const GLubyte * errString = gluErrorString(err);
@@ -1499,6 +1542,16 @@ void AtmosphereDeferredcaster::loadAtmosphereDataIntoShaderProgram(std::unique_p
shaderProg->setUniform("betaMieExtinction", _mieExtinctionCoeff);
shaderProg->setUniform("mieG", _miePhaseConstant);
shaderProg->setUniform("sunRadiance", _sunRadianceIntensity);
shaderProg->setUniform("TRANSMITTANCE_W", (int)_transmittance_table_width);
shaderProg->setUniform("TRANSMITTANCE_H", (int)_transmittance_table_height);
shaderProg->setUniform("SKY_W", (int)_irradiance_table_width);
shaderProg->setUniform("SKY_H", (int)_irradiance_table_height);
shaderProg->setUniform("OTHER_TEXTURES_W", (int)_delta_e_table_width);
shaderProg->setUniform("OTHER_TEXTURES_H", (int)_delta_e_table_height);
shaderProg->setUniform("SAMPLES_R", (int)_r_samples);
shaderProg->setUniform("SAMPLES_MU", (int)_mu_samples);
shaderProg->setUniform("SAMPLES_MU_S", (int)_mu_s_samples);
shaderProg->setUniform("SAMPLES_NU", (int)_nu_samples);
}
void AtmosphereDeferredcaster::checkFrameBufferState(const std::string & codePosition) const {
@@ -1529,10 +1582,10 @@ void AtmosphereDeferredcaster::checkFrameBufferState(const std::string & codePos
violates an implementation - dependent set of restrictions.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
LERROR("Returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all \
LERROR("Returned if the value of GL_RENDERBUFFE_r_samples is not the same for all \
attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all \
attached textures; or , if the attached images are a mix of renderbuffers and textures, \
the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.");
the value of GL_RENDERBUFFE_r_samples does not match the value of GL_TEXTURE_SAMPLES.");
LERROR("Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same \
for all attached textures; or , if the attached images are a mix of renderbuffers and \
textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.");
@@ -1564,9 +1617,9 @@ void AtmosphereDeferredcaster::step3DTexture(std::unique_ptr<ghoul::opengl::Prog
float earth2 = _atmospherePlanetRadius * _atmospherePlanetRadius;
float atm2 = _atmosphereRadius * _atmosphereRadius;
float diff = atm2 - earth2;
float ri = static_cast<float>(layer) / static_cast<float>(R_SAMPLES - 1);
float ri = static_cast<float>(layer) / static_cast<float>(_r_samples - 1);
float ri_2 = ri * ri;
float epsilon = (layer == 0) ? 0.01f : (layer == (R_SAMPLES - 1)) ? -0.001f : 0.0f;
float epsilon = (layer == 0) ? 0.01f : (layer == (static_cast<int>(_r_samples) - 1)) ? -0.001f : 0.0f;
float r = sqrtf(earth2 + ri_2 * diff) + epsilon;
float dminG = r - _atmospherePlanetRadius;
float dminT = _atmosphereRadius - r;
@@ -58,7 +58,7 @@ public:
// 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_WIDTH = 256;
const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 64;
const unsigned int IRRADIANCE_TABLE_WIDTH = 64;
@@ -66,22 +66,11 @@ public:
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 NU_SAMPLES = 8;*/
public:
AtmosphereDeferredcaster();
@@ -117,6 +106,9 @@ public:
void setEllipsoidRadii(const glm::dvec3 & radii);
void setRenderableClass(const AtmosphereDeferredcaster::AtmospherRenderableClass rc);
void setPrecalculationTextureScale(const float _preCalculatedTexturesScale);
void enablePrecalculationTexturesSaving();
private:
void loadComputationPrograms();
void unloadComputationPrograms();
@@ -187,10 +179,27 @@ private:
GLuint _atmosphereRenderVAO;
GLuint _atmosphereRenderVBO;
// Atmosphere Textures Dimmensions
unsigned int _transmittance_table_width;
unsigned int _transmittance_table_height;
unsigned int _irradiance_table_width;
unsigned int _irradiance_table_height;
unsigned int _delta_e_table_width;
unsigned int _delta_e_table_height;
unsigned int _r_samples;
unsigned int _mu_samples;
unsigned int _mu_s_samples;
unsigned int _nu_samples;
glm::dmat4 _modelTransform;
float _stepSize;
double _time;
// Atmosphere Debugging
float _calculationTextureScale;
bool _saveCalculationTextures;
AtmospherRenderableClass _renderableClass;
};
@@ -60,6 +60,7 @@ namespace {
const std::string keyFrame = "Frame";
const std::string keyGeometry = "Geometry";
const std::string keyDebug = "Debug";
const std::string keyRadius = "Radius";
const std::string keyShading = "PerformShading";
const std::string keyShadowGroup = "Shadow_Group";
@@ -75,6 +76,8 @@ namespace {
const std::string keyMieHeightScale = "H_M";
const std::string keyMiePhaseConstant = "G";
const std::string keyBody = "Body";
const std::string keyTextureScale = "PreCalculatedTextureScale";
const std::string keySaveTextures = "SaveCalculatedTextures";
}
namespace openspace {
@@ -122,6 +125,8 @@ namespace openspace {
, _mieAsymmetricFactorGP("mieAsymmetricFactorG", "Mie Asymmetric Factor G", 0.85f, -1.0f, 1.0f)
, _sunIntensityP("sunIntensity", "Sun Intensity", 50.0f, 0.1f, 1000.0f)
, _hdrExpositionP("hdrExposition", "HDR", 0.4f, 0.01f, 5.0f)
, _saveCalculationsToTexture(false)
, _preCalculatedTexturesScale(1.0)
{
std::string name;
bool success = dictionary.getValue(SceneGraphNode::KeyName, name);
@@ -390,6 +395,19 @@ namespace openspace {
<< name << " planet.\nDisabling atmosphere effects for this planet.");
}
ghoul::Dictionary debugDictionary;
success = atmosphereDictionary.getValue(keyDebug, debugDictionary);
if (success) {
if (debugDictionary.getValue(keyTextureScale, _preCalculatedTexturesScale)) {
LDEBUG("Atmosphere Texture Scaled to " << _preCalculatedTexturesScale);
}
if (debugDictionary.getValue(keySaveTextures, _saveCalculationsToTexture)) {
LDEBUG("Saving Precalculated Atmosphere Textures.");
}
}
if (!errorReadingAtmosphereData) {
_atmosphereEnabled = true;
@@ -547,6 +565,10 @@ namespace openspace {
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
_deferredcaster->setRenderableClass(AtmosphereDeferredcaster::RenderablePlanet);
_deferredcaster->setPrecalculationTextureScale(_preCalculatedTexturesScale);
if (_saveCalculationsToTexture)
_deferredcaster->enablePrecalculationTexturesSaving();
_deferredcaster->initialize();
}
@@ -152,6 +152,10 @@ namespace openspace {
glm::vec3 _rayleighScatteringCoeff;
glm::vec3 _mieScatteringCoeff;
// Atmosphere Debug
bool _saveCalculationsToTexture;
float _preCalculatedTexturesScale;
// Testing Deferredcast
std::unique_ptr<AtmosphereDeferredcaster> _deferredcaster;
@@ -34,6 +34,18 @@ uniform vec3 betaMieExtinction;
uniform float mieG;
uniform float sunRadiance;
uniform int TRANSMITTANCE_W;
uniform int TRANSMITTANCE_H;
uniform int SKY_W;
uniform int SKY_H;
uniform int OTHER_TEXTURES_W;
uniform int OTHER_TEXTURES_H;
uniform int SAMPLES_R;
uniform int SAMPLES_MU;
uniform int SAMPLES_MU_S;
uniform int SAMPLES_NU;
const float ATM_EPSILON = 1.0;
// Integration steps
@@ -44,30 +56,17 @@ const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
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 TRANSMITTANCE_W = 512;
// const int TRANSMITTANCE_H = 128;
// const int SKY_W = 128;
// const int SKY_H = 32;
// const int OTHER_TEXTURES_W = 128;
// const int OTHER_TEXTURES_H = 32;
// cosines sampling
const int SAMPLES_R = 32;
const int SAMPLES_MU = 128;
const int SAMPLES_MU_S = 32;
const int SAMPLES_NU = 8;
// 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;
// // cosines sampling
// const int SAMPLES_R = 32;
// const int SAMPLES_MU = 128;
// const int SAMPLES_MU_S = 32;
// const int SAMPLES_NU = 8;
uniform sampler2D transmittanceTexture;
@@ -415,7 +415,7 @@ vec3 inscatterNoTestRadiance(inout vec3 x, inout float t, const vec3 v, const ve
// The "infinite" ray hist something inside the atmosphere, so we need to remove
// the unsused contribution to the final radiance.
inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muSun0, nu), 0.0);
// cos(PI-thetaH) = dist/r
// cos(thetaH) = - dist/r
// muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2)
@@ -44,6 +44,9 @@ namespace {
const char* keySegmentsPerPatch = "SegmentsPerPatch";
const char* keyLayers = "Layers";
#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED
const std::string keyATMDebug = "Debug";
const std::string keyTextureScale = "PreCalculatedTextureScale";
const std::string keySaveTextures = "SaveCalculatedTextures";
const std::string keyAtmosphere = "Atmosphere";
const std::string keyAtmosphereRadius = "AtmoshereRadius";
const std::string keyPlanetRadius = "PlanetRadius";
@@ -117,6 +120,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
, _sunRadianceIntensity(50.0f)
, _hdrConstant(0.4f)
, _atmosphereEnabled(false)
, _saveCalculationsToTexture(false)
, _preCalculatedTexturesScale(1.0)
#endif
{
setName("RenderableGlobe");
@@ -273,6 +278,19 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
// << name << " planet.\nDisabling atmosphere effects for this planet.");
}
ghoul::Dictionary debugATMDictionary;
success = atmosphereDictionary.getValue(keyATMDebug, debugATMDictionary);
if (success) {
if (debugATMDictionary.getValue(keyTextureScale, _preCalculatedTexturesScale)) {
//LDEBUG("Atmosphere Texture Scaled to " << _preCalculatedTexturesScale);
}
if (debugATMDictionary.getValue(keySaveTextures, _saveCalculationsToTexture)) {
//LDEBUG("Saving Precalculated Atmosphere Textures.");
}
}
if (!errorReadingAtmosphereData) {
_atmosphereEnabled = true;
@@ -352,6 +370,11 @@ bool RenderableGlobe::initialize() {
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
_deferredcaster->setEllipsoidRadii(_ellipsoid.radii());
_deferredcaster->setRenderableClass(AtmosphereDeferredcaster::RenderableGlobe);
_deferredcaster->setPrecalculationTextureScale(_preCalculatedTexturesScale);
if (_saveCalculationsToTexture)
_deferredcaster->enablePrecalculationTexturesSaving();
_deferredcaster->initialize();
}
@@ -165,6 +165,10 @@ private:
glm::vec3 _rayleighScatteringCoeff;
glm::vec3 _mieScatteringCoeff;
// Atmosphere Debug
bool _saveCalculationsToTexture;
float _preCalculatedTexturesScale;
AtmosphereProperties _atmosphereProperties;
properties::PropertyOwner _atmospherePropertyOwner;