水波特效

shader + 多个渲染目标, 这个例子可以把接触点的圆形换成任意模型,这样水波就会沿着模型边缘线产生,形成一个模型形状的水波更逼真.

完整源代码下载http://download.csdn.net/detail/a5326262/4589944 不知道如何在博客园 上传只好传到CSDN上

Shader代码:

   1:  
   2:  
   3: struct VS_INPUT
   4: {
   5:     float3 Position : POSITION;
   6:     float2 Texcoord : TEXCOORD;
   7: };
   8:  
   9: struct VS_OUTPUT
  10: {
  11:     float4 Position : SV_POSITION;
  12:     float2 Texcoord : TEXCOORD0;
  13: };
  14: //是否提高精度
  15: bool bHighPrecision = false;
  16:  
  17: texture heightmap_prev;
  18:  
  19: sampler2D HeightPrevSampler = sampler_state
  20: {
  21:     Texture = <heightmap_prev>;//Linear
  22:     MinFilter = Point;
  23:     MagFilter = Point;
  24:     MipFilter = Point;   
  25:     AddressU  = Clamp;
  26:     AddressV  = Clamp;
  27: };
  28:  
  29: texture heightmap_current;
  30:  
  31: sampler2D HeightCurrentSampler = sampler_state
  32: {
  33:     Texture = <heightmap_current>;
  34:     MinFilter = Point;
  35:     MagFilter = Point;
  36:     MipFilter = Point;   
  37:     AddressU  = Clamp;
  38:     AddressV  = Clamp;
  39: };
  40:  
  41: //
  42: // Pass through vertex shader
  43: //
  44: VS_OUTPUT VS_Passthrough(VS_INPUT In)
  45: {
  46:     VS_OUTPUT Out;
  47:     
  48:     Out.Position = float4(In.Position, 1.0f);
  49:     Out.Texcoord = In.Texcoord;
  50:  
  51:     return Out;
  52: }
  53:  
  54: float4x4 wvp_matrix;
  55: //
  56: // Vertex Shader
  57: //
  58: VS_OUTPUT VS(VS_INPUT In)
  59: {
  60:     VS_OUTPUT Out;
  61:     
  62:     Out.Position = mul(float4(In.Position, 1.0f), wvp_matrix);
  63:     Out.Texcoord = In.Texcoord;
  64:  
  65:     return Out;
  66: }
  67:  
  68: // 
  69: float4 EncodeHeightmap(float fHeight)
  70: {
  71:     float h = fHeight;
  72:     float positive = fHeight > 0 ? fHeight : 0;
  73:     float negative = fHeight < 0 ? -fHeight : 0;
  74:  
  75:     float4 color = 0;
  76:  
  77:     
  78:     color.r = positive;
  79:     color.g = negative;
  80:     
  81:     if ( bHighPrecision )
  82:     {
  83:     
  84:         color.ba = frac(color.rg*256);
  85:     
  86:         color.rg -= color.ba/256.0f;
  87:     }
  88:     
  89:     return color;
  90: }
  91:  
  92:  
  93: float DecodeHeightmap(float4 heightmap)
  94: {
  95:     float4 table;
  96:  
  97:     if ( bHighPrecision )
  98:         table = float4(1.0f, -1.0f, 1.0f/256.0f, -1.0f/256.0f);
  99:     else
 100:         table = float4(1.0f, -1.0f, 0.0f, 0.0f);
 101:     
 102:     return dot(heightmap, table);
 103: }
 104:  
 105: float DecodeHeightmap(sampler2D HeightmapSampler, float2 texcoord)
 106: {
 107:     float4 heightmap = tex2D(HeightmapSampler, texcoord);
 108:     return DecodeHeightmap(heightmap);
 109: }
 110:  
 111: float4 texture_size;
 112: float  fDamping;
 113: //
 114: // Pixel Shader
 115: //
 116: float4 PS_Simulate(VS_OUTPUT In) : COLOR
 117: {
 118:     float3 offset[4] =
 119:     {
 120:         float3(-1.0f, 0.0f, 0.25f),
 121:         float3( 1.0f, 0.0f, 0.25f),
 122:         float3( 0.0f,-1.0f, 0.25f),
 123:         float3( 0.0f, 1.0f, 0.25f),
 124:     };    
 125:  
 127:     // float4(1.0f, -1.0f, 1.0f/256.0f, -1.0f/256.0f);
 128:     float fHeightPrev = DecodeHeightmap(HeightPrevSampler, In.Texcoord);
 129:     
 130:  
 131:     float fNeighCurrent = 0;
 132:     for ( int i=0; i<4; i++ )
 133:     {
 134:         float2 texcoord = In.Texcoord + offset[i].xy * texture_size.xy;
 135:         fNeighCurrent += (DecodeHeightmap(HeightCurrentSampler, texcoord) * offset[i].z);
 136:     }
 137:  
 138:     float fHeight = fNeighCurrent * 2.0f - fHeightPrev;
 139:     fHeight *= fDamping;
 140:     float4 color = EncodeHeightmap(fHeight);
 141:             
 142:     return color;
 143: }
 144:  
 145: float fNormalScale;
 146:  
 147: float4 PS_Normal(VS_OUTPUT In) : COLOR
 148: {
 149:     float2 offset[4] =
 150:     {
 151:         float2(-1.0f, 0.0f),
 152:         float2( 1.0f, 0.0f),
 153:         float2( 0.0f,-1.0f),
 154:         float2( 0.0f, 1.0f),
 155:     };    
 156:  
 157:     float fHeightL = DecodeHeightmap(HeightCurrentSampler, In.Texcoord + offset[0]*texture_size.xy);
 158:     float fHeightR = DecodeHeightmap(HeightCurrentSampler, In.Texcoord + offset[1]*texture_size.xy);
 159:     float fHeightT = DecodeHeightmap(HeightCurrentSampler, In.Texcoord + offset[2]*texture_size.xy);
 160:     float fHeightB = DecodeHeightmap(HeightCurrentSampler, In.Texcoord + offset[3]*texture_size.xy);
 161:     
 162:     float3 n = float3(fHeightR - fHeightL,fHeightB - fHeightT,fNormalScale);
 163:     float3 normal = (n + 1.0f) * 0.5f;
 164:     
 165:     return float4(normal.rgb, 1.0f);
 166: }
 167:  
 168: float4 PS_Heightmap(VS_OUTPUT In) : COLOR
 169: {
 170:     float height = DecodeHeightmap(HeightCurrentSampler, In.Texcoord);
 171:     return (height + 1.0f) * 0.5f;
 172: }
 173:  
 174:  
 175: float fForce;
 176:  
 177: float4 PS_Impulse(VS_OUTPUT In) : COLOR
 178: {
 179:     float4 color = EncodeHeightmap(fForce);
 180:     return color;
 181: }
 182:  
 183:  
 184: texture NormalmapTex;
 185:  
 186: sampler2D NormalmapSampler = sampler_state
 187: {
 188:     Texture = <NormalmapTex>;
 189:     MinFilter = Linear;
 190:     MagFilter = Linear;
 191:     MipFilter = Linear;   
 192:     AddressU  = Clamp;
 193:     AddressV  = Clamp;
 194: };
 195:  
 196: texture WaterTex;
 197:  
 198: sampler2D WaterSampler = sampler_state
 199: {
 200:     Texture = <WaterTex>;
 201:     MinFilter = Linear;
 202:     MagFilter = Linear;
 203:     MipFilter = Linear;   
 204:     AddressU  = Clamp;
 205:     AddressV  = Clamp;
 206: };
 207:  
 208: float fTexcoordScale;
 209:  
 210: float4 PS_Water(VS_OUTPUT In) : COLOR
 211: {
 212:     float4 normalmap = tex2D(NormalmapSampler, In.Texcoord);
 213:     float3 normal = (normalmap.rgb - 0.5f) * 2.0f;
 214:     float2 texcoord = In.Texcoord + normal.xy * fTexcoordScale;
 215:     float4 color = tex2D(WaterSampler, texcoord);
 216:     
 217:     return color;
 218: }
 219:  
 220: // 1.渲染物体
 221: technique AddImpulse
 222: {
 223:     pass p0 
 224:     {
 225:         //VertexShader = compile vs_2_0 VS();
 226:         PixelShader = compile ps_2_0 PS_Impulse();
 227:  
 228:         AlphaBlendEnable = TRUE;
 229:         AlphaTestEnable = FALSE;
 230:         SrcBlend = ONE;
 231:         DestBlend = ONE;
 232:         ZEnable = FALSE;
 233:         CULLMODE = NONE;
 234:     }
 235: }
 236:  
 237: // 2.下一帧的高度
 238: technique WaterSimulation
 239: {
 240:     pass p0 
 241:     {
 242:         //VertexShader = compile vs_2_0 VS_Passthrough();
 243:         PixelShader = compile ps_2_0 PS_Simulate();
 244:  
 245:         AlphaBlendEnable = FALSE;
 246:         AlphaTestEnable = FALSE;
 247:         ZEnable = FALSE;
 248:         CULLMODE = NONE;
 249:     }
 250: }
 251: // 3. 计算发现
 252: technique ConvertNormal
 253: {
 254:     pass p0 
 255:     {
 256:         //VertexShader = compile vs_2_0 VS_Passthrough();
 257:         PixelShader = compile ps_2_0 PS_Normal();
 258:  
 259:         AlphaBlendEnable = FALSE;
 260:         AlphaTestEnable = FALSE;
 261:         ZEnable = FALSE;
 262:         CULLMODE = NONE;
 263:     }
 264: }
 265:  
 266: technique Heightmap
 267: {
 268:     pass p0 
 269:     {
 270:         //VertexShader = compile vs_2_0 VS_Passthrough();
 271:         PixelShader = compile ps_2_0 PS_Heightmap();
 272:  
 273:         AlphaBlendEnable = FALSE;
 274:         AlphaTestEnable = FALSE;
 275:         ZEnable = FALSE;
 276:         CULLMODE = NONE;
 277:     }
 278: }
 279: // 4. 画背景
 280: technique Water
 281: {
 282:     pass p0 
 283:     {
 284:         //VertexShader = compile vs_2_0 VS_Passthrough();
 285:         PixelShader = compile ps_2_0 PS_Water();
 286:  
 287:         AlphaBlendEnable = FALSE;
 288:         AlphaTestEnable = FALSE;
 289:         ZEnable = FALSE;
 290:         CULLMODE = NONE;
 291:     }
 292: }

效果图1小半径圆形                   效果图2大半径圆形

未命名未命名

原文地址:https://www.cnblogs.com/ThreeThousandBigWorld/p/2701548.html