Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to create an effect called wormhole effect. I am using a shader file but I am not getting the exact effect. Does anyone have any idea or any smple shader file which can help me?

The effect looks something like the effect named "Wormhole" at found here (bottom right).

The shader file I am trying to improve is based on "Ripple" effect but I am not able to get that much smooth effect.

/// <class>RippleTransitionEffect</class>

/// <description>A transition effect </description>
/// <summary>The amount(%) of the transition from first texture to the second texture. </summary>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0</defaultValue>
float Progress : register(C0);

sampler input : register(s0);

texture Texture;
sampler Texture2 = sampler_state
    texture = <Texture>;
    magfilter = LINEAR;
    minfilter = LINEAR;
    mipfilter = LINEAR;
    AddressU = mirror;
    AddressV = mirror;

float4 Ripple(float2 uv,float progress)
  float radius = progress *  0.75;
  float FuzzyAmount = 0.001;
  float2 CenterPoint = float2(0.5,0.5);
  float fromCenter = length((uv - CenterPoint) / float2(0.75, 1));
  float distFromCircle = fromCenter - radius;  

  float frequency = 10;
  float speed = 1;
  float amplitude = 0.005;

  float wave = cos(frequency * distFromCircle - speed * progress) + 2;
  float offset1 = progress * wave * amplitude;
  float offset2 = (1.0 - progress) * wave * amplitude;
  float2 normToUV = (uv - CenterPoint) / distFromCircle;

  float2 newUV1 = CenterPoint + normToUV * (distFromCircle + offset1);
  float2 newUV2 = CenterPoint + normToUV * (distFromCircle + offset2);

  float4 c1 = tex2D(Texture2, newUV1);
  float4 c2 = tex2D(input, newUV2);

  float p = saturate((distFromCircle + FuzzyAmount) / (1.0 * FuzzyAmount));
  return lerp(c1, c2, p );

float4 main(float2 tex: TEXCOORD) : COlOR
  return Ripple(tex, Progress);

technique TransformTexture {
  pass P0     {        
    PixelShader  = compile ps_2_0 main();
share|improve this question
Before you get any negative comments, consider re-stating your question. I.e. tell the people what your ideas are, where you got stuck and describe your approach/desired approach in plain English. cheers – teodron Apr 19 '12 at 11:41
-1 Shows no research effort and we typically don't like "here's this code write it for me" type "questions". Can't say you weren't warned I guess. – Byte56 Apr 19 '12 at 13:49
up vote 2 down vote accepted

This shader snippet is just a hint on how I would do it, it's not a complete copy-paste-done! solution.

float4 Wormhole(float2 uv, float progress)
    float rad = 0.708 * progress; // radius from center of the uv texture square
    float swell = 0.1; // swell region magnitude
    float2 CPoint(0.5, 0.5); // center point 
    float dist = length(uv - CPoint);
    float2 uvOrig = uv;
    float2 uvNew = uv;
    float alpha = 0; // blend factor between the 2 textures
    if (dist < rad) // show the new texture - this expands from center outwards
        alpha = 1; //when inside, show the new texture colour
    if (dist > rad && dist < rad + swell)
        float lambda = smoothstep(rad, rad+swell, dist); // factor in [0,1]
        alpha = 1 - lambda; // modified blend factor
        float2 vec = uvOrig - CPoint;
        float2 dir = normalize(vec);
        uvOrig = CPoint + ((1-lambda) * rad + lambda * (rad+swell)) * dir;
    if (dist >= rad + swell)
        alpha = 0; // show the new texture only
    float4 c1 = tex2D(Texture2, uvNew);
    float4 c2 = tex2D(input, uvOrig);
    return lerp(c2,c1,alpha);

What does it do? Starting from the center, it should modify a linear interpolation factor based on the texture coordinates of that fragment. If the fragment is "inside" the wormhole, it shows the new texture. If the fragment is outside, but not too far (swell area), it show a blended color between the original "swelled" image and the new image. The fragments that are further away maintain the original texture color. That's how I would write a very simple wormhole shader.

share|improve this answer
Thanks teodron, that really helped me out. Thanks a lot. That's close to what I am looking for. – Vibhore Tanwer Apr 19 '12 at 14:14
You're welcome, I hope it wasn't too difficult to "reverse engineer" that snippet and deduce what it should do. Cheers! – teodron Apr 19 '12 at 16:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.