public void Update()
    {
        // ----- These Filter.Set calls are an editor thing ----
        //    In most cases, you'll have a point in your code when a value changes.
        //    Set them then rather than spamming them like this
        //    (we just unfortunately don't get any events when the inspector changes).

        // Update properties (note that this can be sped up by caching the property references - they don't do all that much anyway):
        Filter.Set("contours", Contours);
        Filter.Set("uniformity", Uniformity);
        Filter.Set("frequency", Frequency);

        // Render it now:
        // Filter.Draw renders it 'live' meaning the result is a RenderTexture.
        // This is better than constantly going from a RT to a Tex2D (but note that it only actually redraws when you call Draw).
        Texture newResult = Filter.Draw(DrawInfo);

        if (Result != newResult)
        {
            Result = newResult;

            // Update element (getById is short for obtaining it as a HtmlElement):
            PowerUI.UI.document.getById("loonim-image").image = Result;
        }
    }
    public void Start()
    {
        // Create it:
        Filter = new SurfaceTexture();

        // Apply initial properties (inputs into the filter):
        Filter.Set("srcA", SourceImageA);
        Filter.Set("srcB", SourceImageB);
        Filter.Set("weight", BlendWeight);
        Filter.Set("mode", (int)Mode);

        // Build the node graph now (just the one node here too):

        Filter.Root = new Blend(
            new Property(Filter, "srcA"),
            new Property(Filter, "srcB"),
            new Property(Filter, "weight"),
            new Property(Filter, "mode")
            );

        // Create the draw information:
        // - GPU mode
        // - Size px square
        // - HDR (true)
        DrawInfo = new DrawInfo((int)SourceImageA.width);
    }
    public void Start()
    {
        // Create it:
        Filter = new SurfaceTexture();

        // Apply initial properties (inputs into the filter):
        Filter.Set("contours", Contours);
        Filter.Set("uniformity", Uniformity);
        Filter.Set("frequency", Frequency);

        // Start building our voronoi node.
        // Voronoi is, in short, a kind of cellular noise.
        Voronoi v = new Voronoi();

        // *All* are required:
        v.Frequency       = new Property(Filter, "frequency");
        v.Distance        = new Property((int)VoronoiDistance.Euclidean);
        v.DrawMode        = new Property((int)VoronoiDraw.Normal);
        v.MinkowskiNumber = new Property(0f);
        v.Function        = new Property((int)VoronoiMethod.F2minusF1);
        v.Jitter          = new Property(Filter, "uniformity");

        // If we just displayed 'v' as our root node, we'd just
        // get some voronoi noise which looks like a bunch of black and white balls.

        // So, next, we'll tonemap for interesting effects.

        // Create a sine wave with a variable frequency (to be used by the tonemapper):
        TextureNode graph = new ScaleInput(
            new SineWave(),
            new Property(Filter, "contours")
            );

        // Create the tonemapper node now.
        // -> We're mapping the black->white range of pixels from the voronoi noise via our sine graph.
        // That creates a kind of hypnotic black-and-white 'rippling' effect.
        ToneMap map = new ToneMap(v, graph);

        // Let's make it some more exciting colours.
        // Create a gradient from a background->foreground colour, and use lookup to map from our b+w to that gradient.
        Blaze.Gradient2D rawGradient = new Blaze.Gradient2D();
        rawGradient.Add(0f, Color.blue);
        rawGradient.Add(1f, Color.white);

        // Create that lookup now:
        Filter.Root = new Lookup(
            new Loonim.Gradient(rawGradient, null),
            map
            );

        // Create the draw information:
        // - GPU mode
        // - Size px square
        // - HDR (true)
        DrawInfo = new DrawInfo((int)Size);
    }
        /// <summary>Builds a Loonim filter from the given set of one or more CSS functions.</summary>
        public static void BuildFilter(Css.Value value, RenderableData context, FilterEventDelegate fe)
        {
            if (value is Css.Functions.UrlFunction)
            {
                // - (A URL to an SVG filter) (not supported yet here)
                // - A URL to a Loonim filter (with a property called source0)

                // Load it now!
                DataPackage dp = new DataPackage(value.Text, context.Document.basepath);

                dp.onload = delegate(UIEvent e){
                    // Got the data! Load a filter now:
                    SurfaceTexture st = null;

                    // Create:
                    st = new SurfaceTexture();

                    // Load it:
                    st.Load(dp.responseBytes);

                    // Run the callback:
                    fe(context, st);
                };

                // Send:
                dp.send();
            }
            else
            {
                Loonim.TextureNode first = null;
                Loonim.TextureNode last  = null;

                // - One or more filter functions
                if (value is Css.CssFunction)
                {
                    // Just one:
                    first = last = value.ToLoonimNode(context);
                }
                else if (value is Css.ValueSet)
                {
                    // Many
                    for (int i = 0; i < value.Count; i++)
                    {
                        // Convert to a Loonim node:
                        Loonim.TextureNode next = value[i].ToLoonimNode(context);

                        if (next == null)
                        {
                            // Quit!
                            first = null;
                            last  = null;
                            break;
                        }

                        // Hook it on:
                        if (first == null)
                        {
                            first = last = next;
                        }
                        else
                        {
                            // Add it to the chain:
                            next.Sources[0] = last;
                            last            = next;
                        }
                    }
                }

                SurfaceTexture st = null;

                if (last != null)
                {
                    // Create the texture:
                    st = new SurfaceTexture();
                    st.Set("source0", (UnityEngine.Texture)null);
                    st.Root          = last;
                    first.Sources[0] = new Loonim.Property(st, "source0");
                }

                // Run the callback now!
                fe(context, st);
            }
        }