Here is refraction shader I've wrote in the last few days. You can use it for example for special windows.

Here's a shot:


Here's the code (copy it first in "MS Word" and then copy it in SED or Notepad):
Code:
//Refraction Shader//////////////////////////////


VIEW refrac_view { layer = 20; } //Second View for Refraction

STARTER refrac_starter //Refrac View has always position of camera view
{
refrac_view.clip_near = 0;
camera.clip_near = 0; //that you can go very near on the refraction entity
refrac_view.visible = on;
proc_late();
while(1)
{
vec_set(refrac_view.x, camera.x);
vec_set(refrac_view.pan, camera.pan);
wait(1);
}
}

FUNCTION render_event_refraction();

MATERIAL mtl_refraction //the material
{
event = render_event_refraction();
flags = enable_view; //this is important

effect=
"
float4x4 matWorldViewProj: register(c0);

texture entSkin1;
texture entSkin2;

float mtlSkill1;
float vecSkill41;

struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 textur: TEXCOORD0;
float3 eye: TEXCOORD1;
};

VS_OUTPUT VS_p0(float4 Pos: POSITION, float2 texcoord0 : TEXCOORD0)
{
VS_OUTPUT Out;

float4 pos = float4(1 * Pos.x, 1 * Pos.y, 1 * Pos.z, 1);
float4 pPos = mul(float4(pos.xyz,1), matWorldViewProj);

Out.Pos = pPos;

Out.textur = texcoord0.xy;

Out.eye.x = 0.5 * (pPos.z + pPos.x);
Out.eye.y = 0.5 * (pPos.z - pPos.y);
Out.eye.z = pPos.z * 1;

return Out;
}

sampler BumpMap = sampler_state
{
texture=(entSkin2);
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
MIPFILTER = LINEAR;
};

sampler RefractionMap = sampler_state
{
texture=(entSkin1);
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
MIPFILTER = LINEAR;
};

float4 PS_p0( float2 texCoord: TEXCOORD0, float3 eye: TEXCOORD1) : COLOR
{
float4 bump = tex2D(BumpMap, texCoord) * 2 - 1;
bump = normalize(bump);
float2 mid = eye.xy / eye.z + bump.xy * vecSkill41;
float4 refraction = tex2D(RefractionMap, mid);

clip(mtlSkill1);
return refraction;
}

technique refraction
{
pass p0
{

VertexShader = compile vs_1_1 VS_p0();
PixelShader = compile ps_2_0 PS_p0();
}
}
";

}

FUNCTION render_event_refraction() //that the refraction entity isn't visible in refrac view
{
if(render_view == camera)
{
mtl.skill1 = float(1);
}
if(render_view == refrac_view)
{
mtl.skill1 = float(-1);
}
}

ACTION ent_refraction
{
my.material = mtl_refraction;
my.skill41 = float(0.05); //bumpness
refrac_view.bmap = bmap_for_entity(my,1);
}



How to use it:
You need an entity with two skins.
  • 1# skin can be any texure (this texture will be overwritten by the refrac view).
  • 2# skin must be a normalmap

Then apply this entity the action "ent_refraction". You can change the value "my.skill41" for more or less bumpness.

Requirements for the shader:
  • Shader 2.0
  • A6.31
  • Pro Edition (for the render-to-textur feature)