Links

Categories

Tags


« | Main | »

Render World Effect

By Jewe | May 22, 2014

Renders a two dimensional world map. (IrfanView Sandbox 1.2)

Download this script

import Random;
import Math;
import RasterizerSSE;

using Math;

class RenderWorld : Effect
{
    Slider XSeed, XFreq, YSeed, YFreq, SPers, SOcts, SInt;
    Label Rand;

    PerlinNoise Perl;
    float SeedX, SeedY;
    float Freq1, Freq2;
    float Int1, Int2;

    const var[] Hues = {
        { 0.00, Color::FromHSL(240, 0.5, 0.3) },  // deep water
        { 0.20, Color::FromHSL(210, 0.4, 0.5) },  // shallow water
        { 0.23, Color::FromHSL(60, 0.3, 0.5)  },  // dark sand
        { 0.25, Color::FromHSL(60, 0.3, 0.7) },   // sand
        { 0.30, Color::FromHSL(110, 0.5, 0.3) },  // dark grass
        { 0.50, Color::FromHSL(130, 0.3, 0.4) },  // grass
        { 0.70, Color::FromHSL(40, 0.4, 0.3) },   // dirt
        { 0.72, Color::FromHSL(0, 0, 0.3) },      // dark stone
        { 0.87, Color::FromHSL(0, 0, 0.5) },      // stone
        { 0.93, Color::FromHSL(70, 0.2, 0.9) },   // dirty snow
        { 1.00, Color::FromHSL(0, 0, 1.0) }       // snow
    };

    method RenderWorld()
    {
        Perl = null;
        SeedX = 0;
        SeedY = 0;
        Freq1 = 0;
        Freq2 = 0;
        Int1 = 0;
        Int2 = 0;

        Rand   = new Label("Perlin Properties");
        XSeed  = new Slider("X Seed (Start Position)",   "", 0,   0, 255,   91);
        YSeed  = new Slider("Y Seed (Start Position)",   "", 0,   0, 255,   91);
        XFreq  = new Slider("Frequency 1 (Zoom Factor)", "", 2,   1,  10,    2);
        YFreq  = new Slider("Frequency 2 (Zoom Factor)", "", 2,   1,  10,    7);
        SPers  = new Slider("Persistence (Smoothing)",   "", 2,   0,   1,  0.5);
        SOcts  = new Slider("Octaves (Level of Detail)", "", 0,   1,   5,    3);
        SInt   = new Slider("Balance (Mix)",             "", 2,   0,   1, 0.95);
    }

    method Parameter[] GetParameters()
    {
        return {Rand, XSeed, YSeed, XFreq, YFreq, SPers, SOcts, SInt};
    }

    method EffectInfo GetEffectInfo()
    {
        return new EffectInfo(
            "Render World",
            "by Jewe",
            "Renders a two dimensional world map."
        );
    }

    method DoEffect(Image img)
    {
        // create rasterizer for the image
        RasterizerSSE sky = new RasterizerSSE(img);
        // set up Perlin noise
        Perl = new PerlinNoise(SOcts.Value, SPers.Value);
        SeedX = XSeed.Value;
        SeedY = YSeed.Value;
        Freq1 = 0.002 * XFreq.Value;
        Freq2 = 0.02 * YFreq.Value;
        Int1 = SInt.Value;
        Int2 = 1.0 - Int1;
        // render map
        sky.ProcessPixels( method(x, y, c) {
            float r = Perl.Random(SeedX + x * Freq1, SeedY + y * Freq1) * Int1;
            r += Perl.Random(SeedX + x * Freq2, SeedY + y * Freq2) * Int2;
            r = Min(Max(r * 0.3 + 0.5, 0), 1.0);
            ColorRGB d = GetLandColor(r);
            c.Set(d.Red, d.Green, d.Blue);
        } );
        // finalize
        sky.Finalize();
    }

    function Color GetLandColor(float height)
    {
        int i = 0;
        for( ; i < Hues.length; i++)
        {
            if (Hues[i, 0] > height)
                break;
        }
        if (i == Hues.length)
            i--;
        int j = i - 1;
        if (j < 0)
            j = 0;
        float min = Hues[j, 0];
        float max = Hues[i, 0];
        float a = (height - min) / (max - min);
        return Color::Blend(Hues[j, 1], Hues[i, 1], a);
    }
}

Topics: code examples, filter sandbox | Comments Off on Render World Effect

Comments are closed.