GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2018-01-31 19:07:04

lostdarkwolf
Member
Registered: 2015-11-19
Posts: 31

surface_perlinize for perlin textures (includes looping)

want realistic perlin textures in your game? Now you have it.
Download required sprite. (through host-a.net)
The resource name of the required sprite is "sp_circle_part", but I've made it easy to rename.

Expand///surface_perlinize(surface, looping*, stamps*, stamp_size*)
// * argument is optional
//
// creates small perturbations in a given surface.
//
// DO NOT set "stamps" to a high number, otherwise risk crashing.
//
// surface     The surface to use, real - integer.
// looping     Make looping perlin texture if true, real - bool
// stamps      Number of times to "stamp" a perturbation to the surface, real - integer.
// stamp_size  The size of the stamps, real - normal.
//
// This script is intended to be run repeatedly. once per step, for each surface it applies to.
// You should not expect to be able to generate fully perlinized surfaces in real time with this script.
//
/// GMLscripts.com/license

 var width, height, stamp_count, stamp_size, surf_id, looping;
 surf_id = argument[0];
 width=surface_get_width(surf_id)
 height=surface_get_height(surf_id)
 looping=0;
 if argument_count>1 looping=argument[1]; 
 stamp_count=100;
 if argument_count>2 stamp_count=argument[2];
 stamp_size=1/255;
 if argument_count>3 stamp_size=argument[3];

 var var_sprite; var_sprite=sp_circle_part;

 surface_set_target(surf_id);
 var side_e, side_n, side_w, side_s, lightness, ii, xx, yy, mode, color, intensity;
 var var_min; var_min=min(width/16,height/16);
 var var_range; var_range=max(width/2,height/2);
 repeat stamp_count {
  side_e=ceil(var_min)+irandom(var_range)
  side_n=ceil(var_min)+irandom(var_range)
  side_w=ceil(var_min)+irandom(var_range)
  side_s=ceil(var_min)+irandom(var_range)
  
  // generation properties
  mode=irandom(16)!=5 // add (true) or subtract (false)
  color=c_white
  intensity=0.001+random(0.099);
  xx=-(width/2)+irandom(width*2);
  yy=-(height/2)+irandom(height*2);
  
  if mode=0 color=c_black;
  if mode=1 draw_set_blend_mode(bm_add)
  
  draw_sprite_ext(var_sprite,0,xx,yy,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
  draw_sprite_ext(var_sprite,0,xx,yy,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
  draw_sprite_ext(var_sprite,0,xx,yy,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
  draw_sprite_ext(var_sprite,0,xx,yy,side_e*stamp_size,side_s*stamp_size,0,color,intensity)

  if looping {
   if xx>width/2 and yy>height/2 {
    draw_sprite_ext(var_sprite,0,xx-width,yy-height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy-height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy-height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy-height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if yy>height/2 {
    draw_sprite_ext(var_sprite,0,xx,yy-height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy-height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy-height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy-height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if xx<=width/2 and yy>height/2 {
    draw_sprite_ext(var_sprite,0,xx+width,yy-height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy-height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy-height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy-height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if xx>width/2 {
    draw_sprite_ext(var_sprite,0,xx-width,yy,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if xx<=width/2 {
    draw_sprite_ext(var_sprite,0,xx+width,yy,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if xx>width/2 and yy<=height/2 {
    draw_sprite_ext(var_sprite,0,xx-width,yy+height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy+height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy+height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx-width,yy+height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if yy<=height/2 {
    draw_sprite_ext(var_sprite,0,xx,yy+height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy+height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy+height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx,yy+height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
   if xx<=width/2 and yy<=height/2 {
    draw_sprite_ext(var_sprite,0,xx+width,yy+height,side_e*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy+height,(-side_w)*stamp_size,(-side_n)*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy+height,(-side_w)*stamp_size,side_s*stamp_size,0,color,intensity)
    draw_sprite_ext(var_sprite,0,xx+width,yy+height,side_e*stamp_size,side_s*stamp_size,0,color,intensity)
   }
  }
  if mode=1 draw_set_blend_mode(bm_normal)
 }
 surface_reset_target();
 

use this part of the way through generation of the texture, it will maximize the generation potential! (use channel 3)

Expand//surface_normalize_channel(surface,channel,mix*)
// * argument is optional
//
// normalizes a color channel on a surface
//
// surface  surface to normalize, real - integer
// channel  color channel to normalize, real - integer - 0 to 3 only
// mix      mix between original and normalized results, real - normal
//
// this script will likely generate lag.
// 
/// GMLscripts.com/license

var surf_id, channel, width, height, norm_mix;
surf_id=argument[0];
channel=argument[1];
width=surface_get_width(surf_id);
height=surface_get_width(surf_id);
norm_mix=1;
if argument_count>2 norm_mix=argument[2];

var var_max; var_max=0;
var var_min; var_min=255;
var surf_array;
var buff; buff = buffer_create(width*height*4, buffer_fixed, 4); 
buffer_get_surface(buff, surf_id, 0, 0, 0);
var iix, iiy;
for(iiy=0; iiy<height; iiy+=1) {
 for(iix=0; iix<width; iix+=1) {
  surf_array[iix,iiy]=buffer_peek(buff,((iix+(iiy*width))*4)+channel,buffer_u8)
  //show_message(surf_array[iix,iiy])
  var_max=max(surf_array[iix,iiy],var_max)
  var_min=min(surf_array[iix,iiy],var_min)
 }
}

if (var_max-var_min)>0 {
 for(iiy=0; iiy<height; iiy+=1) {
  for(iix=0; iix<width; iix+=1) {
   buffer_poke(buff,((iix+(iiy*width))*4)+channel,buffer_u8,round(lerp(surf_array[iix,iiy],(surf_array[iix,iiy]-var_min)*(255/(var_max-var_min)),norm_mix)))
  }
 }
 buffer_set_surface(buff, surf_id, 0, 0, 0)
}
if (var_max-var_min)=0 {
 surface_set_target(surf_id)
 draw_clear($808080)
 surface_reset_target()
}

surf_array=0;
buffer_delete(buff);

This may help too. It is not a script, just a small draw code that will display the buffer created by buffer_get_surface(...).

Expand// hm_width and hm_height are assumed to be set already.
var iix, iiy, var_buffer_val;
for (iiy=hm_height-1; iiy>=0; iiy-=1;) {
 for (iix=hm_width-1; iix>=0; iix-=1;) {
  var_buffer_val=buffer_peek(buffer_hm, ((iix+(iiy*hm_width))*4)+3, buffer_u8);
  draw_point_color(iix,iiy,make_color_rgb(var_buffer_val,var_buffer_val,var_buffer_val));
 }
} 

This may help as well. It is a script that will set a z coordinate from height-field values.

Expand///set_z(x, y, z1, z2, z3, z4, cell_size*)
// * argument is optional
//
// Sets a z coodinate from height-field values.
//
// x          x position of the instance to set z for, real - float
// y          y position of the instance to set z for, real - float
// z1         z coordinate at the top left corner of the cell that the player is in, real - integer
// z2         z coordinate at the top right corner of the cell that the player is in, real - integer
// z3         z coordinate at the bottem left corner of the cell that the player is in, real - integer
// z4         z coordinate at the bottem right corner of the cell that the player is in, real - integer
// cell_size  ammount of units (or pixels) in one cell, real - integer
//
/// GMLscripts.com/license

var z1, z2, z3, z4, cell_size, x_differ, y_differ, ret;
x_differ=argument[0]-(floor(argument[0]/cell_size)*cell_size);
y_differ=argument[1]-(floor(argument[1]/cell_size)*cell_size);
z1=argument[2]
z2=argument[3]
z3=argument[4]
z4=argument[5]
cell_size=16;
if argument_count>6 cell_size=argument[6];

if (x_differ>y_differ) return (z1+(z2-z1)*x_differ/cell_size+(z3-z2)*y_differ/cell_size);
else return (z1+(z4-z1)*y_differ/cell_size+(z3-z4)*x_differ/cell_size);

Last edited by lostdarkwolf (2018-02-08 13:30:20)

Offline

Board footer

Powered by FluxBB