• Advertisement
Sign in to follow this  

Help with lens shader

This topic is 4343 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to write a 2D pixel shader that has the effect of placing a round lens above the image: the centre should magnify, and the edges should shrink. The lens is placed above the source image centred at the point (xOrigin, yOrigin). I've got this so far as my shader:
texture t;

sampler2D Sampler =
    Texture = (t);
    MinFilter = Anisotropic;
    MagFilter = Anisotropic;
    MipFilter = Anisotropic;

// Parameters for where the lens is placed
float xOrigin;
float yOrigin;

float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
    float xd = Tex.x - 0.5f;
    float yd = Tex.y - 0.5f;

    float ZoomValue = sqrt(xd * xd + yd * yd) * 0.5f;

    Tex.x = Tex.x * ZoomValue + xOrigin;
    Tex.y = Tex.y * ZoomValue + yOrigin;

    return tex2D(Sampler, Tex.xy);

technique Effect
    pass p0
        VertexShader = null;
        PixelShader = compile ps_2_0 EffectProcess();

t is the source texture. This isn't quite right, it works but the upper left of the image magnifies less and the bottom right more, due to the increasing Tex.xy values, so it's an uneven zoom. Does anyone have the correct formula? Thanks

Share this post

Link to post
Share on other sites
i think the zoomfactor should be something like:
zoomfactor=strength-sqrt( (Tx-0.5)^2 + (Ty-0.5)^2 );

the squareroot is the distance from the sampled point to the center. Strength is some value that defines how strong your zoomeffect will be. When you put in 0 your lens will only shrink at the edges and in the middle everthing will look like before.

btw haven't looked at the rest of the code but you said the code shrinks some parts so everything should be fine.

hope that helps(and that eveyrthing is correct)


Share this post

Link to post
Share on other sites
You're trying to be way too complicated....

Why not use 2 textures instead of 1.

Check this out.....

The texture below is composited as follows...

the R and G components are the du/dv offsets, and the B component is a scalar height value.


If you add a float input to your shader called 'zoom', you can use this to increase/decrease the effect.

... anyway, in the fragment shader, compute the texcoords of the image as follows:

float zoom= IP_zoom;

vec3 normal= texture2D(tex1, gl_TexCoord[0].xy ).rgb * 2.0 - 1.0;
vec3 image= texture2D(tex0, (gl_TexCoord[0].xy + normal.xy)*(normal.z*zoom) ).rgb

now, if zoom is set to 0, there will be no fisheye, anything greater than 0 will just keep on increasing the effect.

Another benefit, is you can use all different shapes for offsetting the coords, just by creating a new texture.

Hope that helps.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement