2

I'm currently working on a shader for a very mundane effect I'd like to achieve. It's a little bit hard to explain, but the basic gist is that I'm trying to "pull apart" the pixels of a pixel art image.

You can see my current progress, however minor, at this jsfiddle: https://jsfiddle.net/roomyrooms/Lh46z2gw/85/

I can distort the image easily, of course, and make it stretch the further away from the center it is. But this distorts and warps it smoothly, and all the pixels remain connected (whether they're squished/smeared/etc.)

I would like to get an effect where the space between the pixels is stretched rather than the pixels themselves stretching. Sort of like if you were to swipe sand across a table. The grains of sand stay the same size, they just get further apart.

Welcome any ideas! Thanks. Here's what I've got code-wise so far:

var fragmentShader = `
precision mediump float;

varying vec2 vTextureCoord;

uniform sampler2D uSampler;
uniform highp vec4 inputSize;
uniform float time;

vec2 mapCoord( vec2 coord )
{
    coord *= inputSize.xy;
    coord += inputSize.zw;

    return coord;
}

vec2 unmapCoord( vec2 coord )
{
    coord -= inputSize.zw;
    coord /= inputSize.xy;

    return coord;
}

void main(void)
{
    vec2 coord = mapCoord(vTextureCoord);
    float dist = distance(coord.x, inputSize.x/2.);
    coord.x += dist/4.;
    coord = unmapCoord(coord);
    gl_FragColor = texture2D(uSampler, coord);
}`

EDIT: Added an illustration of the effect I'm trying to achieve here: enter image description here

I can get something along these lines:

enter image description here

With modulo, but it's discarding half of the image in the process.

LJᛃ
  • 7,655
  • 2
  • 24
  • 35

2 Answers2

2

You can:

  • discard some fragments (that is slow on some mobile devices)
  • use stencil mask to just draw where you want
  • draw transparent pixels alpha=0 for the ones that you do not want.
  • and lastly, you can draw an array of points or squires and move them around.
Nikolay Handzhiyski
  • 1,360
  • 1
  • 6
  • 20
  • I've attempted to illustrate the effect I'm trying to achieve here: https://i.gyazo.com/23d03a887d2e1c752ce87730b292ccf0.png Is it possible to use the above methods to do something along these lines? Wherein the actual content is still preserved/not discarded, just moved across frags/pixels. – Jacob Davis Oct 27 '21 at 17:28
0

As far as I know, the fragment shader will run on every pixel in your triangle. You can only tell it what color to set that pixel to. In your example you're already duplicating columns of pixels so you can discard some hopefully without losing any of the source image's pixels if you stretch the coord 2x then discard every other column.

vec2 coord = mapCoord(vTextureCoord);
if(coord.x < 100.0 && floor(coord.x/2.0)==floor((coord.x+1.0)/2.0))
    discard;
Curtis
  • 2,486
  • 5
  • 40
  • 44