Newer
Older
/*
* Three-dimensional pattern in C++ based on the "Rings" Processing example.
*
* Uses noise functions modulated by sinusoidal rings, which themselves
* wander and shift according to some noise functions.
*
* 2014 Micah Elizabeth Scott
*/
#include <math.h>
#include "color.h"
#include "effect.h"
#include "noise.h"
class Rings : public Effect
{
public:
Rings()
static const float xyzSpeed = 0.006;
static const float xyzScale = 0.08;
static const float wSpeed = 0.002;
static const float wRate = 0.0001;
static const float ringScale = 1.5;
static const float ringScaleRate = 0.01;
static const float ringDepth = 0.2;
static const float wanderSpeed = 0.04;
static const float wanderSize = 1.8;
static const float hueScale = 5.0;
static const float hueRate = 0.001;
// State variables
// Calculated once per frame
float hue, saturation;
float spacing;
hue = noise2(f.time * hueRate, 20.5) * hueScale;
saturation = sq(std::min(std::max(0.7f * (0.5f + noise2(f.time * 0.01, 0.5)), 0.0f), 1.0f));
spacing = sq(0.5 + noise2(f.time * ringScaleRate, 1.5)) * ringScale;
// Rotate movement in the XZ plane
float angle = noise2(f.time * 0.01, 30.5) * 10.0;
float speed = pow(fabsf(noise2(f.time * 0.01, 40.5)), 2.5) * xyzSpeed;
d[0] += cosf(angle) * speed;
d[2] += sinf(angle) * speed;
// Random wander along the W axis
center = Vec3(noise2(f.time * wanderSpeed, 50.9),
noise2(f.time * wanderSpeed, 51.4),
noise2(f.time * wanderSpeed, 51.7)) * wanderSize;
virtual void calculatePixel(Vec3& rgb, const PixelInfo &p)
float dist = len(p.point - center);
Vec4 pulse = Vec4(sinf(d[2] + dist * spacing) * ringDepth, 0, 0, 0);
Vec4 s = Vec4(p.point * xyzScale, 0) + d;
Vec4 chromaOffset = Vec4(0, 0, 0, 10);
float n = fbm_noise4(s + pulse, 4) * 2.5f + 0.1f;
float m = fbm_noise4(s + chromaOffset, 4);
hsv2rgb(rgb,
hue + 0.5 * m,
saturation,
std::min(0.9f, sq(std::max(0.0f, n)))
);
}
};
int main(int argc, char **argv)
{
EffectRunner r;
Rings e;
r.setEffect(&e);
r.setLayout("../layouts/grid32x16z.json");
return r.main(argc, argv);
}