Skip to content
Snippets Groups Projects
rings.cpp 2.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * 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()
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            : d(0, 0, 0, 0) {}
    
    
        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;
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
        virtual void beginFrame(const FrameInfo &f)
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            hue = noise2(f.time * hueRate, 20.5) * hueScale;
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            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
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            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
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            d[3] += noise2(f.time * wRate, 3.5) * wSpeed;
    
    
            // Update center position
    
    Micah Elizabeth Scott's avatar
    Micah Elizabeth Scott committed
            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);
    }