www.pudn.com > fluid.rar > FluidAnimator2D.fx, change:2006-10-28,size:10044b
#include "util.fxh"
float2 g_texSize; // texture size (width,height)
float g_dx; // 1/width
float g_dy; // 1/height
float g_dt; //time interval
float g_d; // grid length
float g_dis; // dissipation
float g_v; // fluid viscous
float g_vorCoe; // vorticity confinement coefficient
float g_rf_rt=1.0/10.0; //force radius
float2 g_posf_rt; //force position
float2 g_force_rp; //force
texture forceFieldTex;
sampler forceFieldSam = sampler_state
{
texture = <forceFieldTex>;
AddressU =clamp;
AddressV =clamp;
MinFilter =linear;
MipFilter =linear;
MagFilter =linear;
};
texture velFieldTex; //velocity field
sampler velFieldSam = sampler_state
{
texture = <velFieldTex>;
AddressU =clamp;
AddressV =clamp;
MinFilter =linear;
MipFilter =linear;
MagFilter =linear;
};
texture activeVelFieldTex; //velocity field
sampler activeVelFieldSam = sampler_state
{
texture = <activeVelFieldTex>;
AddressU =clamp;
AddressV =clamp;
MinFilter =linear;
MipFilter =linear;
MagFilter =linear;
};
texture scalarFieldTex; //source pressure velocity field
sampler scalarFieldSam = sampler_state
{
texture = <scalarFieldTex>;
AddressU =clamp;
AddressV =clamp;
MinFilter =linear;
MipFilter =linear;
MagFilter =linear;
};
texture activeScalarFieldTex;
sampler activeScalarFieldSam = sampler_state
{
texture = <activeScalarFieldTex>;
AddressU =clamp;
AddressV =clamp;
MinFilter =linear;
MipFilter =linear;
MagFilter =linear;
};
//pos_rp vertex position
inline float2 getExternalForce(
float2 pos_rt,
float rf,
float2 posf_rt,
float2 force_rp)
{
float r;
r= length(pos_rt-posf_rt)/rf;
r=max(0.0,1.0-r);
return r*exp(1.0-r)*force_rp;
}
void addForceTermPS(float2 pos_rt:TEXCOORD,
out float4 oVel:COLOR)
{
float2 force;
//add client force
force = getExternalForce(pos_rt,g_rf_rt,g_posf_rt,g_force_rp);
force +=tex2D(forceFieldSam,pos_rt).xy;
oVel = float4(tex2D(velFieldSam,pos_rt).xy + force*g_dt,
0,1);
//oVel = float4(1.0,1.0,0,1);
//oVel = float4(g_dx,g_dy,0,1);
//oVel = float4(g_dx*50,g_dx*25,0,1);
}
void advectionPS(float2 pos_rt:TEXCOORD,
out float4 oVel:COLOR)
{
//float2 vel =tex2D_bilinear(velFieldSam,pos_rt,g_texSize,g_dx,g_dy).xy;
float2 vel = tex2D(velFieldSam,pos_rt).xy;
float2 dp = -vel*g_dt; //displacement of this vertex
dp = dp /g_d / g_texSize;
dp.y = -dp.y;
float2 pos = pos_rt+dp;
oVel = tex2DRect_bilinear( velFieldSam,pos,g_texSize,float2(g_dx,g_dy));
oVel = g_dis*oVel;
//oVel = float4(vel,0,1);
}
void jacobiPS(float2 pos_rt:TEXCOORD,
out float4 x_:COLOR,
uniform float dx,//texel x size
uniform float dy,//texel y size
uniform float alpha,
uniform float belta,
uniform sampler x,
uniform sampler b)
{
x_= tex2D(x,pos_rt+float2( dx, 0.0))
+tex2D(x,pos_rt+float2(-dx, 0.0))
+tex2D(x,pos_rt+float2(0.0, dy))
+tex2D(x,pos_rt+float2(0.0, -dy))
+alpha*tex2D(b,pos_rt);
x_= x_/belta;
}
void computeDivergencePS(
float2 pos_rt:TEXCOORD,
out float4 oDiv:COLOR,
uniform float dx,
uniform float dy,
uniform float d,//grid step size
uniform sampler u
)
{
// u3
// |
// u0-------u1
// |
// u2
float u0 = tex2D(u,pos_rt+float2(-dx,0.0)).x;
float u1 = tex2D(u,pos_rt+float2( dx,0.0)).x;
float u2 = tex2D(u,pos_rt+float2(0.0, dy)).y;
float u3 = tex2D(u,pos_rt+float2(0.0,-dy)).y;
oDiv = float4(
( (u1-u0)+(u3-u2) )*0.5/d,
0,0,1);
}
void projectPS(float2 pos_rt:TEXCOORD,
out float4 oVel:COLOR)
{
//compute pressure field's gradient
float2 vel;
// p3
// |
// p0-------p1
// |
// p2
float2 gradP;
float p0 = tex2D(scalarFieldSam,pos_rt+float2(-g_dx, 0.0)).x;
float p1 = tex2D(scalarFieldSam,pos_rt+float2( g_dx, 0.0)).x;
float p2 = tex2D(scalarFieldSam,pos_rt+float2( 0.0 , g_dy)).x;
float p3 = tex2D(scalarFieldSam,pos_rt+float2( 0.0 ,-g_dy)).x;
gradP = float2(p1-p0,p3-p2)*0.5/g_d;
oVel = float4(tex2D(velFieldSam,pos_rt) - gradP,
0,1);
}
void velocityBoundaryPS(
float2 pos_ar:VPOS,
out float4 oVel:COLOR0)
{
float2 pos_rt = pos_ar*float2(g_dx,g_dy);
float2 sig = float2(1,1);
float2 dirInner_rt = float2(0,0);
if(pos_ar.x<0.5f)
{
dirInner_rt.x = g_dx;
sig.x = -1;
}
if(pos_ar.x>g_texSize.x-1.5f)
{
dirInner_rt.x = -g_dx;
sig.x = -1;
}
if(pos_ar.y<0.5f)
{
dirInner_rt.y = g_dy;
sig.y = -1;
}
if(pos_ar.y>g_texSize.y-1.5f)
{
dirInner_rt.y = -g_dy;
sig.y = -1;
}
oVel = float4(sig*tex2D(velFieldSam,pos_rt+dirInner_rt).xy,0,1);
}
void pressureBoundaryPS(
float2 pos_ar:VPOS,
out float4 oPre:COLOR0)
{
float2 pos_rt = pos_ar*float2(g_dx,g_dy);
float2 dirInner_rt = float2(0,0);
if(pos_ar.x<0.5f)
{
dirInner_rt.x = g_dx;
}
if(pos_ar.x>g_texSize.x-1.5f)
{
dirInner_rt.x = -g_dx;
}
if(pos_ar.y<0.5f)
{
dirInner_rt.y = g_dy;
}
if(pos_ar.y>g_texSize.y-1.5f)
{
dirInner_rt.y = -g_dy;
}
oPre = float4( tex2D(scalarFieldSam,pos_rt+dirInner_rt).x,
0,0,1);
}
void computeVorticityPS(float2 pos_rt:TEXCOORD,
out float4 oVorticity:COLOR)
{
//u = (P,Q,0)
//vorticity = (0,0,Qx-Py)
float Q0,Q1,Qx;
Q0 = tex2D(velFieldSam,pos_rt+float2(-g_dx,0)).y;
Q1 = tex2D(velFieldSam,pos_rt+float2( g_dx,0)).y;
Qx = (Q1-Q0)*0.5/g_d;
float P0,P1,Py;
P0 = tex2D(velFieldSam,pos_rt+float2(0, g_dy)).x;
P1 = tex2D(velFieldSam,pos_rt+float2(0,-g_dy)).x;
Py = (P1-P0)*0.5/g_d;
oVorticity = float4(Qx-Py,0,0,1);
}
void vorticityConfinementPS(float2 pos_rt:TEXCOORD,
out float4 oF:COLOR)
{
//compute n : ¦Ç=grad(|vorticity|)
float2 n;
n= float2(abs(tex2D(scalarFieldSam,pos_rt+float2( g_dx,0)).x)-
abs(tex2D(scalarFieldSam,pos_rt+float2(-g_dx,0)).x),
abs(tex2D(scalarFieldSam,pos_rt+float2(0,-g_dy)).x)-
abs(tex2D(scalarFieldSam,pos_rt+float2(0, g_dy)).x)
);
float2 fi;
float norm_n = length(n);
if(norm_n == 0)
{
fi = float2(0,0);
}
else
{
fi = n/norm_n;
}
float vor;//vorticity.z
vor = tex2D(scalarFieldSam,pos_rt).x;
//compute vorticity confinement force
oF = float4(g_vorCoe*float2(fi.y,-fi.x)*vor*g_d,
0,1);
//oF = float4(0,0,0,1);
}
technique timeStep
{
pass addForceTerm
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 addForceTermPS();
}
pass advection
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 advectionPS();
}
pass diffuse
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 jacobiPS(g_dx,g_dy,
g_d*g_d/g_v/g_dt,//alpha
g_d*g_d/g_v/g_dt+4.0,//belta
activeVelFieldSam,
velFieldSam
);
}
pass computeDivergence
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 computeDivergencePS(g_dx,g_dy,
g_d,
velFieldSam);
}
pass computePressure
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 jacobiPS(g_dx,g_dy,
-g_d*g_d,//alpha
4.0,//belta
activeScalarFieldSam,
scalarFieldSam
);
}
pass project
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 projectPS();
}
pass velocityBoundary
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 velocityBoundaryPS();
}
pass pressureBoundary
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 pressureBoundaryPS();
}
pass computeVorticity
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 computeVorticityPS();
}
pass computeVorticityConfinement
{
cullmode = none;
ZEnable = false;
VertexShader = compile vs_3_0 screenAlignedQuadFVS();
PixelShader = compile ps_3_0 vorticityConfinementPS();
}
}