shader01

来源:互联网 发布:sysbench mysql 安装 编辑:程序博客网 时间:2024/06/05 07:41


1.固定管线版本:

Shader "Custom/Grab" {
 

Properties {
  //_MainTex ("Base (RGB)", 2D) ="white" {}
 }
 SubShader {
  //在所有不透明对象之后绘制自己,更加靠近屏幕
  Tags{ "Queue" = "Transparent" }
  //通道1:捕捉对象之后的屏幕内容放到_GrabTexture纹理中
  GrabPass{}
  //通道2:设置材质
  Pass{
   //使用上面产生的纹理,进行颜色反相(1-原材质色)
   SetTexture[_GrabTexture]{combineone-texture}
  }
 }
 FallBack "Diffuse"
}

效果如下,它是取模型背后的屏幕纹理:

shader实例(十六)GrabPass捕捉屏幕纹理

2.顶点,片段版本:

Shader "Custom/GrabAllVF" {
 Properties {
  //_MainTex ("Base (RGB)", 2D) ="white" {}
 }
 SubShader {
  //在所有不透明对象之后绘制自己,更加靠近屏幕
  Tags{"Queue"="Transparent"}
  //通道1:捕捉屏幕内容放到_GrabTexture纹理中
  GrabPass{} 
  //通道2:设置材质
  Pass{
        Name"pass2"
        CGPROGRAM
        #pragmavertex vert
        #pragma fragment frag
        #include"UnityCG.cginc"

         sampler2D  _GrabTexture;
         float4       _GrabTexture_ST;
         //片段程序的输入
          struct v2f{
               float4  pos : POSITION;
               float2  uv : TEXCOORD0;
           };
           v2f   vert(appdata_base v)
           {
               v2f o;
               o.pos = mul( UNITY_MATRIX_MVP , v.vertex);
               o.uv = TRANSFORM_TEX(v.texcoord, _GrabTexture);
               return o;
           }
           float4 frag(v2f i) : COLOR
           {
                      half4texCol = tex2D(_GrabTexture, float2(1-i.uv.x , 1-i.uv.y));
                      //颜色反相,便于观察效果
                      return 1 - texCol;
           }
            ENDCG
           }
        }
 FallBack "Diffuse"
}

效果如下:取到的是全屏的纹理:

shader实例(十六)GrabPass捕捉屏幕纹理
1和2为什么取到的屏幕纹理不一样呢?


3.使用vf的方式,只获取物体后面的屏幕纹理,后面的扭曲效果会用到此方式,代码如下:

Shader "Custom/GrabVF" {
       Properties {
             //_MainTex ("Base (RGB)", 2D) ="white" {}
        }
      SubShader {
            // 在所有不透明对象之后绘制自己,更加靠近屏幕
           Tags{"Queue"="Transparent"}
            //通道1:捕捉对象之后的屏幕内容放到_GrabTexture纹理中
            GrabPass{} 
           // 通道2:设置材质
            Pass{
                      Name "pass2"
                      CGPROGRAM
           #pragmavertex vert
           #pragma fragment frag
           #include"UnityCG.cginc"

            sampler2D_GrabTexture;
            float4_GrabTexture_ST;
            struct v2f{
                    float4  pos : POSITION; //输入的模型空间中,顶点坐标信息
                   float4  uv : TEXCOORD0; //材质信息也包含了xyzw,通常只用xy,但是这里由顶点生成
           };
           v2f vert(appdata_base v)
           {
                v2fo;
                 //从模型坐标 - 世界坐标 - 视坐标-(视觉平截体乘以投影矩阵并进行透视除法)-剪裁坐标
               o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                 //【自动生成纹理】通过输出的pos计算的纹理信息
                 //【解决平台差异】D3D原点在顶部(本机需要让y缩放乘以-1),openGL在底部
               #if UNITY_UV_STARTS_AT_TOP
                     float   scale = -1.0;
               #else
                     float   scale = 1.0;
               #endif
               //pos的范围是【-1,1】+1为【0,2】,乘以0.5变成uv的范围【0,1】
               //不清楚为什么这样写,但是标准的写法就是这样
                      o.uv.xy= (float2(o.pos.x, o.pos.y*scale) + o.pos.w) * 0.5;
                      o.uv.zw= o.pos.zw;  
                      return o;
           }
   f         loat4 frag(v2f i) : COLOR
           {
            //对_GrabTexture纹理进行取样,进行2D纹理映射查找,后面传入的一定要四元纹理坐标。
            //UNITY_PROJ_COORD传入四元纹理坐标用于给tex2Dproj读取,但是多数平台上,返回一样的值。
           //【自动生成的纹理UV】类型是float4,使用如下方式进行2D纹理映射查找
           //half4 texCol = tex2Dproj(_GrabTexture,UNITY_PROJ_COORD(i.uv));

           //也可以使用tex2D进行采样,但是【自动生成的纹理UV】时必须要除以w转为齐次坐标
          float   last_x = i.uv.x / i.uv.w;
          float   last_y = i.uv.y / i.uv.w; 
           half4   texCol = tex2D(_GrabTexture, float2(last_x, last_y));
          //颜色反相,便于观察效果
               return 1 -texCol;
 

          }
   ENDCG
  }
 }
 FallBack "Diffuse"
}


0 0
原创粉丝点击