GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2009-12-16 06:41:06

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Smooth color grid

This function smooths/blends the colors held in a grid
I use a grid mapped to the screen and draw to the grid (setting the colors in the grid cells) then call this to smooth things out. Blending the colors together

I could not use a disk function here because the way colors are added and averaged.

Expand//argument0 - grid with color values
var w,h;
w = ds_grid_width(argument0)
h = ds_grid_height(argument0)
var g; g = ds_grid_create(w,h)
var xx,yy;
yy = 0;
var av;
var ct;
repeat(h)
{
    xx = 0;
    repeat(w)
    {
        c1 = ds_grid_get(argument0,xx,yy);
        c2 = ds_grid_get(argument0,xx-1,yy);
        c3 = ds_grid_get(argument0,xx+1,yy);
        c4 = ds_grid_get(argument0,xx,yy-1);
        c5 = ds_grid_get(argument0,xx,yy+1);

        c2 = merge_color(c1,c2,.5)
        c3 = merge_color(c1,c3,.5)
        c4 = merge_color(c1,c4,.5)
        c5 = merge_color(c1,c5,.5)

        c2 = merge_color(c2,c3,.5)
        c3 = merge_color(c4,c5,.5)

        c2 = merge_color(c2,c3,.5)

        c1 = merge_color(c1,c2,.5)


       
        ds_grid_set(g,xx,yy,c1);
        xx+=1;
    }
    yy+=1;
}

ds_grid_copy(argument0,g);
ds_grid_destroy(g);

and this generates a smooth version for final display. As you usually have a small grid mapped to a large screen. It can be used to scale up an image held in a grid. it's faster than that grid manipulation function which I think I had posted here (cant find it)

gs is the grid size. In my application, the width and height (of grid) are the same, argument0 is the grid. I know it's a weird mix but I just though I'd share it as is. You can modify the code to generate a model of any size, via the xf yf values.

Expandmodel = d3d_model_create();

var ct;
ct = 0;


xf = room_width/(gs-1);
yf = room_height/(gs-1);

//argument0 - grid

var w,h;
w = ds_grid_width(argument0)-1
h = ds_grid_height(argument0)-1
var g; g = ds_grid_create(w,h)
var xx,yy;
yy = 0;
var av;

d3d_model_primitive_begin(model,pr_trianglelist);

repeat(h)
{
    xx = 0;
    repeat(w)
    {
        c1 = ds_grid_get(argument0,xx,yy+1);
        c2 = ds_grid_get(argument0,xx,yy);
        c3 = ds_grid_get(argument0,xx+1,yy);
        c4 = ds_grid_get(argument0,xx+1,yy+1);

        x1 = xx*xf;
        x2 = xx*xf;
        x3 = (xx+1)*xf;
        x4 = (xx+1)*xf;
       
        y1 = (yy+1)*yf;
        y2 = yy*yf;
        y3 = yy*yf;
        y4 = (yy+1)*yf;
        
        d3d_model_vertex_color(model,x1,y1,0,c1,1)
        d3d_model_vertex_color(model,x2,y2,0,c2,1)
        d3d_model_vertex_color(model,x3,y3,0,c3,1)
        d3d_model_vertex_color(model,x3,y3,0,c3,1)
        d3d_model_vertex_color(model,x4,y4,0,c4,1)
        d3d_model_vertex_color(model,x1,y1,0,c1,1)



        xx+=1;
        ct+=6;
        if(ct>900)
        {
            d3d_model_primitive_end(model);
            d3d_model_primitive_begin(model,pr_trianglelist);
            ct = 0;
        }
    }
    yy+=1;
}
d3d_model_primitive_end(model);
d3d_model_draw(model,0,0,0,-1)
if(is_string(argument1))
{
    d3d_model_save(model,argument1)
}
d3d_model_destroy(model);

Last edited by icuurd12b42 (2009-12-16 06:42:47)

Offline

#2 2009-12-16 06:52:16

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: Smooth color grid

Here is the program that uses this method

http://www.yoyogames.com/games/107091-nebula-draw

I did move the first function and the rough draw code, which just draws the grid with rectangles, to a dll... But the model generation is pure gml (hold space)

Offline

#3 2009-12-16 15:38:34

xot
Administrator
Registered: 2007-08-18
Posts: 1,240

Re: Smooth color grid

I could not use a disk function here because the way colors are added and averaged.

Yes and no. You could use the disk function if you kept the color channels in separate grids but that might not be a speed improvement unless the radius of the smoothing area is larger than 2 or 3 pixels. It also wouldn't have the same weighting since in your script the center pixel appears to have much more influence on the blended color than the neighbor pixels.


Abusing forum power since 1986.

Offline

#4 2009-12-16 18:49:05

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: Smooth color grid

