[Tech] ... About pixels shader ...

Help
Seb26
2006-03-10
2013-05-08
  • Seb26
    Seb26
    2006-03-10

    Hello, is it possible to a MPC tech to describe all data provided by MPC for shader ...

    There is width, height ...
    ... but the others what are they exactly ?!
    ... clock --> unit ?
    ... one_over_width --> ???
    ... counter  --> ???

    And about texture : in case of PS resize, what is the texture ( original frame or screen ) size when shader is applied ?

    How use counter ?

    Is it possible to have a "per pixel" data stored by MPC ( to remebmber something for each pixel, this allow temporal soften for exemple ... )

    Thanks in advance !

    << MPC is the new king ! >>
    Seb.

    [Edit]
    Another thing : here is an little "EdgeSharpen", not really from me : contour + sharpen ... ;o)

    sampler s0 : register(s0);
    float4 p0 : register(c0);
    float4 p1 : register(c1);

    #define width (p0[0])
    #define height (p0[1])
    #define counter (p0[2])
    #define clock (p0[3])
    #define one_over_width (p1[0])
    #define one_over_height (p1[1])

    #define PI acos(-1)

    #define edge 0.5
    #define effect_width (1.9)
    #define val0 (2)
    #define val1 (0.125)

    float4 main(float2 tex : TEXCOORD0) : COLOR
    {
       float dx = 4/width;
       float dy = 4/height;

       float4 c2 = tex2D(s0, tex + float2(0,-dy));
       float4 c4 = tex2D(s0, tex + float2(-dx,0));
       float4 c5 = tex2D(s0, tex + float2(0,0));
       float4 c6 = tex2D(s0, tex + float2(dx,0));
       float4 c8 = tex2D(s0, tex + float2(0,dy));

       float4 c0 = (c5*4-c2-c4-c6-c8);

       if( length(c0) > edge )
       {
          float dx = effect_width/width;
          float dy = effect_width/height;

          float4 c1 = tex2D(s0, tex + float2(-dx,-dy)) ;
          float4 c2 = tex2D(s0, tex + float2(0,-dy)) ;
          float4 c3 = tex2D(s0, tex + float2(-dx,0)) ;
          float4 c4 = tex2D(s0, tex + float2(dx,0));
          float4 c5 = tex2D(s0, tex + float2(0,dy)) ;
          float4 c6 = tex2D(s0, tex + float2(dx,dy)) ;
          float4 c7 = tex2D(s0, tex + float2(-dx,+dy));
          float4 c8 = tex2D(s0, tex + float2(+dx,-dy)) ;
          float4 c9 = tex2D(s0, tex) * val0;

          c0 = c9 -  (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 )*val1;

          //Uncomment next line to see detected Edges in red ...
          //c0 = float4( 1.0, 0.0, 0.0, 0.0 );
       }
       else
       {
          c0 = tex2D(s0, tex);
       }

       return c0;
    }

     
    • Seb26
      Seb26
      2006-03-13

      Nobody for answering ...
      ... Maybe latter ;o)

      I've wrote some more little filters :

      *************************************
      1) EdgeSharpen v1.1 ( more readable )
      *************************************
      = Find a Sharp Edge zone ( thank to Edge and Sharpen filters from MPC ;o)
      = You can see edge zone by uncoment a line

      sampler s0 : register(s0);
      float4 p0 : register(c0);
      float4 p1 : register(c1);

      #define width (p0[0])
      #define height (p0[1])
      #define counter (p0[2])
      #define clock (p0[3])
      #define one_over_width (p1[0])
      #define one_over_height (p1[1])

      #define PI acos(-1)

      #define Edge_width      2.0
      #define Edge_threshold       0.2

      #define Sharpen_width       1.2
      #define Sharpen_val0       2.0
      #define Sharpen_val1       0.125

      float4 main(float2 tex : TEXCOORD0) : COLOR
      {
         // Read current pixel color
         float4 Res = tex2D( s0, tex );

         // Edge detection width vector
         float dx = Edge_width / height;
         float dy = Edge_width / width;

         // Read corners color
         float4 c2 = tex2D(s0, tex + float2( 0,-dy) );
         float4 c3 = tex2D(s0, tex + float2(-dx,0) );
         float4 c4 = tex2D(s0, tex + float2( dx,0) );
         float4 c5 = tex2D(s0, tex + float2( 0, dy) );

         // Compute vector lenght
         float4 c0 = Res*4 - c2 - c3 - c4 - c5;

         // If vector lenght > Edge_threshold : sharp this pixel
         if( length(c0) > Edge_threshold )
         {
            // Compute sharpen's width vector
            dx = Sharpen_width / width;
            dy = Sharpen_width / height;

            // Read 8 around pixels color
            float4 c1 = tex2D(s0, tex + float2(-dx,-dy)) ;
            c2 = tex2D(s0, tex + float2(0,-dy)) ;
            c3 = tex2D(s0, tex + float2(-dx,0)) ;
            c4 = tex2D(s0, tex + float2(dx,0));
            c5 = tex2D(s0, tex + float2(0,dy)) ;
            float4 c6 = tex2D(s0, tex + float2(dx,dy)) ;
            float4 c7 = tex2D(s0, tex + float2(-dx,+dy));
            float4 c8 = tex2D(s0, tex + float2(+dx,-dy)) ;

            float4 c9 =Res * Sharpen_val0;

            Res = c9 - (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 ) * Sharpen_val1 ;

            // Uncomment next line to see detected Edges in red ...
            //Res = float4( 1.0, 0.0, 0.0, 0.0 );

         }

         return Res;
      }

      **********************
      2) DisplayLessThan16 :
      **********************
      = Display in green pixel with a R, G, or B value < 16 ( to detect 16-235 color mapping )

      sampler s0 : register(s0);
      float4 p0 : register(c0);
      float4 p1 : register(c1);

      #define width (p0[0])
      #define height (p0[1])
      #define counter (p0[2])
      #define clock (p0[3])
      #define one_over_width (p1[0])
      #define one_over_height (p1[1])

      #define PI acos(-1)
      #define Value_16 (16.0/255.0)

      float4 main(float2 tex : TEXCOORD0) : COLOR
      {
         float4 c0 = tex2D(s0, tex);
         if( c0[0]<Value_16 || c0[1]<Value_16 || c0[2]<Value_16 )
            c0 = float4( 0, 1, 0, 0 );

         return c0;
      }

      *****************
      3) Remap_16_235 :
      *****************
      = Remap color from 16->235 to 0->255

      sampler s0 : register(s0);
      float4 p0 : register(c0);
      float4 p1 : register(c1);

      #define width (p0[0])
      #define height (p0[1])
      #define counter (p0[2])
      #define clock (p0[3])
      #define one_over_width (p1[0])
      #define one_over_height (p1[1])

      #define PI acos(-1)

      #define Const_1 (16.0/255.0)
      #define Const_2 (255.0/219.0)

      float4 main(float2 tex : TEXCOORD0) : COLOR
      {
         return( ( tex2D( s0, tex ) - Const_1 ) * Const_2 );
      }

       
    • Seb26
      Seb26
      2006-03-14

      Does anybody can take 2 minute to explain this few lines please ?

      #define counter (p0[2])
      #define clock (p0[3])
      #define one_over_width (p1[0])
      #define one_over_height (p1[1])

      Must I read MPC source code ???

      Thanks in advance ...

       
      • BlindWanderer
        BlindWanderer
        2006-03-14

        actually it's much much worse then that, you will have to read the Shader section of the Microsoft DirectX SDK Manual.

        sampler s0 : register(s0);
        float4 p0 : register(c0);
        float4 p1 : register(c1);

        #define width (p0[0])
        #define height (p0[1])
        #define counter (p0[2])
        #define clock (p0[3])
        #define one_over_width (p1[0])
        #define one_over_height (p1[1])

        p0 & p1 are names for the values in registers c0 & c1
        These registers by default contain this information. Clock is the frame time. Counter is (probably) the frame number.

        My graphics card only supports PS_1_1 (and below) so i cannot do complex shaders.

         
      • The Titan
        The Titan
        2006-06-22

        shaders take geometry information (is not a concern here in MPC), texture information and some constants to render something on the screen/buffer.

        In HLSL (High Level Shader Language) you'll work those three kind of variables.
        MPC will send some geometry to the video board (a screen aligned quad), a texture (the current frame of anything you want to display in MPC) and some constants (right now 8 constants).

        The current frame is stored in the first texture sent to the videoboard (s0 - the first texture register).

        To take advantage of that texture, you'll declare a sampler variable and then use it. It goes something like:

        sampler s0 : register(s0);

        8 float variables are also sent per frame by MPC. To retrieve those values inside a pixel shader, you'll have to declare them like that:

        float4 p0 : register(c0);
        float4 p1 : register(c1);

        Each constant register will store 4 float values. The constants come packed in those two registers so you'll have to separate each of the two declared variables p0 and p1 and distribute one float per constant (widht, height, counter, ...)

         
    • Seb26
      Seb26
      2006-03-14

      I'm OK with DirectX and C/C++/C#, my answer was more on the values offer by MPC ... ;o)

      So Clock is the timeline position ( you know the unit ? ) ... And counter the frame number ...

      Thanks a lot to you for answering my post ! :o)

      No idea "for one_over_width" & "one_over_height" ?

      Thanks again.
      Seb

       
    • Eep²
      Eep²
      2008-12-15

      Is there a shader tutorial somewhere? I want a shader to simply increase the brightness/gamma a bit since MPC seems incapable of doing this by default on its own!