jeudi 23 juin 2016

GLSL - fragment shaders for image manipulation/blending


I'm trying to build a shader that allows you to combine two images by applying a gradient opacity mask to the one on top, like you do in photoshop. I've gotten to the point where I can overlay the masked image over the other but as a newbie am confused about a few things.

It seems that the images inside the shader are sometimes skewed to fit the canvas size, and they always start at position 0,0. I have played around with a few snippets I have found to try and scale the textures, but always end up with unsatisfactory results.

I am curious if there is a standard way to size, skew, and translate textures within a view, or if images in GLSL are necessarily limited in some way that will stop me from accomplishing my goal.

I'm also unsure of how I am applying the gradient/mask and if it is the right way to do it, because I do not have a lot of control over the shape of the gradient at the moment.

Here's what I have so far:

  precision highp float;
  varying vec2 uv;
  uniform sampler2D originalImage;
  uniform sampler2D image;
  uniform vec2 resolution;

  void main(){

    float mask;
    vec4 result;

    vec2 position = gl_FragCoord.xy / ((resolution.x + resolution.y) * 2.0 );

    mask = vec4(1.0,1.0,1.0,1.0 - position.x).a;

    vec4 B = texture2D(image,uv);
    vec4 A = texture2D(originalImage,uv) * (mask);

    result = mix(B, A, A.a);

    gl_FragColor = result;
  }

Which produces an image like this:

What I would like to be able to do is change the positions of the images independently and also make sure that they conform to their proper dimensions.

I have tried naively shifting positions like this:

vec2 pos = uv;
pos.y = pos.y + 0.25;
texture2D(image, pos)

Which does shift the texture, but leads to a bunch of strange lines dragging:

I tried to get rid of them like this:

gl_FragColor = uv.y < 0.25 ? vec4(0.0,0.0,0.0,0.0) : result;

but it does nothing


Aucun commentaire:

Enregistrer un commentaire