Help with lens shader

Started by
2 comments, last by AshleysBrain 18 years ago
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 =
sampler_state
{
    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
Construct (Free open-source game creator)
Advertisement
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)

regards,
m4gnus
"There are 10 types of people in the world... those who understand binary and those who don't."
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.

http://img135.imageshack.us/my.php?image=offsetmap9wo.jpg


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.
Thanks guys, got it all sorted!
Construct (Free open-source game creator)

This topic is closed to new replies.

Advertisement