0

I'm trying to implement a 2D distortion effect with a displacementmap, which I will create at runtime by combining images like this. Link to Displacementmap

But due to the fact that (255,255,x) is equal to no displacement, I'm not able do combine these images with existing BlendModes.

So I wanted to store information in the RGBA (for x+,y+,x-,y-) of the color, but rendering to a RenderTarget2D sets every color with Alpha = 0 to Black with Alpha = 0. Is there a better way to combine displacementmaps or a way to prevent this behavieur?

AntiHeadshot
  • 1,130
  • 9
  • 24

1 Answers1

0

You can use custom shader like this

/* Variables */

float OffsetPower;

texture TextureMap; // texture 0
sampler2D textureMapSampler = sampler_state
{
    Texture = (TextureMap);
    MagFilter = Linear;
    MinFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

texture DisplacementMap; // texture 1
sampler2D displacementMapSampler = sampler_state
{
    Texture = (DisplacementMap);
    MagFilter = Linear;
    MinFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

/* Vertex shader output structures */

struct VertexShaderOutput
{
    float4 Position : position0;
    float2 TexCoord : texcoord0;
};

/* Pixel shaders */

float4 PixelShader1(VertexShaderOutput pVertexOutput) : color0
{
    float4 displacementColor = tex2D(displacementMapSampler, pVertexOutput.TexCoord);
    float offset = (displacementColor.g - displacementColor.r) * OffsetPower;

    float2 newTexCoord = float2(pVertexOutput.TexCoord.x + offset, pVertexOutput.TexCoord.y + offset);
    float4 texColor = tex2D(textureMapSampler, newTexCoord);

    return texColor;
}

/* Techniques */

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShader1();
    }
}

In LoadContent method:

this.textureMap = this.Content.Load<Texture2D>(@"Textures/creeper");
this.displacementMap = this.Content.Load<Texture2D>(@"Textures/displacement_map");
this.displacementEffect = this.Content.Load<Effect>(@"Effects/displacement");

In Draw method:

Rectangle destinationRectangle = new Rectangle(0, 0, this.GraphicsDevice.Viewport.Width, this.GraphicsDevice.Viewport.Height);

this.displacementEffect.Parameters["OffsetPower"].SetValue(0.5f);
this.displacementEffect.Parameters["DisplacementMap"].SetValue(this.displacementMap);

this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, this.displacementEffect);
this.spriteBatch.Draw(this.textureMap, destinationRectangle, Color.White);
this.spriteBatch.End();

Result.

  • I confused distortion with displacement, i want to store x and y displacement seperately to acive redults like http://i.stack.imgur.com/m8IoW.jpg, my shader for this is working. The problem is adding two maps to one with both images overlapping. Due to the fact no displacement is 0.5r 0.5g ?b so adding 0.25r 0.5g (x+= -0.25, y+=0) to 0.25r 0.5g will result in 0r 0.5g (x+= -0.5, y+=0 – AntiHeadshot Jul 10 '14 at 04:50
  • @AntiHeadshot, sorry that you are confused :) As I understand you calculate distortion in some way like this: offset = ((r-0.5)*power, (g-0.5)*power). I cannot check this now but think if you doing like this you will get correct distortion. –  Jul 10 '14 at 10:44
  • Yes thats right, but my problem isn't the shader, its creating the displacementmap but i think i have a sollution. I will test implementing it this night. – AntiHeadshot Jul 10 '14 at 14:47