Skip to content

Instantly share code, notes, and snippets.

@cjameshuff
Last active December 21, 2015 04:59
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 cjameshuff/6253837 to your computer and use it in GitHub Desktop.
Save cjameshuff/6253837 to your computer and use it in GitHub Desktop.
struct VolumeVal {
uint16_t type;
float field;
};
using fieldfn_t = std::function<float(const vec3 &)>;
using volfn_t = std::function<VolumeVal(const vec3 &)>;
// Result is a function giving one of three possible results:
// the result of fnb (preexisting layers)
// {type, fna(pt)} (new layer)
// {kAirVolume, 1.0f}
template<typename fna_t>
auto layer(uint16_t type, const fna_t & fna, const volfn_t & fnb) -> volfn_t
{
return [=](const vec3 & pt){
auto f = fnb(pt);
if(f.field <= 0.0f)
return f;
auto f2 = fna(pt);
return (f2 <= 0.0f)? VolumeVal{type, f2} : VolumeVal{kAirVolume, 1.0f};
};
}
template<typename fn_t>
auto turbulate(const vec3 & scl, const vec3 & amp, const fn_t & fn) -> volfn_t
{
return [=](const vec3 & pt){
vec3 turbPtX = pt/scl + vec3{0, 0, 1000};
vec3 turbPtY = turbPtX + vec3{1000, 0, 0};
vec3 turbPtZ = turbPtX + vec3{0, 1000, 0};
return fn(pt + vec3{glm::simplex(turbPtX), glm::simplex(turbPtY), glm::simplex(turbPtZ)}*amp);
};
}
auto plane(float y, float yscl) -> fieldfn_t {
return [=](const vec3 & pt){return (pt.y - y)/yscl;};
}
int main(int argc, const char * argv[])
{
uint32_t colors[] = {
0x00FFFFFF,
0x00880000,
0x00008800,
0x00000088
};
volfn_t volfn = [](const vec3 &){return VolumeVal{kAirVolume, 1.0f};};
volfn = layer(1, plane(0.0f, 100.0f), volfn);
volfn = turbulate(vec3{100.0f}, vec3{10.0f}, volfn);
volfn = layer(2, plane(32.0f, 100.0f), volfn);
volfn = turbulate(vec3{100.0f}, vec3{10.0f}, volfn);
volfn = layer(3, plane(40.0f, 100.0f), volfn);
volfn = turbulate(vec3{100.0f}, vec3{10.0f}, volfn);
SimpleImage output(1024, 512, 3);
for(int ix = 0; ix < output.width; ++ix)
for(int iy = 0; iy < output.height; ++iy)
{
float x = ix, y = iy - output.height/2.0f;
VolumeVal val = volfn(vec3{x, y, 0.5f});
output.SetPixelRGB(ix, iy, colors[val.type]);
}
TargaFileInfo::Write("testout.tga", output);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment