Skip to content

Commit

Permalink
add FLOOD loop and jump flood shader
Browse files Browse the repository at this point in the history
  • Loading branch information
patriciogonzalezvivo committed Oct 16, 2023
1 parent f1f13b0 commit 1525f06
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 22 deletions.
147 changes: 139 additions & 8 deletions src/core/sandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Sandbox::Sandbox():
m_buffers_total(0),
m_doubleBuffers_total(0),
m_pyramid_total(0),
m_flood_total(0),
// PostProcessing
m_postprocessing(false),
// Plot helpers
Expand Down Expand Up @@ -1333,6 +1334,7 @@ void Sandbox::resetShaders( WatchFileList &_files ) {
m_buffers_total = countBuffers(m_frag_source);
m_doubleBuffers_total = countDoubleBuffers(m_frag_source);
m_pyramid_total = countPyramid( m_frag_source );
m_flood_total = countFlood( m_frag_source );

// UPDATE Postprocessing
bool havePostprocessing = checkPostprocessing( getSource(FRAGMENT) );
Expand Down Expand Up @@ -1432,11 +1434,11 @@ void Sandbox::_updateBuffers() {
for (size_t i = 0; i < m_doubleBuffers_shaders.size(); i++)
m_doubleBuffers_shaders[i].setSource(m_frag_source, vera::getDefaultSrc(vera::VERT_BILLBOARD));

// Update Convolution Pyramids
// Update PYRAMID buffers
if ( m_pyramid_total != int(uniforms.pyramids.size()) ) {

if (verbose)
std::cout << "Removing " << uniforms.pyramids.size() << " convolution pyramids to create " << m_pyramid_total << std::endl;
std::cout << "Removing " << uniforms.pyramids.size() << " pyramids to create " << m_pyramid_total << std::endl;

for (size_t i = 0; i < m_pyramid_subshaders.size(); i++)
if (m_pyramid_subshaders[i].isLoaded())
Expand All @@ -1458,7 +1460,7 @@ void Sandbox::_updateBuffers() {
uniforms.pyramids[i].scale = size.z;

// Create pass function for this pyramid
uniforms.pyramids[i].pass = [this](vera::Fbo *_target, const vera::Fbo *_tex0, const vera::Fbo *_tex1, int _depth) {
uniforms.pyramids[i].pass = [&](vera::Fbo *_target, const vera::Fbo *_tex0, const vera::Fbo *_tex1, int _depth) {
_target->bind();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
Expand All @@ -1467,7 +1469,7 @@ void Sandbox::_updateBuffers() {
uniforms.feedTo( &m_pyramid_shader );

m_pyramid_shader.setUniform("u_pyramidDepth", _depth);
m_pyramid_shader.setUniform("u_pyramidTotalDepth", (int)uniforms.pyramids[0].getDepth());
m_pyramid_shader.setUniform("u_pyramidTotalDepth", (int)uniforms.pyramids[i].getDepth());
m_pyramid_shader.setUniform("u_pyramidUpscaling", _tex1 != NULL);

m_pyramid_shader.textureIndex = (uniforms.models.size() == 0) ? 1 : 0;
Expand All @@ -1488,20 +1490,82 @@ void Sandbox::_updateBuffers() {
}
}

// Update PYRAMID algo
if (m_pyramid_total > 0 ) {
if ( checkPyramidAlgorithm( getSource(FRAGMENT) ) ) {
m_pyramid_shader.addDefine("PYRAMID_ALGORITHM");
m_pyramid_shader.setSource(m_frag_source, vera::getDefaultSrc(vera::VERT_BILLBOARD));
}
else
m_pyramid_shader.setSource(vera::getDefaultSrc(vera::FRAG_POISSON), vera::getDefaultSrc(vera::VERT_BILLBOARD));
m_pyramid_shader.setSource(vera::getDefaultSrc(vera::FRAG_POISSONFILL), vera::getDefaultSrc(vera::VERT_BILLBOARD));
}

// Update PYRAMID subshaders
for (size_t i = 0; i < m_pyramid_subshaders.size(); i++) {
m_pyramid_subshaders[i].addDefine("PYRAMID_" + vera::toString(i));
m_pyramid_subshaders[i].setSource(m_frag_source, vera::getDefaultSrc(vera::VERT_BILLBOARD));
}

// Update FLOOD Buffers
if ( m_flood_total != int(uniforms.floods.size()) ) {

if (verbose)
std::cout << "Removing " << uniforms.floods.size() << " flood to create " << m_flood_total << std::endl;

for (size_t i = 0; i < m_flood_subshaders.size(); i++)
if (m_flood_subshaders[i].isLoaded())
m_flood_subshaders[i].detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);

uniforms.floods.clear();
m_flood_subshaders.clear();

for (int i = 0; i < m_flood_total; i++) {
glm::vec3 size = getBufferSize(m_frag_source, "u_flood" + vera::toString(i));

// Create Subshader
m_flood_subshaders.push_back( vera::Shader() );

// Create Pyramid structure
uniforms.floods.push_back( vera::Flood() );
uniforms.floods[i].allocate(size.x, size.y, vera::COLOR_FLOAT_TEXTURE);
uniforms.floods[i].scale = size.z;

// Create pass function for this flood
uniforms.floods[i].pass = [&](vera::Fbo *_dst, const vera::Fbo *_src, int _index) {
_dst->bind();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_flood_shader.use();

// uniforms.feedTo( &m_flood_shader, false, false );

m_flood_shader.setUniform("u_resolution", ((float)_dst->getWidth()), ((float)_dst->getHeight()));
m_flood_shader.setUniform("u_floodIndex",_index);
m_flood_shader.setUniform("u_floodTotal", (int)uniforms.floods[0].getTotalIterations());

m_flood_shader.textureIndex = (uniforms.models.size() == 0) ? 1 : 0;
m_flood_shader.setUniformTexture("u_floodSrc", _src);

vera::getBillboard()->render( &m_flood_shader );
_dst->unbind();
};
}
}

if (m_flood_total > 0 ) {
if ( checkFloodAlgorithm( getSource(FRAGMENT) ) ) {
m_flood_shader.addDefine("FLOOD_ALGORITHM");
m_flood_shader.setSource(m_frag_source, vera::getDefaultSrc(vera::VERT_BILLBOARD));
}
else
m_flood_shader.setSource(vera::getDefaultSrc(vera::FRAG_JUMPFLOOD), vera::getDefaultSrc(vera::VERT_BILLBOARD));
}

for (size_t i = 0; i < m_flood_subshaders.size(); i++) {
m_flood_subshaders[i].addDefine("FLOOD_" + vera::toString(i));
m_flood_subshaders[i].setSource(m_frag_source, vera::getDefaultSrc(vera::VERT_BILLBOARD));
}

// Update Postprocessing
if (m_postprocessing || m_plot == PLOT_RGB || m_plot == PLOT_RED || m_plot == PLOT_GREEN || m_plot == PLOT_BLUE || m_plot == PLOT_LUMA) {
if (quilt >= 0)
Expand Down Expand Up @@ -1541,6 +1605,9 @@ void Sandbox::_renderBuffers() {
for (size_t j = 0; j < uniforms.doubleBuffers.size(); j++)
m_buffers_shaders[i].setUniformTexture("u_doubleBuffer" + vera::toString(j), uniforms.doubleBuffers[j]->src );

for (size_t j = 0; j < uniforms.floods.size(); j++)
m_buffers_shaders[i].setUniformTexture("u_flood" + vera::toString(j), uniforms.floods[j].dst );

for (size_t j = 0; j < m_sceneRender.buffersFbo.size(); j++)
m_buffers_shaders[i].setUniformTexture("u_sceneBuffer" + vera::toString(j), m_sceneRender.buffersFbo[j] );

Expand Down Expand Up @@ -1570,6 +1637,9 @@ void Sandbox::_renderBuffers() {
for (size_t j = 0; j < uniforms.doubleBuffers.size(); j++)
m_doubleBuffers_shaders[i].setUniformTexture("u_doubleBuffer" + vera::toString(j), uniforms.doubleBuffers[j]->src );

for (size_t j = 0; j < uniforms.floods.size(); j++)
m_doubleBuffers_shaders[i].setUniformTexture("u_flood" + vera::toString(j), uniforms.floods[j].dst );

for (size_t j = 0; j < m_sceneRender.buffersFbo.size(); j++)
m_doubleBuffers_shaders[i].setUniformTexture("u_sceneBuffer" + vera::toString(j), m_sceneRender.buffersFbo[j] );

Expand All @@ -1585,7 +1655,7 @@ void Sandbox::_renderBuffers() {
}

for (size_t i = 0; i < m_pyramid_subshaders.size(); i++) {
TRACK_BEGIN("render:convolution_pyramid" + vera::toString(i))
TRACK_BEGIN("render:pyramid" + vera::toString(i))

reset_viewport += m_pyramid_fbos[i].scale <= 0.0;

Expand All @@ -1611,7 +1681,46 @@ void Sandbox::_renderBuffers() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
uniforms.pyramids[i].process(&m_pyramid_fbos[i]);

TRACK_END("render:convolution_pyramid" + vera::toString(i))
TRACK_END("render:pyramid" + vera::toString(i))
}

for (size_t i = 0; i < m_flood_subshaders.size(); i++) {
TRACK_BEGIN("render:flood" + vera::toString(i))

reset_viewport += uniforms.floods[i].scale <= 0.0;

uniforms.floods[i].dst->bind();
m_flood_subshaders[i].use();

// Clear the background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for (size_t j = 0; j < uniforms.buffers.size(); j++)
m_flood_subshaders[i].setUniformTexture("u_buffer" + vera::toString(j), uniforms.buffers[j] );

for (size_t j = 0; j < uniforms.doubleBuffers.size(); j++)
m_flood_subshaders[i].setUniformTexture("u_doubleBuffer" + vera::toString(j), uniforms.doubleBuffers[j]->src );

for (size_t j = 0; j < uniforms.floods.size(); j++)
m_flood_subshaders[i].setUniformTexture("u_flood" + vera::toString(j), uniforms.floods[j].src );

for (size_t j = 0; j < m_sceneRender.buffersFbo.size(); j++)
if (m_sceneRender.buffersFbo[j]->isAllocated())
m_flood_subshaders[i].setUniformTexture("u_sceneBuffer" + vera::toString(j), m_sceneRender.buffersFbo[j] );

// Update uniforms and textures
uniforms.feedTo( &m_flood_subshaders[i], true, false );

vera::getBillboard()->render( &m_flood_subshaders[i] );

uniforms.floods[i].dst->unbind();

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
uniforms.floods[i].process();

TRACK_END("render:flood" + vera::toString(i))
}

#if defined(__EMSCRIPTEN__)
Expand Down Expand Up @@ -1653,7 +1762,8 @@ void Sandbox::renderPrep() {

if (uniforms.buffers.size() > 0 ||
uniforms.doubleBuffers.size() > 0 ||
m_pyramid_total > 0)
m_pyramid_total > 0 ||
m_flood_total > 0)
_renderBuffers();

// RENDER SHADOW MAP
Expand Down Expand Up @@ -1886,6 +1996,7 @@ void Sandbox::renderUI() {
int nTotal = uniforms.buffers.size();
nTotal += uniforms.doubleBuffers.size();
nTotal += uniforms.pyramids.size();
nTotal += uniforms.floods.size();
if (m_postprocessing && uniforms.models.size() > 0 ) {
nTotal += 1;
nTotal += uniforms.functions["u_scene"].present;
Expand Down Expand Up @@ -1964,6 +2075,18 @@ void Sandbox::renderUI() {

}

for (size_t i = 0; i < uniforms.floods.size(); i++) {
glm::vec2 offset = glm::vec2(xOffset, yOffset);
glm::vec2 scale = glm::vec2(yStep);
scale.x *= ((float)uniforms.floods[i].dst->getWidth()/(float)uniforms.floods[i].dst->getHeight());
offset.x += xStep - scale.x;

vera::image(uniforms.floods[i].dst, offset.x, offset.y, scale.x, scale.y);
vera::text("u_flood" + vera::toString(i), xOffset - scale.x, vera::getWindowHeight() - yOffset - yStep);

yOffset -= yStep * 2.0;
}

if (uniforms.models.size() > 0) {
vera::fill(0.0);
for (vera::LightsMap::iterator it = uniforms.lights.begin(); it != uniforms.lights.end(); ++it ) {
Expand Down Expand Up @@ -2363,6 +2486,14 @@ void Sandbox::onViewportResize(int _newWidth, int _newHeight) {
}
}

for (size_t i = 0; i < uniforms.floods.size(); i++) {
if (uniforms.floods[i].scale > 0.0) {
uniforms.floods[i].allocate( _newWidth * uniforms.floods[i].scale,
_newHeight * uniforms.floods[i].scale,
vera::COLOR_FLOAT_TEXTURE);
}
}

if (m_postprocessing || m_plot == PLOT_LUMA || m_plot == PLOT_RGB || m_plot == PLOT_RED || m_plot == PLOT_GREEN || m_plot == PLOT_BLUE ) {
if (quilt >= 0)
m_sceneRender.updateBuffers(uniforms, vera::getQuiltWidth(), vera::getQuiltHeight());
Expand Down
19 changes: 12 additions & 7 deletions src/core/sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,27 @@ class Sandbox {
ShaderList m_buffers_shaders;
int m_buffers_total;

// Buffers
// Double Buffers
ShaderList m_doubleBuffers_shaders;
int m_doubleBuffers_total;

// Pyramids
FboList m_pyramid_fbos;
ShaderList m_pyramid_subshaders;
vera::Shader m_pyramid_shader;
int m_pyramid_total;

// Floods
ShaderList m_flood_subshaders;
vera::Shader m_flood_shader;
int m_flood_total;

// A. CANVAS
vera::Shader m_canvas_shader;

// B. SCENE
SceneRender m_sceneRender;

// Pyramid Convolution
FboList m_pyramid_fbos;
ShaderList m_pyramid_subshaders;
vera::Shader m_pyramid_shader;
int m_pyramid_total;

// Postprocessing
vera::Shader m_postprocessing_shader;
bool m_postprocessing;
Expand Down
24 changes: 20 additions & 4 deletions src/core/tools/text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,22 @@ using regex_stringdata_t = const char * const;
template<typename T1>
using regex_string_t = std::tuple<T1, regex_stringdata_t>;

// Single check keywords
enum class regex_check_t {
Pyramid_Algorithm,
Flood_Algorithm,
Floor,
Background,
Post_Processing,
MAX_KEYWORDS_CHECK_IDS
};
using regex_check_string_t = regex_string_t<regex_check_t>;
const auto valid_check_keyword_ids = std::array<regex_check_string_t, +(regex_check_t::MAX_KEYWORDS_CHECK_IDS)> {{
{regex_check_t::Pyramid_Algorithm, "PYRAMID_ALGORITHM"}
, {regex_check_t::Floor,"FLOOR"}
, {regex_check_t::Background, "BACKGROUND"}
, {regex_check_t::Post_Processing, "POSTPROCESSING"}
{regex_check_t::Pyramid_Algorithm, "PYRAMID_ALGORITHM"},
{regex_check_t::Flood_Algorithm, "FLOOD_ALGORITHM"},
{regex_check_t::Floor,"FLOOR"},
{regex_check_t::Background, "BACKGROUND"},
{regex_check_t::Post_Processing, "POSTPROCESSING"},
}};

bool generic_search_check(const std::string& _source, regex_check_t keyword_id ) {
Expand All @@ -72,10 +75,12 @@ bool generic_search_check(const std::string& _source, regex_check_t keyword_id )
return std::get<0>(does_any_of_the_regex_exist(_source, re)); //return only the "result" boolean.
}

// Multiple count keywords
enum class regex_count_t {
Buffers,
Double_Buffers,
Pyramid,
Flood,
Scene_Buffers,
MAX_KEYWORDS_COUNT_IDS
};
Expand All @@ -84,6 +89,7 @@ const auto valid_count_keyword_ids = std::array<regex_count_string_t, +(regex_co
{regex_count_t::Buffers, "BUFFER"},
{regex_count_t::Double_Buffers, "DOUBLE_BUFFER"},
{regex_count_t::Pyramid, "PYRAMID"},
{regex_count_t::Flood, "FLOOD"},
{regex_count_t::Scene_Buffers, "SCENE_BUFFER"}
}};

Expand Down Expand Up @@ -201,6 +207,16 @@ bool checkPyramidAlgorithm(const std::string& _source) {
return generic_search_check(_source, regex_check_t::Pyramid_Algorithm);
}

// Count how many PYRAMID_ are in the shader
int countFlood(const std::string& _source) {
return generic_search_count(_source, regex_count_t::Flood);
}

bool checkFloodAlgorithm(const std::string& _source) {
return generic_search_check(_source, regex_check_t::Flood_Algorithm);
}


int countSceneBuffers(const std::string& _source) {
return generic_search_count(_source, regex_count_t::Scene_Buffers);
}
Expand Down
5 changes: 4 additions & 1 deletion src/core/tools/text.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ glm::vec3 getBufferSize(const std::string& _source, const std::string& _name);

int countBuffers(const std::string& _source);
int countDoubleBuffers(const std::string& _source);
int countPyramid(const std::string& _source);

int countPyramid(const std::string& _source);
bool checkPyramidAlgorithm(const std::string& _source);

int countFlood(const std::string& _source);
bool checkFloodAlgorithm(const std::string& _source);

bool checkFloor(const std::string& _source);
bool checkBackground(const std::string& _source);
bool checkPostprocessing(const std::string& _source);
Expand Down
4 changes: 4 additions & 0 deletions src/core/uniforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,15 @@ bool Uniforms::feedTo(vera::Shader *_shader, bool _lights, bool _buffers ) {

for (size_t i = 0; i < doubleBuffers.size(); i++)
_shader->setUniformTexture("u_doubleBuffer" + vera::toString(i), doubleBuffers[i]->src, _shader->textureIndex++ );

for (size_t i = 0; i < floods.size(); i++)
_shader->setUniformTexture("u_flood" + vera::toString(i), floods[i].dst, _shader->textureIndex++ );
}

// Pass Convolution Piramids resultant Texture
for (size_t i = 0; i < pyramids.size(); i++)
_shader->setUniformTexture("u_pyramid" + vera::toString(i), pyramids[i].getResult(), _shader->textureIndex++ );


if (_lights) {
// Pass Light Uniforms
Expand Down
Loading

0 comments on commit 1525f06

Please sign in to comment.