1// We store vertex coordinates and the quad shape in a constant buffer, this is
2// easy to update and allows us to use a single call to set the x, y, w, h of
3// the quad.
4// The QuadDesc and TexCoords both work as follows:
5// The x component is the quad left point, the y component is the top point
6// the z component is the width, and the w component is the height. The quad
7// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
8// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
9// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
10// space <0, 1.0f> left to right and top to bottom. The input vertices of the
11// shader stage always form a rectangle from {0, 0} - {1, 1}
12cbuffer cb0
13{
14    float4 QuadDesc;
15    float4 TexCoords;
16    float4 MaskTexCoords;
17    float4 TextColor;
18}
19
20cbuffer cb1
21{
22    float4 BlurOffsetsH[3];
23    float4 BlurOffsetsV[3];
24    float4 BlurWeights[3];
25    float4 ShadowColor;
26}
27
28cbuffer cb2
29{
30    float3x3 DeviceSpaceToUserSpace;
31    float2 dimensions;
32    // Precalculate as much as we can!
33    float3 diff;
34    float2 center1;
35    float A;
36    float radius1;
37    float sq_radius1;
38}
39
40cbuffer cb3
41{
42    float3x3 DeviceSpaceToUserSpace_cb3;
43    float2 dimensions_cb3;
44    float2 center;
45    float angle;
46    float start_offset;
47    float end_offset;
48}
49
50struct VS_OUTPUT
51{
52    float4 Position : SV_Position;
53    float2 TexCoord : TEXCOORD0;
54    float2 MaskTexCoord : TEXCOORD1;
55};
56
57struct VS_RADIAL_OUTPUT
58{
59    float4 Position : SV_Position;
60    float2 MaskTexCoord : TEXCOORD0;
61    float2 PixelCoord : TEXCOORD1;
62};
63
64struct VS_CONIC_OUTPUT
65{
66    float4 Position : SV_Position;
67    float2 MaskTexCoord : TEXCOORD0;
68    float2 PixelCoord : TEXCOORD1;
69};
70
71struct PS_TEXT_OUTPUT
72{
73    float4 color;
74    float4 alpha;
75};
76
77Texture2D tex;
78Texture2D bcktex;
79Texture2D mask;
80uint blendop;
81
82sampler sSampler = sampler_state {
83    Filter = MIN_MAG_MIP_LINEAR;
84    Texture = tex;
85    AddressU = Clamp;
86    AddressV = Clamp;
87};
88
89sampler sBckSampler = sampler_state {
90    Filter = MIN_MAG_MIP_LINEAR;
91    Texture = bcktex;
92    AddressU = Clamp;
93    AddressV = Clamp;
94};
95
96sampler sWrapSampler = sampler_state {
97    Filter = MIN_MAG_MIP_LINEAR;
98    Texture = tex;
99    AddressU = Wrap;
100    AddressV = Wrap;
101};
102
103sampler sMirrorSampler = sampler_state {
104    Filter = MIN_MAG_MIP_LINEAR;
105    Texture = tex;
106    AddressU = Mirror;
107    AddressV = Mirror;
108};
109
110sampler sMaskSampler = sampler_state {
111    Filter = MIN_MAG_MIP_LINEAR;
112    Texture = mask;
113    AddressU = Clamp;
114    AddressV = Clamp;
115};
116
117sampler sShadowSampler = sampler_state {
118    Filter = MIN_MAG_MIP_LINEAR;
119    Texture = tex;
120    AddressU = Border;
121    AddressV = Border;
122    BorderColor = float4(0, 0, 0, 0);
123};
124
125RasterizerState TextureRast
126{
127  ScissorEnable = True;
128  CullMode = None;
129};
130
131BlendState ShadowBlendH
132{
133  BlendEnable[0] = False;
134  RenderTargetWriteMask[0] = 0xF;
135};
136
137BlendState ShadowBlendV
138{
139  BlendEnable[0] = True;
140  SrcBlend = One;
141  DestBlend = Inv_Src_Alpha;
142  BlendOp = Add;
143  SrcBlendAlpha = One;
144  DestBlendAlpha = Inv_Src_Alpha;
145  BlendOpAlpha = Add;
146  RenderTargetWriteMask[0] = 0xF;
147};
148
149BlendState bTextBlend
150{
151  AlphaToCoverageEnable = FALSE;
152  BlendEnable[0] = TRUE;
153  SrcBlend = Src1_Color;
154  DestBlend = Inv_Src1_Color;
155  BlendOp = Add;
156  SrcBlendAlpha = Src1_Alpha;
157  DestBlendAlpha = Inv_Src1_Alpha;
158  BlendOpAlpha = Add;
159  RenderTargetWriteMask[0] = 0x0F; // All
160};
161
162VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
163{
164    VS_OUTPUT Output;
165    Output.Position.w = 1.0f;
166    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
167    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
168    Output.Position.z = 0;
169    Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
170    Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
171    Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
172    Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;
173    return Output;
174}
175
176VS_RADIAL_OUTPUT SampleRadialVS(float3 pos : POSITION)
177{
178    VS_RADIAL_OUTPUT Output;
179    Output.Position.w = 1.0f;
180    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
181    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
182    Output.Position.z = 0;
183    Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
184    Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;
185
186    // For the radial gradient pixel shader we need to pass in the pixel's
187    // coordinates in user space for the color to be correctly determined.
188
189    Output.PixelCoord.x = ((Output.Position.x + 1.0f) / 2.0f) * dimensions.x;
190    Output.PixelCoord.y = ((1.0f - Output.Position.y) / 2.0f) * dimensions.y;
191    Output.PixelCoord.xy = mul(float3(Output.PixelCoord.x, Output.PixelCoord.y, 1.0f), DeviceSpaceToUserSpace).xy;
192    return Output;
193}
194
195VS_CONIC_OUTPUT SampleConicVS(float3 pos : POSITION)
196{
197    VS_CONIC_OUTPUT Output;
198    Output.Position.w = 1.0f;
199    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
200    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
201    Output.Position.z = 0;
202    Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
203    Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;
204
205    // For the conic gradient pixel shader we need to pass in the pixel's
206    // coordinates in user space for the color to be correctly determined.
207
208    Output.PixelCoord.x = ((Output.Position.x + 1.0f) / 2.0f) * dimensions_cb3.x;
209    Output.PixelCoord.y = ((1.0f - Output.Position.y) / 2.0f) * dimensions_cb3.y;
210    Output.PixelCoord.xy = mul(float3(Output.PixelCoord.x, Output.PixelCoord.y, 1.0f), DeviceSpaceToUserSpace_cb3).xy;
211    return Output;
212}
213
214float Screen(float a, float b)
215{
216  return 1 - ((1 - a)*(1 - b));
217}
218
219static float RedLuminance = 0.3f;
220static float GreenLuminance = 0.59f;
221static float BlueLuminance = 0.11f;
222
223float Lum(float3 C)
224{
225  return RedLuminance * C.r + GreenLuminance * C.g + BlueLuminance * C.b;
226}
227
228float3 ClipColor(float3 C)
229{
230  float L = Lum(C);
231  float n = min(min(C.r, C.g), C.b);
232  float x = max(max(C.r, C.g), C.b);
233
234  if(n < 0)
235    C = L + (((C - L) * L) / (L - n));
236
237  if(x > 1)
238    C = L + ((C - L) * (1 - L) / (x - L));
239
240  return C;
241}
242
243float3 SetLum(float3 C, float l)
244{
245  float d = l - Lum(C);
246  C = C + d;
247  return ClipColor(C);
248}
249
250float Sat(float3 C)
251{
252  return max(C.r, max(C.g, C.b)) - min(C.r, min(C.g, C.b));
253}
254
255void SetSatComponents(inout float minComp, inout float midComp, inout float maxComp, in float satVal)
256{
257  midComp -= minComp;
258  maxComp -= minComp;
259  minComp = 0.0;
260  if (maxComp > 0.0)
261  {
262    midComp *= satVal/maxComp;
263    maxComp = satVal;
264  }
265}
266
267float3 SetSat(float3 color, in float satVal)
268{
269  if (color.x <= color.y) {
270    if (color.y <= color.z) {
271      // x <= y <= z
272      SetSatComponents(color.x, color.y, color.z, satVal);
273    }
274    else {
275      if (color.x <= color.z) {
276        // x <= z <= y
277        SetSatComponents(color.x, color.z, color.y, satVal);
278      }
279      else {
280        // z <= x <= y
281        SetSatComponents(color.z, color.x, color.y, satVal);
282      }
283    }
284  }
285  else {
286    if (color.x <= color.z) {
287      // y <= x <= z
288      SetSatComponents(color.y, color.x, color.z, satVal);
289    }
290    else {
291      if (color.y <= color.z) {
292        // y <= z <= x
293        SetSatComponents(color.y, color.z, color.x, satVal);
294      }
295      else {
296        // z <= y <= x
297        SetSatComponents(color.z, color.y, color.x, satVal);
298      }
299    }
300  }
301
302  return color;
303}
304
305float4 SampleBlendTextureSeparablePS_1( VS_OUTPUT In) : SV_Target
306{
307  float4 output = tex.Sample(sSampler, In.TexCoord);
308  float4 background = bcktex.Sample(sBckSampler, In.TexCoord);
309  if((output.a == 0) || (background.a == 0))
310	return output;
311
312  output.rgb /= output.a;
313  background.rgb /= background.a;
314
315  float4 retval = output;
316
317  if(blendop == 1) { // multiply
318      retval.rgb = output.rgb * background.rgb;
319  } else if(blendop == 2) {
320      retval.rgb = output.rgb + background.rgb - output.rgb * background.rgb;
321  } else if(blendop == 3) {
322    if(background.r <= 0.5)
323      retval.r  = 2*background.r * output.r;
324    else
325      retval.r  = Screen(output.r, 2 * background.r - 1);
326    if(background.g <= 0.5)
327      retval.g  = 2 * background.g * output.g;
328    else
329      retval.g  = Screen(output.g, 2 * background.g - 1);
330    if(background.b <= 0.5)
331      retval.b  = 2 * background.b * output.b;
332    else
333      retval.b  = Screen(output.b, 2 * background.b - 1);
334  } else if(blendop == 4) {
335      retval.rgb = min(output.rgb, background.rgb);
336  } else if(blendop == 5) {
337    retval.rgb = max(output.rgb, background.rgb);
338  } else {
339    if(background.r == 0)
340	  retval.r = 0;
341	else
342    if(output.r == 1)
343	  retval.r = 1;
344    else
345      retval.r = min(1, background.r / (1 - output.r));
346    if(background.g == 0)
347	  retval.g = 0;
348	else
349    if(output.g == 1)
350	  retval.g = 1;
351    else
352      retval.g = min(1, background.g / (1 - output.g));
353    if(background.b == 0)
354	  retval.b = 0;
355	else
356    if(output.b == 1)
357	  retval.b = 1;
358    else
359      retval.b = min(1, background.b / (1 - output.b));
360  }
361
362  output.rgb = ((1 - background.a) * output.rgb + background.a * retval.rgb) * output.a;
363  return output;
364}
365
366float4 SampleBlendTextureSeparablePS_2( VS_OUTPUT In) : SV_Target
367{
368  float4 output = tex.Sample(sSampler, In.TexCoord);
369  float4 background = bcktex.Sample(sBckSampler, In.TexCoord);
370  if((output.a == 0) || (background.a == 0))
371	return output;
372
373  output.rgb /= output.a;
374  background.rgb /= background.a;
375
376  float4 retval = output;
377
378  if(blendop == 7) {
379    if(background.r == 1)
380	  retval.r = 1;
381	else
382    if(output.r == 0)
383	  retval.r = 0;
384    else
385      retval.r = 1 - min(1, (1 - background.r) / output.r);
386    if(background.g == 1)
387	  retval.g = 1;
388	else
389    if(output.g == 0)
390	  retval.g = 0;
391    else
392      retval.g = 1 - min(1, (1 - background.g) / output.g);
393    if(background.b == 1)
394	  retval.b = 1;
395	else
396    if(output.b == 0)
397	  retval.b = 0;
398    else
399      retval.b = 1 - min(1, (1 - background.b) / output.b);
400  } else if(blendop == 8) {
401    if(output.r <= 0.5)
402      retval.r = 2 * output.r * background.r;
403	else
404      retval.r = Screen(background.r, 2 * output.r -1);
405    if(output.g <= 0.5)
406      retval.g = 2 * output.g * background.g;
407    else
408      retval.g = Screen(background.g, 2 * output.g -1);
409    if(output.b <= 0.5)
410      retval.b = 2 * output.b * background.b;
411    else
412      retval.b = Screen(background.b, 2 * output.b -1);
413  } else if(blendop == 9){
414    float D;
415    if(background.r <= 0.25)
416      D = ((16 * background.r - 12) * background.r + 4) * background.r;
417    else
418      D = sqrt(background.r);
419    if(output.r <= 0.5)
420      retval.r = background.r - (1 - 2 * output.r) * background.r * (1 - background.r);
421    else
422      retval.r = background.r + (2 * output.r - 1) * (D - background.r);
423
424    if(background.g <= 0.25)
425      D = ((16 * background.g - 12) * background.g + 4) * background.g;
426    else
427      D = sqrt(background.g);
428    if(output.g <= 0.5)
429      retval.g = background.g - (1 - 2 * output.g) * background.g * (1 - background.g);
430    else
431      retval.g = background.g + (2 * output.g - 1) * (D - background.g);
432
433    if(background.b <= 0.25)
434      D = ((16 * background.b - 12) * background.b + 4) * background.b;
435    else
436      D = sqrt(background.b);
437
438    if(output.b <= 0.5)
439      retval.b = background.b - (1 - 2 * output.b) * background.b * (1 - background.b);
440    else
441      retval.b = background.b + (2 * output.b - 1) * (D - background.b);
442  } else if(blendop == 10) {
443    retval.rgb = abs(output.rgb - background.rgb);
444  } else {
445    retval.rgb = output.rgb + background.rgb - 2 * output.rgb * background.rgb;
446  }
447
448  output.rgb = ((1 - background.a) * output.rgb + background.a * retval.rgb) * output.a;
449  return output;
450}
451
452float4 SampleBlendTextureNonSeparablePS( VS_OUTPUT In) : SV_Target
453{
454  float4 output = tex.Sample(sSampler, In.TexCoord);
455  float4 background = bcktex.Sample(sBckSampler, In.TexCoord);
456  if((output.a == 0) || (background.a == 0))
457	return output;
458
459  output.rgb /= output.a;
460  background.rgb /= background.a;
461
462  float4 retval = output;
463
464  if(blendop == 12) {
465    retval.rgb = SetLum(SetSat(output.rgb, Sat(background.rgb)), Lum(background.rgb));
466  } else if(blendop == 13) {
467    retval.rgb = SetLum(SetSat(background.rgb, Sat(output.rgb)), Lum(background.rgb));
468  } else if(blendop == 14) {
469    retval.rgb = SetLum(output.rgb, Lum(background.rgb));
470  } else {
471    retval.rgb = SetLum(background.rgb, Lum(output.rgb));
472  }
473
474  output.rgb = ((1 - background.a) * output.rgb + background.a * retval.rgb) * output.a;
475  return output;
476}
477
478
479float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
480{
481  return tex.Sample(sSampler, In.TexCoord);
482}
483
484float4 SampleMaskTexturePS( VS_OUTPUT In) : SV_Target
485{
486    return tex.Sample(sSampler, In.TexCoord) * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
487}
488
489float4 SampleRadialGradientPS(VS_RADIAL_OUTPUT In, uniform sampler aSampler) : SV_Target
490{
491    // Radial gradient painting is defined as the set of circles whose centers
492    // are described by C(t) = (C2 - C1) * t + C1; with radii
493    // R(t) = (R2 - R1) * t + R1; for R(t) > 0. This shader solves the
494    // quadratic equation that arises when calculating t for pixel (x, y).
495    //
496    // A more extensive derrivation can be found in the pixman radial gradient
497    // code.
498
499    float2 p = In.PixelCoord;
500    float3 dp = float3(p - center1, radius1);
501
502    // dpx * dcx + dpy * dcy + r * dr
503    float B = dot(dp, diff);
504
505    float C = pow(dp.x, 2) + pow(dp.y, 2) - sq_radius1;
506
507    float det = pow(B, 2) - A * C;
508
509    if (det < 0) {
510      return float4(0, 0, 0, 0);
511    }
512
513    float sqrt_det = sqrt(abs(det));
514
515    float2 t = (B + float2(sqrt_det, -sqrt_det)) / A;
516
517    float2 isValid = step(float2(-radius1, -radius1), t * diff.z);
518
519    if (max(isValid.x, isValid.y) <= 0) {
520      return float4(0, 0, 0, 0);
521    }
522
523    float upper_t = lerp(t.y, t.x, isValid.x);
524
525    float4 output = tex.Sample(aSampler, float2(upper_t, 0.5));
526    // Premultiply
527    output.rgb *= output.a;
528    // Multiply the output color by the input mask for the operation.
529    output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
530    return output;
531};
532
533float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In, uniform sampler aSampler ) : SV_Target
534{
535    // This simpler shader is used for the degenerate case where A is 0,
536    // i.e. we're actually solving a linear equation.
537
538    float2 p = In.PixelCoord;
539    float3 dp = float3(p - center1, radius1);
540
541    // dpx * dcx + dpy * dcy + r * dr
542    float B = dot(dp, diff);
543
544    float C = pow(dp.x, 2) + pow(dp.y, 2) - pow(radius1, 2);
545
546    float t = 0.5 * C / B;
547
548    if (-radius1 >= t * diff.z) {
549      return float4(0, 0, 0, 0);
550    }
551
552    float4 output = tex.Sample(aSampler, float2(t, 0.5));
553    // Premultiply
554    output.rgb *= output.a;
555    // Multiply the output color by the input mask for the operation.
556    output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
557    return output;
558};
559
560float4 SampleConicGradientPS(VS_CONIC_OUTPUT In, uniform sampler aSampler) : SV_Target
561{
562    float2 current_dir = In.PixelCoord - center;
563    float current_angle = atan2(current_dir.y, current_dir.x) + (3.141592 / 2.0 - angle);
564    float offset = fmod(current_angle / (2.0 * 3.141592), 1.0) - start_offset;
565    offset = offset / (end_offset - start_offset);
566
567    float upper_t = lerp(0, 1, offset);
568
569    float4 output = tex.Sample(aSampler, float2(upper_t, 0.5));
570    // Premultiply
571    output.rgb *= output.a;
572    // Multiply the output color by the input mask for the operation.
573    output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
574    return output;
575};
576
577float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
578{
579    float outputStrength = 0;
580
581    outputStrength += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].x, In.TexCoord.y)).a;
582    outputStrength += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].y, In.TexCoord.y)).a;
583    outputStrength += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].z, In.TexCoord.y)).a;
584    outputStrength += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].w, In.TexCoord.y)).a;
585    outputStrength += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].x, In.TexCoord.y)).a;
586    outputStrength += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].y, In.TexCoord.y)).a;
587    outputStrength += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].z, In.TexCoord.y)).a;
588    outputStrength += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].w, In.TexCoord.y)).a;
589    outputStrength += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[2].x, In.TexCoord.y)).a;
590
591    return ShadowColor * outputStrength;
592};
593
594float4 SampleShadowVPS( VS_OUTPUT In) : SV_Target
595{
596    float4 outputColor = float4(0, 0, 0, 0);
597
598    outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
599    outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
600    outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
601    outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
602    outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
603    outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
604    outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
605    outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
606    outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));
607
608    return outputColor;
609};
610
611float4 SampleMaskShadowVPS( VS_OUTPUT In) : SV_Target
612{
613    float4 outputColor = float4(0, 0, 0, 0);
614
615    outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
616    outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
617    outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
618    outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
619    outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
620    outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
621    outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
622    outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
623    outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));
624
625    return outputColor * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
626};
627
628PS_TEXT_OUTPUT SampleTextTexturePS( VS_OUTPUT In) : SV_Target
629{
630    PS_TEXT_OUTPUT output;
631    output.color = float4(TextColor.r, TextColor.g, TextColor.b, 1.0);
632    output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a;
633    return output;
634};
635
636PS_TEXT_OUTPUT SampleTextTexturePSMasked( VS_OUTPUT In) : SV_Target
637{
638    PS_TEXT_OUTPUT output;
639
640    float maskValue = mask.Sample(sMaskSampler, In.MaskTexCoord).a;
641
642    output.color = float4(TextColor.r, TextColor.g, TextColor.b, 1.0);
643    output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a * maskValue;
644
645    return output;
646};
647
648technique10 SampleTexture
649{
650    pass P0
651    {
652        SetRasterizerState(TextureRast);
653        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
654        SetGeometryShader(NULL);
655        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
656    }
657}
658
659technique10 SampleTextureForSeparableBlending_1
660{
661    pass P0
662    {
663        SetRasterizerState(TextureRast);
664        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
665        SetGeometryShader(NULL);
666        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleBlendTextureSeparablePS_1()));
667    }
668}
669
670technique10 SampleTextureForSeparableBlending_2
671{
672    pass P0
673    {
674        SetRasterizerState(TextureRast);
675        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
676        SetGeometryShader(NULL);
677        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleBlendTextureSeparablePS_2()));
678    }
679}
680
681technique10 SampleTextureForNonSeparableBlending
682{
683    pass P0
684    {
685        SetRasterizerState(TextureRast);
686        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
687        SetGeometryShader(NULL);
688        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleBlendTextureNonSeparablePS()));
689    }
690}
691
692technique10 SampleRadialGradient
693{
694    pass APos
695    {
696        SetRasterizerState(TextureRast);
697        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
698        SetGeometryShader(NULL);
699        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sSampler )));
700    }
701    pass A0
702    {
703        SetRasterizerState(TextureRast);
704        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
705        SetGeometryShader(NULL);
706        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sSampler )));
707    }
708    pass APosWrap
709    {
710        SetRasterizerState(TextureRast);
711        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
712        SetGeometryShader(NULL);
713        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sWrapSampler )));
714    }
715    pass A0Wrap
716    {
717        SetRasterizerState(TextureRast);
718        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
719        SetGeometryShader(NULL);
720        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sWrapSampler )));
721    }
722    pass APosMirror
723    {
724        SetRasterizerState(TextureRast);
725        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
726        SetGeometryShader(NULL);
727        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sMirrorSampler )));
728    }
729    pass A0Mirror
730    {
731        SetRasterizerState(TextureRast);
732        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
733        SetGeometryShader(NULL);
734        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sMirrorSampler )));
735    }
736}
737
738technique10 SampleConicGradient
739{
740    pass APos
741    {
742        SetRasterizerState(TextureRast);
743        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleConicVS()));
744        SetGeometryShader(NULL);
745        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleConicGradientPS( sSampler )));
746    }
747    pass APosWrap
748    {
749        SetRasterizerState(TextureRast);
750        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleConicVS()));
751        SetGeometryShader(NULL);
752        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleConicGradientPS( sWrapSampler )));
753    }
754    pass APosMirror
755    {
756        SetRasterizerState(TextureRast);
757        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleConicVS()));
758        SetGeometryShader(NULL);
759        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleConicGradientPS( sMirrorSampler )));
760    }
761}
762
763technique10 SampleMaskedTexture
764{
765    pass P0
766    {
767        SetRasterizerState(TextureRast);
768        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
769        SetGeometryShader(NULL);
770        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskTexturePS()));
771    }
772}
773
774technique10 SampleTextureWithShadow
775{
776    // Horizontal pass
777    pass P0
778    {
779        SetRasterizerState(TextureRast);
780        SetBlendState(ShadowBlendH, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
781        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
782        SetGeometryShader(NULL);
783        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowHPS()));
784    }
785    // Vertical pass
786    pass P1
787    {
788        SetRasterizerState(TextureRast);
789        SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
790        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
791        SetGeometryShader(NULL);
792        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowVPS()));
793    }
794    // Vertical pass - used when using a mask
795    pass P2
796    {
797        SetRasterizerState(TextureRast);
798        SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
799        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
800        SetGeometryShader(NULL);
801        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskShadowVPS()));
802    }
803}
804
805technique10 SampleTextTexture
806{
807    pass Unmasked
808    {
809        SetRasterizerState(TextureRast);
810        SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
811        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
812        SetGeometryShader(NULL);
813        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePS()));
814    }
815    pass Masked
816    {
817        SetRasterizerState(TextureRast);
818        SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
819        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
820        SetGeometryShader(NULL);
821        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePSMasked()));
822    }
823}
824
825