(十四)计算机图形学 之 Shader 渲染通道常用指令(混合模式、Alpha测试、深度测试、通道遮罩、面剔除)

混合模式

1:在所有计算完成后,决定当前的计算结果输出到帧缓冲区时,如何混合源和目标,通常用
来绘制半透明的物体;
2:Blend off 关闭混合
3:Blend 源因子,目标因子:配置并开启混合,产生的颜色和源因子相乘,然后两个颜色相加
4:Blend 源因子,目标因子,源因子A,目标因子A:源因子与目标因子用户混合颜色值,源因子A,与目标因子A,用于混合alpha
5:BlandOp操作命令:不是将颜色混合在一起,而是对他们进行操作,主要有:
Min, Max, Sub, RevSub
6:混合因子的类型:
One 使用源或目标色完全显示出来;
zero 删除源颜色或目标颜色;
SrcColor 这个阶段的值*源颜色值;

SrcAlpha 这个阶段的值*源颜色Alpha值
DstColor 这个阶段的值* 帧缓冲颜色值;
DstAlpha这个阶段的值*帧缓冲源Alpha值
OneMinusSrccolor 阶段值*(1-源颜色的值)
OneMinusSrcAlpha 阶段值*(1-源颜色的Alpha值)
OneMinusDstcolor 阶段值*(1-目标颜色的值);
OneMinusDstAlha 阶段值*(1-目标颜色Alpha值)
6:一般放在放在Pass通道里面;

Alpha测试

 1:Alpha测试:阻止片元被写到屏幕的最后机会,最终渲染出来的颜色计算出来后可通过透明
度和最后一个固定值比较,如果通过测试则绘制次片元,否则丢弃此片元;
2:AlphaTest off/on:开启/关闭Alpha测试,默认是关闭的;
-3:比较测试值的模式:
Greater >, GEqual >=,Less <, LEqual <=, Equal ==, NotEqual !=,
Always(永远渲染),Never(从不渲染);
4:AlphaTest 条件[交量]/常数,一般放在放在pass通道里面;

深度测试

 1:为了使近距离的物体挡佳远距离的物体,当片元写入到缓冲的时候,需要将片元的深度值
与缓冲区的深度值进行比较,测试成功写入帧缓冲区;
2:zWrite 深度写开关,控制是否将深度z的片元写入缓冲区中,如果不绘制透明物体设置为
On, 否则的话设置为Off,默认为On;
3:ZTest 深度测试模式:设置深度测试的执行方式,默认为LEqual,深度测试的模式:
Less <, Greater >, LEqual <= , GEqual >=, Equal ==, NotEqual !=,Always 总是绘制关闭深度测试;
4:ZTest 条件
5:一般放在放在Pass通道里面;

通道遮罩

1:通道遮罩可以是开发人员指定渲染结果输出的通道,而不是通常情况下的RGBA四个通道;
2:可选的是RGBA的任意组合以及0,如果为0意味着不会写入到任何通道:
3: ColorMask RG ... ColorMask 0

面剔除

1:通过不谊染背对摄像机的几何体的面来提高性能优化错误,所有的几何体都包含正面和反面
2:面剔除操作,大多数都是封闭的物体,所以不需要绘制背面;
3:面剔除操作:
        Cull Back: 不绘制背对摄像机的面,默认项
        Cull Front, 不绘制面向摄像机的面,
        Cull Off,关闭面剔除操作 

Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Color",Color) = (1.0,0.0,0.0,1.0)
        _Alpha("Alp",float) = 1.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Transparent"}  // "Queue"="Transparent" 这里渲染队列选择带透明度的队列 ,方块墙后面的球就能看到了,否则是看不到的。
        LOD 100

        Pass
        {
            // 如果是变量 一定要加中括号包住参数[] 
            // 如果是常量 则直接写即可 比如这里的 0
            AlphaTest Never [_Alpha]
            //AlphaTest Never 0

            //深度测试也类似 AlphaTest写法
            //ZTest Never

            // 面剔除 开关
            //Cull Off
        }
    }

混合模式案例:

1.在Unity中,新建一个Unlit shader,新加一个颜色修改属性,然后在着色部分,使用该颜色

_Color("Color",Color) = (1.0,0.0,0.0,1.0)


 fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                //fixed4 col = tex2D(_MainTex, i.uv);
                fixed4 col = _Color;
                return col;
            }

2.然后在Unity中新建一个球和一面墙,让墙在球的前面,遮挡作用。

给墙使用我们的shader,并修改下色盘的alpha,效果如下,虽然透明度是修改了,但是没有效果;

 3.此时用到了 Blend SrcAlpha OneMinusSrcAlpha 来开启渲染混合通道

注意:这里通道的命令一般都是写在Pass内,且不在cg代码块中

shader同样的设置,效果如图:(很明显,已经有了透明效果,但是在墙别后的球是被遮挡了的,看不到)

 4.此时用到了渲染队列里的内容,一般物体是在Geometry(默认)使用这个队列的,不包含透明度,此时我们将渲染队列修改,使用Transparent有透明度的渲染通道,效果如图:(墙后面的球也能看到了,而且颜色是叠加的,本来白色的球,通过红色的墙,也会有红色)

 实例代码:

Shader "GFStudy/BlendShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Color",Color) = (1.0,0.0,0.0,1.0)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Transparent"}  // "Queue"="Transparent" 这里渲染队列选择带透明度的队列 ,方块墙后面的球就能看到了,否则是看不到的。
        LOD 100

        Pass
        {
            // 渲染通道 一定要在cg代码块外部写 
            // 开启混合通道 就会有透明度  否则在色盘里调整alpha是没有反应的
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                //fixed4 col = tex2D(_MainTex, i.uv);
                fixed4 col = _Color;
                return col;
            }
            ENDCG
        }
    }
}

通道遮罩案例:

1.在Unity新建一个默认shader,然后把内容全部去掉,只剩一个简单的SubShader:

这里在pass中给定了一个颜色,白色

hader "GFStudy/colorMask"
{

    SubShader
    {
        Pass
        {
            // 颜色遮罩  R 只输出Rad通道,R的值是多少就是什么颜色  B指输出蓝色通道  0是都不输出,就看不到了,  RGBA是都输出
            ColorMask R  //R  B  G  RGBA  0
            // 定义一个颜色 白色 
            Color(1.0,1.0,1.0,1.0)
        }
      
    }
    FallBack "Diffuse"
}

2.默认情况下,没有颜色遮罩命令 ColorMask R,看效果可以先把这个注释掉

效果如图:

 3.当加入颜色遮罩命令后,ColorMask R 是显示R通道颜色:

这个命令设置,有 R 、 G 、 B 、 RGBA 、  0  

0就是什么通道也不显示:

ColorMask 0 效果:

猜你喜欢

转载自blog.csdn.net/u013774978/article/details/130255411