## Code Excerpt for Texture Model Rings

    Scalar RingNo;     // in [0 .. 1] stepsize 0.01
    Scalar RingSize;   // in [0 .. 1] stepsize 0.01
    Scalar Seed;       // in [0 .. 1] stepsize 0.01
    Scalar Turbulence; // in [0 .. 1] stepsize 0.01
    Scalar Width;      // in [0.1.. 1] stepsize 0.09
    Scalar Grain;      // in [0 .. 0.3] stepsize 0.03
    Scalar GrainSmall; // in [0 .. 0.3] stepsize 0.03

    NoisePerlin perlin;

    void TextureRings::setupParameter(const std::vector<Scalar> &parameter){

        ring_size_ = 0.4 + RingSize * 5;
        ring_no_ = 2 + RingNo*38 *(0.9-(min(RingSize,0.6)));

        seed_ = Seed*5;
        ring_turbulence_ = Turbulence*0.5;
        width_ = Width;
        grain_ = Grain;
        grain_small_ = GrainSmall;

    }

    Scalar TextureRings::evaluate(const Scalar &x, const Scalar &y){

        Scalar x_shift = x + seed_;
        Scalar y_shift = y;

        Scalar rings_noise, tmp, rings= 0.0;
        Scalar value  = 0.0;

        Scalar noise = NoiseTurbulence::turbulence(x_shift, y_shift, 1);
        rings_noise = perlin.noise(ring_size_ * x_shift, ring_size_ * y_shift, 0.2) + noise * ring_turbulence_;

        tmp = rings_noise * ring_no_;
        rings = tmp - int(tmp);
        rings = fabs(rings);

        Scalar stepWidth = 0.2 * width_;
        if (rings < width_-stepWidth) {
            rings = smoothStep(rings, 0, stepWidth);
        } else if (rings < width_) {
            rings = 1.0 - smoothStep(rings, width_-stepWidth, width_);
        } else {
            rings = 0;
        }

        // grain
        Scalar grain = NoiseTurbulence::turbulence(x_shift * 4, y_shift * 4 , 0.5);
        Scalar grain_small = NoiseTurbulence::turbulence(x_shift * 160, y_shift * 160, 0.5);

        // all
        value = rings * (1-grain_-grain_small_) + grain_ *grain + grain_small_ *grain_small;

        return value;

    }