目录

前言

一、日常生活中的常见现象

二、unity自带的一个结构体(表面着色器SurfaceOutputStandard)

三、自己写一个颜色混合的Shader

1.只加基础颜色Albedo

2.加入法线

 3.加入光滑度

  4.加入金属度

  5.加入自发光

四、作者的话


前言

shader里每一个结构体的存在都是有原因的,都是来源于生活的,让我们一起来从生活的角度看看吧。

一、日常生活中的常见现象

小故事一:

家里的墙是白色的,我买了一个黄色的台灯,当我打开台灯时,白墙变成了黄色。(如图1所示)

图1 白墙照了黄光

备注:墙(物体)本身的颜色是白色,环境光的颜色是黄色,得到结果是黄色。

自身颜色叫:贴图

环境光叫:环境光

小故事二(上节课讲的,法线颜色),如图2所示:

Unity | Shader基础知识(第十一集:什么是Normal Map法线贴图)-CSDN博客

图2 法线贴图

备注:物体本身有颜色,加了深度的颜色信息。

有凹凸感:法线贴图

小故事三:

手电筒打到白纸上,白纸会亮一片,手电筒打到镜子里,只会亮一个点。(如图3,4所示)

ps:我找第二张图的时候要被吓死了....都搜出来什么鬼东西。救命!!!

图3 手电筒照纸
图4 手电筒照镜子

备注:白纸比较粗糙,光照上去以后会朝不同的地方散开,但物体如果非常光滑,光线会反射一下,朝一个方向走去。
光线方向是否会朝一个方向反射过去:光滑度

小故事四:

玻璃光滑,但光会都穿过去,金属片光滑,光会全部被反弹回去。(如图5,6)

图5 透光玻璃
图6 反光铝板

备注:光照到物体上以后,会穿透,会吸收,会反射,反射占比越多,就越像镜子。
像镜子一样,光都反射回去了:金属度

小故事五:

灯笼本身有颜色,但是它还会发光。(如图7)

图7 灯笼

备注:物体本身是蓝色带小鱼,但是有白色的光射出来。
自己是一个会发光的东西:自发光

二、unity自带的一个结构体(表面着色器SurfaceOutputStandard)

struct SurfaceOutputStandard
{
    fixed3 Albedo;      // 基础颜色——故事1
    fixed3 Normal;      // 法线——故事2
    half3 Emission;     //自发光——故事5
    half Metallic;      // 0=非金属,1=金属    金属度——故事4
    half Smoothness;    // 0=粗糙,1=平滑    光滑度——故事3
    half Occlusion;     // 遮挡(默认为 1) 这里先不讲
    fixed Alpha;        // 透明度 Alpha    这里先不讲
};

中文参考链接:编写表面着色器 - Unity 手册

我们就可以在shader里面直接用。

三、自己写一个颜色混合的Shader

1.只加基础颜色Albedo

(如图8所示)

图8 基础颜色
Shader "Custom/007_mixColor"
{
    Properties
    {    //贴图
        _MainTex ("Albedo", 2D) = "white" {}
    }
    SubShader
    {
        CGPROGRAM
        //把表面着色器的结构体相关部分引用进来
        #pragma surface surf Standard

        //承接资源的部分
        sampler2D _MainTex;

        //输入的结构体
        struct Input
        {
            float2 uv_MainTex;
        };

        //数据传递的方法
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //把贴图转换成能用的数据
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

备注:其实这里已经加了环境光,因为如果没有环境光,你就啥也看不见。(如图9所示)

图9 关闭环境光

 如果改变环境光的颜色,贴图的颜色也会改变,和故事一相同。(如图10所示)

图10 改变环境光的颜色
2.加入法线

(这部分就不细讲了,直接放代码)(如图11所示) 

图11 加入法线贴图
Shader "Custom/007_mixColor"
{
    Properties
    {    //贴图
        _MainTex ("Albedo", 2D) = "white" {}
        //法线图片
        _MainNormal ("NormalTexture",2D) = "bump" {}
    }
    SubShader
    {
        CGPROGRAM
        //把表面着色器的结构体相关部分引用进来
        #pragma surface surf Standard

        //承接资源的部分
        sampler2D _MainTex;
        sampler2D _MainNormal;

        //输入的结构体
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainNormal;
        };

        //数据传递的方法
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //把贴图转换成能用的数据
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
        }
        ENDCG
    }
    FallBack "Diffuse"
}
3.加入光滑度

