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(); 
    }     
}