目录

一、前言

二、素材准备

三、准备基础代码

四、准备基础场景

五、SurfaceOutput结构体

六、透明度

七、渲染顺序

八、选错的后果

九、Tags之渲染顺序

十、Cull(正面和反面渲染)

十一、代码汇总

十二、作者的碎碎念


一、前言

因为shader这个专题得到了大家的支持,所以目前在继续更新下去。

之前一直讲的都是rgb模式,我们一直没有带着a玩,因为透明模式和其他的稍微有些不太一样。

二、素材准备

首先我们需要准备一个透明贴图,如果你实在没有,可以选择去

FreePNG | FreePNG is a free to use PNG gallery where you can download high quality transparent PNG images.

不需要账号,直接找一个喜欢的下载就行了,我下载了(如图1所示)

三、准备基础代码

前面讲过的肯定不能再讲了,我们是在这个代码的基础上进行的。

Shader "Custom/011"
{
    Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
    }
    SubShader
    {
        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

四、准备基础场景

我们拿3D物体中的Quad来做放置的物体。

五、SurfaceOutput结构体

如果你仔细注意,本次准备的基础代码,有一个新的结构体,和以前用过的只有一个单词的差距,但比那个简单(也可以用上一个,这不是给大家多练习几个吗,嘿嘿)。具体可以查询以下链接。

编写表面着色器 - Unity 手册

struct SurfaceOutput
{
    fixed3 Albedo;  // 贴图颜色
    fixed3 Normal;  // 法线
    fixed3 Emission;//自发光
    half Specular;  // 0..1 范围内的镜面反射能力
    fixed Gloss;    // 镜面反射强度
    fixed Alpha;    // 透明度 Alpha
};

我们可以观察到,这里面专门有一个透明度的信息,所以我们的第一个目标就是,把透明度先放进去。 

六、透明度

我们改一下surf中的内容,把导入进来的贴图信息,分成两份,一份给贴图颜色,一份给透明度。

        void surf (Input IN, inout SurfaceOutput o)
        {
            //我们新建一个fixed4 把转换的所有的颜色信息都接进来
            fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
            //我们把rgb给了贴图
            o.Albedo = c.rgb;
            //把透明度给alpha
            o.Alpha = c.a;
        }

虽然代码已经写好了,可以写入进去,但到此为止,我们的透明是没有打开的,因为透明的种类有很多,需要我们标注一下

 写的位置,这个标注的位置在我们引用的后面

#pragma surface surf Lambert alpha:fade

 然后,我们就得到了一张透明的树(如图3所示)

七、渲染顺序

因为有了透明,所以渲染顺序就变得重要起来了。以前都是实心的,就没那么重要。

计算机的渲染顺序是这样的:

  • Background:背景,数值为1000,先画背景,没毛病吧!
  • Geometry:不透明物体,数值为2000
  • AlphaTest:需要进行透明度测试的物体,数值为2450(有些透明设置的比较复杂,计算机也不太确认,所以先测试一下,万一它属于不透明呢?)
  • Transparent:一定有透明的物体,数值为3000
  • Overlay:叠加效果,数值为4000(如镜头光晕)

所以一般是让你选择的。(如图4所示)

八、选错的后果

我们的树是透明物体,但我就想选成不透明的,你会发现,如果我把球一直往后挪,它会在相机里面突然渲染到前面。(如图5所示)

解决方案,就是(如图6所示),调对就可以了。

九、Tags之渲染顺序

这个里面有很多,我们暂时只讲渲染顺序。

我们除了可以在外面手动去选择渲染顺序,我们也可以自己在代码里面写好,有一些可以事先标注的内容,会放在Tags里。

顺序的单词是:Queue

顺序选择透明就写成:“Queue”=“Transparent”

如果选其他的,后面那个Transparent,就写别的。

代码如下:

    Tags
    {
        "Queue" = "Transparent"
    }

这时候你会发现,你的fromShader会自动变成Transparent的数值。(如图7所示)

十、Cull(正面和反面渲染)

所有的模型,包含图片,在Unity中,都是有正面和反面一说的。

对于图片来说,背面就是反面(如图8所示)。翻到反面,默认就会看不见。

对于模型来说,内部就是反面。我们只能看见外面。(如图9所示)

 摄像机移动到球体内部,就看不见了,因为和图片一样,反面不显示。

如果你希望看见,你就要在shader里面加代码。

 所以我们在代码里加上。

 SubShader
    {
        Tags
        {
        "Queue" = "Transparent"
        }
        
        //加在这个位置就可以了
        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

 然后你就会拥有一个,正反面的树。(如图10所示)

十一、代码汇总

本节课所有代码如下,方便你们参考比对。

Shader "Custom/011"
{
    Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
    }
    SubShader
    {
        //Tags放在这里哦
        Tags
        {
        "Queue" = "Transparent"
        }

        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade
        sampler2D _MainTex;
        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            //我们新建一个fixed4 把转换的所有的颜色信息都接进来
            fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
            //我们把rgb给了贴图
            o.Albedo = c.rgb;
            //把透明度给alpha
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

十二、作者的碎碎念

不知不觉已经更新十五集了,非常感谢大家一如既往的支持~up会继续努力更新下去的!~

另外,up已经同步对这个专题进行了视频录制,视频更新的要比文章慢,如果想看视频,大家也可以支持一下~视频已经更新了十二集了。

Unity 什么是shader第一集_哔哩哔哩_bilibili

06-29 04:38