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大半径圆形



浙公网安备 33010602011771号