Yes, you can always change a few lines so the center pixel has less weight. I tried a half dozen variations. This one was best in the case of my little nebula drawing tool. As I needed the extra weight for the gradual changes (it's called every step) so that the whole getup would not fade out entirely.

Offline

#5 2009-12-18 08:30:20

xot
Administrator
Registered: 2007-08-18
Posts: 1,240

Re: Smooth color grid

I think a faster way, again only if you are willing to use separate grids for each channel, could be like this:

Expandw = ds_grid_width(source);
h = ds_grid_height(source);
destination = ds_grid_create(w, h);
ds_grid_copy(destination, source);
ds_grid_add_grid_region(destination, source, 0, 0, w, h, -1,  0);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  1,  0);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  0, -1);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  0,  1);
ds_grid_multiply_region(destination, 0, 0, w, h, 0.2);

You could easily give the center pixel extra weight with another ds_grid_multiply_region call after the copy.

Expandw = ds_grid_width(source);
h = ds_grid_height(source);
destination = ds_grid_create(w, h);
ds_grid_copy(destination, source);
ds_grid_multiply_region(destination, 0, 0, w, h, 12);
ds_grid_add_grid_region(destination, source, 0, 0, w, h, -1,  0);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  1,  0);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  0, -1);
ds_grid_add_grid_region(destination, source, 0, 0, w, h,  0,  1);
ds_grid_multiply_region(destination, 0, 0, w, h, 0.0625);

Abusing forum power since 1986.

Offline

#6 2009-12-18 19:02:58

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: Smooth color grid

Yep. Definitely you should also copy that suggestion in that grid smooth topic... Smart.

Offline

#7 2009-12-18 19:18:32

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: Smooth color grid

Also, I'm starting to wonder if I can do this with surfaces...

Instead of a 32x32 grid, have a 32x32 surface and draw onto another 32x32 surface at +1 -1... with alpha set properly. The final draw is that surface streched with interpolation ON....

Offline

#8 2009-12-18 21:30:27

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: Smooth color grid

icuurd12b42 wrote:

Also, I'm starting to wonder if I can do this with surfaces...

Instead of a 32x32 grid, have a 32x32 surface and draw onto another 32x32 surface at +1 -1... with alpha set properly. The final draw is that surface streched with interpolation ON....

Yep. here it is. In my case, I had to use alpha .2 so it would balance (not fade out or fill the screen) because I call it all the time. And bm add so the pixel would keep the right color...

s2 and s(1) are the surfaces, say 32x32

s1 has the original image, draw onto with set pixel.
s2 is draws to with bm_add (on black), at offset
s2 is transfered back to s1
global.bleed 0-1 value defines how much the surface is tranfered back and in effect defined how much the color leaks on the canvas

s is drawn stretched with interpolation on the screen in the draw event

texture_set_interpolation(0)
surface_set_target(s2)
draw_set_blend_mode(bm_add)
draw_clear_alpha(c_black,1)

draw_surface_ext(s,0,0,1,1,0,c_white,.2);
v = 1;
draw_surface_ext(s,-v,0,1,1,0,c_white,.2);
draw_surface_ext(s,+v,0,1,1,0,c_white,.2);
draw_surface_ext(s,0,-v,1,1,0,c_white,.2);
draw_surface_ext(s,0,+v,1,1,0,c_white,.2);
draw_set_blend_mode(bm_add)
draw_set_color(c_black)
draw_rectangle(0,0,gs,gs,0)
draw_set_color(c_white)
draw_set_blend_mode(bm_normal)

surface_set_target(s)
draw_surface_ext(s2,0,0,1,1,0,c_white,global.bleed);
draw_set_blend_mode(bm_add)
draw_set_color(c_black)
draw_rectangle(0,0,gs,gs,0)
draw_set_color(c_white)
draw_set_blend_mode(bm_normal)

surface_reset_target();

http://www.yoyogames.com/games/107435-nebula-draw-v2

Offline

#9 2009-12-19 12:25:20

xot
Administrator
Registered: 2007-08-18
Posts: 1,240

Re: Smooth color grid

Good call on the additive blending, that's the key to these multipass blur effects, especially when surfaces are involved.

Something you should experiment with is using blend mode _ext(bm_one,bm_one) instead of bm_add. Although they generally look identical, they are not exactly the same (at least on my hardware). I think they treat the alpha channel a little differently, although I haven't spent any time determining exactly how they differ. The difference between them is profound in my effects engine. Since _ext(bm_one,bm_one) seems a little more predictable I tend to avoid bm_add now.


Abusing forum power since 1986.

Offline

#10 2009-12-19 17:40:24

RaiSoleil
Member
Registered: 2009-08-02
Posts: 16

Re: Smooth color grid

I believe bm_add is functionally equivalent to _ext(bm_src_alpha,bm_one).

Offline

#11 2009-12-19 18:21:59

xot
Administrator
Registered: 2007-08-18
Posts: 1,240

Re: Smooth color grid

Hmmmm, I think you are right. I just tried _ext(bm_src_alpha,bm_one) where I was having a problem with bm_add and the result looked identical.


Abusing forum power since 1986.

Offline

Board footer

Powered by FluxBB