Skip to content

Instantly share code, notes, and snippets.

@silvesthu
Created July 11, 2021 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silvesthu/0338b703a155c4bf61487fc0074cabf6 to your computer and use it in GitHub Desktop.
Save silvesthu/0338b703a155c4bf61487fc0074cabf6 to your computer and use it in GitHub Desktop.
Generate code to apply multiple iteration in one pass for ShaderToy
#include <iostream>
#include <vector>
struct Sample
{
int x = 0;
int y = 0;
unsigned __int64 count = 0;
};
struct Template
{
std::vector<Sample> pressure_samples;
std::vector<Sample> divergence_samples;
};
int main()
{
std::vector<Template> templates;
templates.push_back(Template());
templates[0].pressure_samples =
{
Sample { -1, +0, 1 },
Sample { +1, +0, 1 },
Sample { +0, -1, 1 },
Sample { +0, +1, 1 }
};
templates[0].divergence_samples =
{
Sample { +0, +0, 1 }
};
auto get_samples = [&](int x, int y, std::vector<Sample>& template_samples)
{
std::vector<Sample> samples = template_samples;
for (auto& sample : samples)
{
sample.x += x;
sample.y += y;
}
return std::move(samples);
};
auto merge_sampels = [](std::vector<Sample>& target, std::vector<Sample>&& source)
{
std::vector<Sample> adds;
for (auto& sample : source)
{
auto it = std::find_if(target.begin(), target.end(), [&](Sample& s)
{
return sample.x == s.x && sample.y == s.y;
});
if (it != target.end())
it->count += sample.count;
else
adds.push_back(sample);
}
target.insert(target.end(), adds.begin(), adds.end());
};
int iteration_to_generate = 20;
for (int iteration = 1; iteration <= iteration_to_generate; iteration++)
{
templates.push_back(Template());
std::vector<Sample>& pressure_samples = templates[iteration].pressure_samples;
std::vector<Sample>& previous_pressure_samples = templates[iteration - 1].pressure_samples;
merge_sampels(pressure_samples, get_samples(-1, +0, previous_pressure_samples));
merge_sampels(pressure_samples, get_samples(+1, +0, previous_pressure_samples));
merge_sampels(pressure_samples, get_samples(+0, -1, previous_pressure_samples));
merge_sampels(pressure_samples, get_samples(+0, +1, previous_pressure_samples));
std::vector<Sample>& divergence_samples = templates[iteration].divergence_samples;
std::vector<Sample>& previous_divergence_samples = templates[iteration - 1].divergence_samples;
merge_sampels(divergence_samples, get_samples(-1, +0, previous_divergence_samples));
merge_sampels(divergence_samples, get_samples(+1, +0, previous_divergence_samples));
merge_sampels(divergence_samples, get_samples(+0, -1, previous_divergence_samples));
merge_sampels(divergence_samples, get_samples(+0, +1, previous_divergence_samples));
std::vector<Sample> divergence_sample = { Sample{0, 0, 1ull << (iteration * 2)} };
merge_sampels(divergence_samples, get_samples(+0, +0, divergence_sample));
}
unsigned __int64 pressure_count = 0;
for (auto&& sample : templates[iteration_to_generate - 1].pressure_samples)
{
pressure_count += sample.count;
std::cout << " pressure += texture(Pressure, (fragCoord + vec2(" << sample.x << ", " << sample.y << ")) / iResolution.xy).x * " << sample.count << ".0;\n";
}
unsigned __int64 divergence_count = 0;
for (auto&& sample : templates[iteration_to_generate - 1].divergence_samples)
{
divergence_count += sample.count;
std::cout << " divergence += texture(Divergence, (fragCoord + vec2(" << sample.x << ", " << sample.y << ")) / iResolution.xy).x * " << sample.count << ".0;\n";
}
std::cout << "Pressure count = " << pressure_count << ", Divergence count = " << divergence_count << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment