-->

分類

2016年4月26日 星期二

Mosaic Shader for Unity

one of my friends wanted to make 3D h-game and he wondered how to make mosaic effect in 3D, so I did some research and made this



references:
风宇冲Unity3D教程学院 第二十三讲GrabPass
Dr.Dobb's Understanding Photomosaics
Shader "Custom/MosaicShader" {
 Properties{
  _MainTex("Base (RGB)", 2D) = "white" {}
 }

 SubShader
 {
  Tags{ "Queue" = "Transparent" }

  GrabPass
  {
   "_MyGrabTexture"
  }

  pass
  {
   Name "pass2"
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag

   #include "UnityCG.cginc"
   sampler2D _MyGrabTexture;
   float4 _MyGrabTexture_ST;

   struct VertexIn
   {
    float4 vertex : POSITION;
    float2 texcoord : TEXCOORD0;
    float4 screenPos : TEXCOORD1;
   };
   struct VtoF 
   {
    float4  pos : SV_POSITION;
    float2  uv : TEXCOORD0;
    float4 screenPos : TEXCOORD1;
   };

   VtoF vert(VertexIn v)
   {
    VtoF o;
    o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
    o.uv = TRANSFORM_TEX(v.texcoord,_MyGrabTexture);
    /*
    //source code in UnityCG.cginc
    inline float4 ComputeScreenPos(float4 pos) {
     //if we do perspective divide here(pos/pos.w), we got pos.x in range (-1, 1)(NDC)
     float4 o = pos * 0.5f;
     //if we do perspective divide here(o/pos.w), we got o.x in range (-0.5,0.5)
     #if defined(UNITY_HALF_TEXEL_OFFSET)
     o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.zw;
     #else
     o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
     #endif

     o.zw = pos.zw;
     //if we do perspective divide here(o/pos.w), we got o.x in range (0,1)
     //o.x / pos.w in range(-0.5, 0.5), o.w / pos.w = 0.5
     //(o.x + o.w) / pos.w in range (-0.5 + 0.5, 0.5 + 0.5) = (0,1)
     return o;
    }
    */
    o.screenPos = ComputeScreenPos(o.pos);
    return o;
   }
   float4 frag(VtoF i) : COLOR
   {
    //perspective divide for screen pos to normalize p to be in the range of (0,1)
    fixed4 p = i.screenPos / i.screenPos.w;
    float4 tmp = float4(0, 0, 0, 0);

    //http://docs.unity3d.com/462/Documentation/Manual/SL-BuiltinValues.html
    //_ScreenParams: screen dimension in pixel
    //p.x*_ScreenParams.x: get x coordinate on screen, unit: pixel
    //floor(p.x*_ScreenParams.x / 10) * 10: 100 -> 100, 101 -> 100, 102 -> 100 ..., 109 -> 100, 110 -> 110
    [unroll(10)]
    for (float ii = floor(p.x*_ScreenParams.x / 10) * 10; ii < floor(p.x*_ScreenParams.x / 10) * 10 + 10; ii += 1)
    {
     [unroll(10)]
     for (float jj = floor(p.y *_ScreenParams.y / 10) * 10; jj < floor(p.y *_ScreenParams.x / 10) * 10 + 10; jj += 1)
     {
      //sample pixel color on screen
      tmp += tex2D(_MyGrabTexture, float2(ii / _ScreenParams.x, 1 - jj / _ScreenParams.y));
     }
    }
    return tmp / 100;//average samples
   }
   ENDCG
  }
 }
}

2016年4月21日 星期四

Android recycler view inflation error

stack overflow
I meet this problem today. And solved it.

first step:keep the support-libs you used are same version

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'


second step:you should add recyclerView to your proguard files

-keep class android.support.v7.widget.** {*;}
// I`ve just keep all widgets

2016年4月18日 星期一

NDC to world coordinates

here is the original link
link

We transform it to clip space by multiplying it with our projection/modelview matrix.

clip = Matrix\text{ }world
Then move on to device coordinates by dividing with w.

device = clip_{xyz} / clip_w
So the problem we face is: given clip = Matrix\text{ }worlddevice = clip_{xyz} / clip_wworld_w = 1,
and given device as an input and Matrix as a constant, calculate world.
Let’s walk through it. Invert the first step:

Matrix^{-1}\text{ }clip = Matrix^{-1}\text{ }Matrix\text{ }world

Matrix^{-1}\text{ }clip = world
Now let’s see what we can do with the second equation.

device = clip_{xyz} / clip_w

clip_w\text{ }device = clip_{xyz}
Let’s use this syntax to indicate a 4-vector formed by combining a 3-vector and a fourth number:

clip = clip_{xyzw} = (clip_{xyz}, clip_w)
substitute clip_{xyz}

clip = (clip_w\text{ }device, clip_w)
insert into our earlier equation

Matrix^{-1}\text{ }clip = world

Matrix^{-1}\text{ }(clip_w\text{ }device, clip_w) = world

Matrix^{-1}\text{ }clip_w\text{ }(device, 1) = world
And note that since matrices are linear transforms, we can pull that clip_w in front of the matrix multiply:

clip_w\text{ }Matrix^{-1}\text{ }(device, 1) = world
So it seems we run into a wall. clip_w is lost, right? Don’t give up hope: we haven’t used the third of our initial givens yet.

world_w = 1
So let’s look at just the w component of that last equation there:

clip_w\text{ }\left(Matrix^{-1}\text{ }(device, 1)\right)_w = world_w = 1
Divide:

clip_w = \frac 1 {\left(Matrix^{-1}\text{ }(device, 1)\right)_w}
And insert into the equation that previously gave us trouble:

\frac{Matrix^{-1}\text{ }(device, 1)}{\left(Matrix^{-1}\text{ }(device, 1)\right)_w} = world
Or in other words:

\left(Matrix^{-1}\text{ }(device, 1)\right)_{xyz/w} = world\text{ ... and done.}