You don’t have to use the apply call unless you add a vertex shader you don’t have to use the set either on the first texture you can redo it like so.
to paste code just make sure there are a couple emptly lines above and below the code you paste.
drop it in and highlight all of it.
then hit the preformatted text button.
//
// refract
//
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
// This vector should be in motion in order to achieve the desired effect.
float2 DisplacementMotionVector;
// displacement amount
float DisplacementIntensity;
Texture2D Texture : register(t0);
sampler TextureSampler : register(s0)
{
Texture = (Texture);
};
Texture2D DisplacementTexture;
sampler2D DisplacementSampler = sampler_state
{
AddressU = wrap;
AddressV = wrap;
Texture = <DisplacementTexture>;
};
float4 PsRefraction(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// Look up the displacement amount.
float2 displacement = tex2D(DisplacementSampler, DisplacementMotionVector + texCoord * DisplacementIntensity) * 0.2 - 0.15;
// Offset the main texture coordinates.
texCoord += displacement;
// Look up into the main texture.
return tex2D(TextureSampler, texCoord) * color;
}
technique Refraction
{
pass Pass0
{
PixelShader = compile PS_SHADERMODEL PsRefraction(); // ps_2_0 doesn't error either.
}
}
The game1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
namespace RefractionShader
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Effect refractionEffect;
Texture2D tex2dForground;
Texture2D tex2dRefractionTexture;
Texture2D tex2dEgyptianDesert;
Texture2D tex2dpgfkp;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 1200;
graphics.PreferredBackBufferHeight = 700;
Window.AllowUserResizing = true;
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
tex2dEgyptianDesert = Content.Load<Texture2D>("EgyptianDesert");
tex2dpgfkp = Content.Load<Texture2D>("pgfkp");
tex2dForground = tex2dEgyptianDesert;
tex2dRefractionTexture = tex2dpgfkp;
refractionEffect = Content.Load<Effect>("RefractShader");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// Draw the background image.
spriteBatch.Begin();
spriteBatch.Draw(tex2dForground, new Rectangle(0, 0, 300, 150), Color.White);
spriteBatch.Draw(tex2dRefractionTexture, new Rectangle(0, 150, 300, 150), Color.White);
spriteBatch.End();
// similar to the original shown.
Draw2dRefracted(tex2dForground, tex2dRefractionTexture, new Rectangle(300, 0, 300, 150), .05f, (1f/3f) ,gameTime);
// this one has wind instead.
Draw2dRefractedDirectionally(tex2dForground, tex2dRefractionTexture, new Rectangle(600, 0, 300, 150), .05f, (1f / 3f), new Vector2(10,1), gameTime);
base.Draw(gameTime);
}
/// <summary>
/// Draw a refracted texture using the refraction effect.
/// </summary>
/// <param name="texture">the texture to draw that will be effected</param>
/// <param name="refractionTexture">the texture to use for the refraction effect</param>
/// <param name="screenRectangle">the area to draw to on the screen</param>
/// <param name="refractionSpeed">the speed at which the refraction occurs</param>
/// <param name="displacementIntensity">the displacement intensity of the refraction how drastic it is 1/3 was the default.</param>
public void Draw2dRefracted(Texture2D texture, Texture2D refractionTexture, Rectangle screenRectangle, float refractionSpeed, float displacementIntensity, GameTime gameTime)
{
double time = gameTime.TotalGameTime.TotalSeconds * refractionSpeed;
var displacement = new Vector2((float)Math.Cos(time), (float)Math.Sin(time));
// Set an effect parameter to make the displacement texture scroll in a giant circle.
refractionEffect.CurrentTechnique = refractionEffect.Techniques["Refraction"];
refractionEffect.Parameters["DisplacementMotionVector"].SetValue(displacement);
refractionEffect.Parameters["DisplacementIntensity"].SetValue(displacementIntensity);
refractionEffect.Parameters["DisplacementTexture"].SetValue(refractionTexture);
spriteBatch.Begin(0, null, null, null, null, refractionEffect);
spriteBatch.Draw(texture, screenRectangle, Color.White);
spriteBatch.End();
}
/// <summary>
/// Draw a refracted texture using the refraction directional effect.
/// </summary>
/// <param name="wind"> the directionality of the refraction</param>
public void Draw2dRefractedDirectionally(Texture2D texture, Texture2D refractionTexture, Rectangle screenRectangle, float refractionSpeed, float displacementIntensity, Vector2 wind, GameTime gameTime)
{
wind = Vector2.Normalize(wind) * -(float)(gameTime.TotalGameTime.TotalSeconds * refractionSpeed);
var displacement = new Vector2(wind.X, wind.Y); // + screenRectangle.Location.ToVector2();
// Set an effect parameter to make the displacement texture scroll in a giant circle.
refractionEffect.CurrentTechnique = refractionEffect.Techniques["Refraction"];
refractionEffect.Parameters["DisplacementMotionVector"].SetValue(displacement);
refractionEffect.Parameters["DisplacementIntensity"].SetValue(displacementIntensity);
refractionEffect.Parameters["DisplacementTexture"].SetValue(refractionTexture);
spriteBatch.Begin(0, null, null, null, null, refractionEffect);
spriteBatch.Draw(texture, screenRectangle, Color.White);
spriteBatch.End();
}
}
}
actually if you set the other values in load one time displacement speed and stuff all you have to set is the motion. then call spritebatch,Draw
// the other stuff can be set to the effect after you loaded it in load including the refraction texture.
public void Draw2dRefracted(Texture2D texture, Texture2D refractionTexture, Rectangle screenRectangle, float refractionSpeed, float displacementIntensity, GameTime gameTime)
{
double time = gameTime.TotalGameTime.TotalSeconds * refractionSpeed;
var displacement = new Vector2((float)Math.Cos(time), (float)Math.Sin(time));
// might still want to set this if you have other techniques in the shader.
// refractionEffect.CurrentTechnique = refractionEffect.Techniques["Refraction"];
// then this is all that you need to set.
refractionEffect.Parameters["DisplacementMotionVector"].SetValue(displacement);
spriteBatch.Begin(0, null, null, null, null, refractionEffect);
spriteBatch.Draw(texture, screenRectangle, Color.White); // and call it.
spriteBatch.End();
}