Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Stackie – A tiny stack machine for texture generation (fingswotidun.com)
81 points by Lerc on Aug 18, 2015 | hide | past | favorite | 19 comments



This code run from console will generate and execute random codes, whenever it finds something new it stops (just reexecute it and it will continue searching)

  var seen = seen || [];
  while (true) {
    c='';
    m=30*Math.random();
    var a='x0123456789dcp+*~!yPsqa-/^';
    for (var i=0; i<m; i++) {    
      c+=a.charAt(Math.floor(Math.random()*a.length));
    }
    code.value = c;
    buttonClick();
    d=f.getImageData();
    sum=0; 
    for (var i=0; i<5000; i++) { 
      sum+=d.data[i];
    }
    console.log('seen ', sum);
    if (seen.indexOf(sum) < 0) {
      seen.push(sum);
      break;
    }
  } 
Few examples generated by this:

    s*23-yxxx+-7x7s/y-^3sp*
    9sx2+ysx-7ysp+*+
    -P+p*syq6^xp15x/syxyyc-p**


I quite like this generated one: cq1cxxq~!4+p~/~37d^8y/3-c


a similar, less complicated one 55 * y! * y! * y! * P *s


I made something that compiles it to Javascript: https://gist.github.com/Matheus28/ce76f1f7f5e2b046b1fd

The original idea was compiling it to GLSL, but I got lazy. But it should be pretty easy to make it generate GLSL.

It doesn't do constant folding or any smart optimizations, but it should be pretty easy to code that in.

Example:

This:

    x12/-y12/-a6+8*x12/-d*y12/-d*+qq82**p112/x-d*-112/y-d*-*d*d*d**dd*+dd*+dd*+
Generates:

  var tmp0 = (x - (1 / 2))
  var tmp1 = (y - (1 / 2))
  var tmp2 = ((1 / 2) - x)
  var tmp3 = ((1 / 2) - y)
  var tmp4 = ((1 - (tmp2 * tmp2)) * (1 - (tmp3 * tmp3)))
  var tmp5 = (tmp4 * tmp4)
  var tmp6 = (tmp5 * tmp5)
  var tmp7 = (perlin(((Math.atan2((x - (1 / 2)), (y - (1 / 2))) + 6) * 8), (Math.sqrt(Math.sqrt(((tmp0 * tmp0) + (tmp1 * tmp1)))) * (8 * 2))) * (tmp6 * tmp6))
  var tmp9 = (tmp7 + (tmp7 * tmp7))
  var tmp11 = (tmp9 + (tmp9 * tmp9))
  
  return (tmp11 + (tmp11 * tmp11))
  function perlin(b,c){function g(b,c,a){a=a*a*a*(a*(6*a-15)+10);return(1-a)*b+a*c}function d(d,e){var a=2*(256*e+d);return(b-d)*gradient[a]+(c-e)*gradient[a+1]}b%=256;c%=256;var e=b&255,f=c&255,h=e+1&255,k=f+1&255,l=b-e,m=c-f;return g(g(d(e,f),d(h,f),l),g(d(e,k),d(h,k),l),m)};


If you make a GLSL version you absolutely must add

"t" : push(time);



For those who don't immediately understand (I hope I got that right):

- the 'Try It' button disappears behind a text box if the browser window is too narrow, making you unable to use the tool. (edited after hobs' reply)

- 0 is black, 1 is white (and so is larger than 1).

- if a,b is on top of the stack, then - pops b and a and puts (a-b) on the stack

- the value on top of the stack (after the entire string was processed by the stack machine) will determine the final colour of the pixel

- the algorithm runs for every pixel, that's why it's kinda slow


I am one of those people, because I see the examples and the text box but nothing appears to occur when I use it or try any of the examples.

Tried Chrome and FF (and disabling extensions), so I thought I was just doing it wrong.

However, I did a little more digging because of the discussions, and I think the button that I am supposed to click is hidden http://i.imgur.com/kI8TrfE.png

I dont know how this is happening across both browsers though, but I thought I would leave this here if anyone else is confused as I was.

Update: After trying a few things, stretching the screen width made the button pop up.


The page was constructed by progressively adding bits as I coded. The page layout is somewhat crazy because of that.


Haha, no worries, I just wanted to try out this cool tool, and had never used something like it before, so I thought it was me!


The use of single digit constants is a bit strange. Why kot take the approach of dc and let constant tokens be any string of digits, separated either by a different token or whitespace? Or the rather simpler approach of forth where all tokens are separated by whitespace.

I also have to echo shat someone else mentioned: give Forth Haiku a try!


Lovely! It reminds me of some methods of generating images with genetic programming, e.g. Karl Sims, http://dahart.com, and http://picbreeder.org. The main difference being a stack-based representation versus a tree-based one. Some people do use stack-based genetic programming, so it would be fun to hook this up to one of those systems and evolve textures.

One nice feature in the above strand of research is that the output value, instead of being mapped to a greyscale, is mapped via a colour map to produce colour images.


if you provide a mapping function Stackie will generate colours too. It just uses a grey mapper if none is provided.

You can provide your own function that takes a number and returns an ARGB Int32, so for pretty flame you would just do.

  f.generate(Stackie.program("x1x-*5*dx4**y3*p+y!-"));
  var flame = f.getImageData(blackbody);


FYI I'm getting "Uncaught TypeError: Failed to construct 'ImageData': Illegal constructor" on Chrome 41.


Yeah, it used to be the case that you had to create ImageData from a previously existing Canvas

The ImageData Constructor got support in Chrome 43 and FireFox 29.


Is it me or are there tools for Ludum Dare popping up everywhere? :D

http://www.ludumdare.com/compo/


Awesome! Would be awesomer if it supported color. E.g. a similar stack based way to generate a smooth 256 color palette.


Since Stacky.program() just makes a function(x,y) I added a palette generator. red is at y==0 green y=0.5 blue at y=1.0

so the palette program "x" generates a greyscale. "xy*" makes it orangy.


That is so cool.

L-systems could work as a stack system too perhaps ?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: