Jump to content
  • Advertisement
Sign in to follow this  
greenpig83

[Dx9] How to use Fragment Shader (XBR filter)

This topic is 2135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm new to Shader and HLSL. I'm working with sprite and Zooming with Linear (SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);) 

get very bad result, it's blurry and darken! After search a while I found out that XBR 2x filter is so good for sprite zooming (Although it work only well with 2x). I think we can use it to zoom to 2x then scale back to where we want (because zoom out work very well). Search awhile and I found some code but it's not in vertex shader -> pixel shader format that I used to work it. So I have trouble to load it in my code and test !

The code is like this :

 

const static float coef           = 2.0;
const static half3 yuv_weighted  = half3(14.352, 28.176, 5.472);
 
 
float4 df(float4 A, float4 B)
{
  return float4(abs(A.x-B.x), abs(A.y-B.y), abs(A.z-B.z), abs(A.w-B.w));
}
 
 
float4 weighted_distance(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h)
{
  return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
}
 
 
struct input
{
  half2 video_size;
  float2 texture_size;
  half2 output_size;
  float frame_count;
  float frame_direction;
  float frame_rotation;
};
 
 
struct out_vertex {
  half4 position : POSITION;
  float2 texCoord : TEXCOORD0;
  half4 t1 : TEXCOORD1;
};
 
