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