• 透明度测试


    透明度测试:只要一个片元的透明度不满足条件(通常是小于某个阈值),那它对应的片元就会被舍弃。被舍弃的片元不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则就会按照普通的不透明物体的处理方式来处理它。

    通常,我们会在片元着色器中使用clip函数来进行透明度测试。clip是Cg中的一个函数,它的定义如下。

    void clip(float4 x);
    void clip(float3 x);
    void clip(float2 x);
    void clip(float1 x);
    void clip(float x);

    参数:裁剪时使用的标量或矢量条件。

    描述:如果给定参数的任何一个分量是负数,就会舍弃当前像素的输出颜色。它等同于下面的代码:

    void clip(float4 x)
    {
        if(any(x<0))
          discard;//显式剔除片元
    }    

    接下来写一个透明度测试的实例:

     1 Shader "Custom/AlphaTest" {
     2     Properties {
     3         _Color ("Main Tint", Color) = (1,1,1,1)
     4         _MainTex ("Albedo (RGB)", 2D) = "white" {}
     5         _Cutoff("Alpha Cutoff",Range(0,1))=0.5
     6     }
     7     SubShader {
     8     /*
     9     "Queue"="AlphaTest":Unity中透明度测试使用的渲染队列是名为AlphaTest的队列
    10     "IgnoreProjectors"="True":意味着这个Shader不会受到投影器的影响
    11 RenderType标签可以让Unity把这个Shader归入到提前定义的组(这里就是TransparentCutout组)
    12     通常使用了透明度测试的shader都应该在SubShader中设置这3个标签
    13     */
    14     Tags{"Queue"="AlphaTest""IgnoreProjectors"="True""RenderType"="TransparentCutout"}
    15         Pass
    16         {
    17         Tags{"LightMode"="ForwardBase"}
    18         //Cull Off//控制双面渲染开关
    19         CGPROGRAM
    20         #pragma vertex vert
    21         #pragma fragment frag
    22         #include"Lighting.cginc"
    23 
    24         fixed4 _Color;
    25         sampler2D _MainTex;
    26         float4 _MainTex_ST;
    27         fixed _Cutoff;
    28 
    29         struct a2v
    30         {
    31         float4 vertex:POSITION;
    32         float3 normal:NORMAL;
    33         float4 texcoord:TEXCOORD0;
    34         };
    35         struct v2f
    36         {
    37         float4 pos:SV_POSITION;
    38         float3 worldNormal:TEXCOORD0;
    39         float3 worldPos:TEXCOORD1;
    40         float2 uv:TEXCOORD2;
    41         };
    42         v2f vert(a2v v)
    43         {
    44         v2f o;
    45         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
    46         o.worldNormal=UnityObjectToWorldNormal(v.normal);
    47         o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
    48         o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
    49         return o;
    50         }
    51 
    52         fixed4 frag(v2f i):SV_Target
    53         {
    54         fixed3 worldNormal=normalize(i.worldNormal);
    55         fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
    56         fixed4 texColor=tex2D(_MainTex,i.uv);
    57         clip(texColor.a-_Cutoff);//当texColor.a小于材质参数_Cutoff时u,该片元就会产生完全透明的效果。
    58         fixed3 albedo=texColor.rgb*_Color.rgb;
    59         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
    60         fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(worldNormal,worldLightDir));
    61         return fixed4(ambient+diffuse,1.0);
    62         }
    63 
    64         ENDCG
    65         }
    66     }
    67     FallBack "Transparent/Cutout/VertexLit"
    68 }
    透明度测试

     效果如下:

    双面渲染:在Pass中Cull Off(关闭剔除),效果如下:

  • 相关阅读:
    在VMWare的虚拟机中设置共享文件夹(Linux-Ubuntu系统)
    得到cell视图
    推送
    常用框架
    截屏
    多线程枷锁
    java与IOS的交互
    缓存机制
    iOS数据库操作(使用FMDB)
    插入排序
  • 原文地址:https://www.cnblogs.com/luxishi/p/6483038.html
Copyright © 2020-2023  润新知