/*    VERTEX_SHADER    */
out_vertex main_vertex
(
  half4 position  : POSITION,
  float2 texCoord : TEXCOORD0,
 
     uniform half4x4 modelViewProj,
  uniform input IN
)
{
        out_vertex OUT = (out_vertex)0;
 
  OUT.position = mul(modelViewProj, position);
 
  half2 ps = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
  half dx = ps.x;
  half dy = ps.y;
 
  OUT.texCoord = texCoord;
  OUT.t1.xy = half2( dx,  0); // F
  OUT.t1.zw = half2(  0, dy); // H
 
  return OUT;
}
 
 
/*    FRAGMENT SHADER    */
half4 main_fragment(in out_vertex VAR, uniform sampler2D decal : TEXUNIT0, uniform input IN) : COLOR
{
  bool4 edr, edr_left, edr_up, px; // px = pixel, edr = edge detection rule
  bool4 ir_lv1, ir_lv2_left, ir_lv2_up;
  bool4 nc; // new_color
  bool4 fx, fx_left, fx_up; // inequations of straight lines.
 
  float2 fp = frac(VAR.texCoord*IN.texture_size);
 
  float2 dx = VAR.t1.xy;
  float2 dy = VAR.t1.zw;
 
  half3 A = tex2D(decal, VAR.texCoord -dx -dy).xyz;
  half3 B = tex2D(decal, VAR.texCoord     -dy).xyz;
  half3 C = tex2D(decal, VAR.texCoord +dx -dy).xyz;
  half3 D = tex2D(decal, VAR.texCoord -dx    ).xyz;
  half3 E = tex2D(decal, VAR.texCoord        ).xyz;
  half3 F = tex2D(decal, VAR.texCoord +dx    ).xyz;
  half3 G = tex2D(decal, VAR.texCoord -dx +dy).xyz;
  half3 H = tex2D(decal, VAR.texCoord     +dy).xyz;
  half3 I = tex2D(decal, VAR.texCoord +dx +dy).xyz;
 
  half3  A1 = tex2D(decal, VAR.texCoord     -dx -2.0*dy).xyz;
  half3  C1 = tex2D(decal, VAR.texCoord     +dx -2.0*dy).xyz;
  half3  A0 = tex2D(decal, VAR.texCoord -2.0*dx     -dy).xyz;
  half3  G0 = tex2D(decal, VAR.texCoord -2.0*dx     +dy).xyz;
  half3  C4 = tex2D(decal, VAR.texCoord +2.0*dx     -dy).xyz;
  half3  I4 = tex2D(decal, VAR.texCoord +2.0*dx     +dy).xyz;
  half3  G5 = tex2D(decal, VAR.texCoord     -dx +2.0*dy).xyz;
  half3  I5 = tex2D(decal, VAR.texCoord     +dx +2.0*dy).xyz;
  half3  B1 = tex2D(decal, VAR.texCoord         -2.0*dy).xyz;
  half3  D0 = tex2D(decal, VAR.texCoord -2.0*dx        ).xyz;
  half3  H5 = tex2D(decal, VAR.texCoord         +2.0*dy).xyz;
  half3  F4 = tex2D(decal, VAR.texCoord +2.0*dx        ).xyz;
 
float4 b = mul( half4x3(B, D, H, F), yuv_weighted );
float4 c = mul( half4x3(C, A, G, I), yuv_weighted );
float4 e = mul( half4x3(E, E, E, E), yuv_weighted );
float4 d = b.yzwx;
float4 f = b.wxyz;
float4 g = c.zwxy;
float4 h = b.zwxy;
float4 i = c.wxyz;
 
float4 i4 = mul( half4x3(I4, C1, A0, G5), yuv_weighted );
float4 i5 = mul( half4x3(I5, C4, A1, G0), yuv_weighted );
float4 h5 = mul( half4x3(H5, F4, B1, D0), yuv_weighted );
float4 f4 = h5.yzwx;
 
  float4 Ao = float4( 1.0, -1.0, -1.0, 1.0 );
  float4 Bo = float4( 1.0,  1.0, -1.0,-1.0 );
  float4 Co = float4( 1.5,  0.5, -0.5, 0.5 );
  float4 Ax = float4( 1.0, -1.0, -1.0, 1.0 );
  float4 Bx = float4( 0.5,  2.0, -0.5,-2.0 );
  float4 Cx = float4( 1.0,  1.0, -0.5, 0.0 );
  float4 Ay = float4( 1.0, -1.0, -1.0, 1.0 );
  float4 By = float4( 2.0,  0.5, -2.0,-0.5 );
  float4 Cy = float4( 2.0,  0.0, -1.0, 0.5 );
 
  // These inequations define the line below which interpolation occurs.
  fx.x      = (Ao.x*fp.y+Bo.x*fp.x > Co.x); 
  fx_left.x = (Ax.x*fp.y+Bx.x*fp.x > Cx.x);
  fx_up.x   = (Ay.x*fp.y+By.x*fp.x > Cy.x);
 
  fx.y      = (Ao.y*fp.y+Bo.y*fp.x > Co.y); 
  fx_left.y = (Ax.y*fp.y+Bx.y*fp.x > Cx.y);
  fx_up.y   = (Ay.y*fp.y+By.y*fp.x > Cy.y);
 
  fx.z      = (Ao.z*fp.y+Bo.z*fp.x > Co.z); 
  fx_left.z = (Ax.z*fp.y+Bx.z*fp.x > Cx.z);
  fx_up.z   = (Ay.z*fp.y+By.z*fp.x > Cy.z);
 
  fx.w      = (Ao.w*fp.y+Bo.w*fp.x > Co.w); 
  fx_left.w = (Ax.w*fp.y+Bx.w*fp.x > Cx.w);
  fx_up.w   = (Ay.w*fp.y+By.w*fp.x > Cy.w);
 
  ir_lv1.x      = ((e.x!=f.x) && (e.x!=h.x));
  ir_lv2_left.x = ((e.x!=g.x) && (d.x!=g.x));
  ir_lv2_up.x   = ((e.x!=c.x) && (b.x!=c.x));
 
  ir_lv1.y      = ((e.y!=f.y) && (e.y!=h.y));
  ir_lv2_left.y = ((e.y!=g.y) && (d.y!=g.y));
  ir_lv2_up.y   = ((e.y!=c.y) && (b.y!=c.y));
 
  ir_lv1.z      = ((e.z!=f.z) && (e.z!=h.z));
  ir_lv2_left.z = ((e.z!=g.z) && (d.z!=g.z));
  ir_lv2_up.z   = ((e.z!=c.z) && (b.z!=c.z));
 
  ir_lv1.w      = ((e.w!=f.w) && (e.w!=h.w));
  ir_lv2_left.w = ((e.w!=g.w) && (d.w!=g.w));
  ir_lv2_up.w   = ((e.w!=c.w) && (b.w!=c.w));
 
  float4 w1 = weighted_distance( e, c, g, i, h5, f4, h, f);
  float4 w2 = weighted_distance( h, d, i5, f, i4, b, e, i);
 
  float4 t1 = (coef*df(f,g));
  float4 t2 = df(h,c);
  float4 t3 = df(f,g);
  float4 t4 = (coef*df(h,c));
 
  edr      = bool4((w1.x<w2.x) && ir_lv1.x, (w1.y<w2.y) && ir_lv1.y, (w1.z<w2.z) && ir_lv1.z, (w1.w<w2.w) && ir_lv1.w);
  edr_left = bool4((t1.x<=t2.x) && ir_lv2_left.x, (t1.y<=t2.y) && ir_lv2_left.y, (t1.z<=t2.z) && ir_lv2_left.z, (t1.w<=t2.w) && ir_lv2_left.w);
  edr_up   = bool4((t4.x<=t3.x) && ir_lv2_up.x, (t4.y<=t3.y) && ir_lv2_up.y, (t4.z<=t3.z) && ir_lv2_up.z, (t4.w<=t3.w) && ir_lv2_up.w);
 
  nc.x = ( edr.x && (fx.x || edr_left.x && fx_left.x || edr_up.x && fx_up.x) );
  nc.y = ( edr.y && (fx.y || edr_left.y && fx_left.y || edr_up.y && fx_up.y) );
  nc.z = ( edr.z && (fx.z || edr_left.z && fx_left.z || edr_up.z && fx_up.z) );
  nc.w = ( edr.w && (fx.w || edr_left.w && fx_left.w || edr_up.w && fx_up.w) );
 
  t1 = df(e,f);
  t2 = df(e,h);
 
  px = bool4(t1.x<=t2.x, t1.y<=t2.y, t1.z<=t2.z, t1.w<=t2.w);
 
  half3 res = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : nc.w ? px.w ? H : D : E;
 
  return half4(res.x, res.y, res.z, 1.0);
}
 
Thanks!
Edited by greenpig83

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!