(如图12所示) 越光滑,光线就会朝着太阳照射的地方反射回去。因为改变的是方向,所以调到中间的时候刚好射到眼睛里,就是白的。

图12 光滑度
Shader "Custom/007_mixColor"
{
    Properties
    {    //贴图
        _MainTex ("Albedo", 2D) = "white" {}
        //法线图片
        _MainNormal ("NormalTexture",2D) = "bump" {}
        //光滑度
        _Smoothness("Smoothness",Range(0,1)) = 0.5
    }
    SubShader
    {
        CGPROGRAM
        //把表面着色器的结构体相关部分引用进来
        #pragma surface surf Standard

        //承接资源的部分
        sampler2D _MainTex;
        sampler2D _MainNormal;
        float _Smoothness;

        //输入的结构体
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainNormal;
        };

        //数据传递的方法
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //把贴图转换成能用的数据
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
            //光滑度
            o.Smoothness =_Smoothness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 4.加入金属度

(如图13所示) 这里为了光泽度感觉更明显,把其他贴图先去掉了。

图13 加入金属度​​​​​​
Shader "Custom/007_mixColor"
{
    Properties
    {    //贴图
        _MainTex ("Albedo", 2D) = "white" {}
        //法线图片
        _MainNormal ("NormalTexture",2D) = "bump" {}
        //光滑度
        _Smoothness("Smoothness",Range(0,1)) = 0.5
        //金属度
        _Metallic("Metallic",Range(0,1)) = 0
    }
    SubShader
    {
        CGPROGRAM
        //把表面着色器的结构体相关部分引用进来
        #pragma surface surf Standard

        //承接资源的部分
        sampler2D _MainTex;
        sampler2D _MainNormal;
        float _Smoothness;
        float _Metallic;

        //输入的结构体
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainNormal;
        };

        //数据传递的方法
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //把贴图转换成能用的数据
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
            //光滑度
            o.Smoothness =_Smoothness;
            //金属度
            o.Metallic =_Metallic;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 5.加入自发光

(如图14所示) 

如图14 自发光
Shader "Custom/007_mixColor"
{
    Properties
    {    //贴图
        _MainTex ("Albedo", 2D) = "white" {}
        //法线图片
        _MainNormal ("NormalTexture",2D) = "bump" {}
        //光滑度
        _Smoothness("Smoothness",Range(0,1)) = 0.5
        //金属度
        _Metallic("Metallic",Range(0,1)) = 0
         //自发光
        _Emission ("Emission", Color) = (1,1,1,1)
    }
    SubShader
    {
        CGPROGRAM
        //把表面着色器的结构体相关部分引用进来
        #pragma surface surf Standard

        //承接资源的部分
        sampler2D _MainTex;
        sampler2D _MainNormal;
        float _Smoothness;
        float _Metallic;
        float3 _Emission;

        //输入的结构体
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainNormal;
        };

        //数据传递的方法
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //把贴图转换成能用的数据
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Normal = UnpackNormal(tex2D(_MainNormal,IN.uv_MainNormal));
            //光滑度
            o.Smoothness =_Smoothness;
            //金属度
            o.Metallic =_Metallic;
            //自发光
            o.Emission = _Emission;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 备注:到此为止,我们常用的五个故事里的颜色混合,都写出来了。

四、作者的话

恭喜大家,shader最最基础的部分已经学完了,现在的大家已经可以看懂一些基础的shader和进行一些修改了。最近up稍微闲了一点,会努力更新哒,感谢大家的支持,没有你们观看,就没有我写下去的动力。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