Unity内置Shader解读2——Bumped Specular

  • Post author:
  • Post category:其他

1.Shader在什么情况下使用

Bumped Specular(凹凸镜面反射),看名字就知道在篇1的基础上加了Specular镜面反射。镜面反射嘛,通常用在一些金属之类会反光的东西上。

image.png

镜面反射效果:

image.png

2.Shader的价值(用的多不多),Shader的难度

Unity4.x时代,默认的金属材质,当年用的也比较多的。

3.代码详细注释

刚打开这个Shader的时候一脸懵啊?怎么shader代码写在SubShader外面,而且写了两个只声明#pragma surface surf xxxx的SubShader。
静下来想想才明白,首先SubShader是按顺序执行的,并且只如果执行一个通过了,后面的不再执行,所以如果赋值以下代码贴在那两个SubShader之前的话,就会只执行到兰伯特。

SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 400

        CGPROGRAM
        #pragma surface surf Lambert
        #pragma target 3.0
        ENDCG
    }

那这样就说明后一个SubShader必定是为了一些不大行的平台准备的,大多数设备只执行前一个SubShader。
而这两个SubShader需要执行的函数都一样是surf,内容也不变,唯一变化的是声明光照模型的时候后者多了一个nodynlightmap(禁用动态光照贴图)适配一些低端机型。
所以这边的逻辑就比较好理解了,因为CG代码内容一样 所以写在前面,后面用两个不同的SubShader如果第一个SubShader跑不了就跑第二个禁用动态光照贴图的SubShader。

Shader "Legacy Shaders/Bumped Specular" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)//镜面反射颜色
        [PowerSlider(5.0)] _Shininess ("Shininess", Range (0.03, 1)) = 0.078125//镜面反射度
        _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
        _BumpMap ("Normalmap", 2D) = "bump" {}
    }

    CGINCLUDE
    sampler2D _MainTex;
    sampler2D _BumpMap;
    fixed4 _Color;
    half _Shininess;

    struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
    };

    void surf (Input IN, inout SurfaceOutput o) {
        fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
        o.Albedo = tex.rgb * _Color.rgb;
        o.Alpha = tex.a * _Color.a;
        //光泽度受原图的alpha影响
        //这里如果改成_Color.a,在修改颜色值透明度的时候会有光泽度明暗调节效果
        o.Gloss = tex.a;
        //镜面反射强度直接由一个数值影响
        o.Specular = _Shininess;
        o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    }
    ENDCG

    //通常情况下只执行第一个SubShader
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 400

        CGPROGRAM
        #pragma surface surf BlinnPhong
        #pragma target 3.0
        ENDCG
    }

    //禁用动态光照贴图,适配某些机型
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 400

        CGPROGRAM
        #pragma surface surf BlinnPhong nodynlightmap
        ENDCG
    }

    FallBack "Legacy Shaders/Specular"
}

4.Shader编写思路,用到的知识点

SurfaceShader输入结构体可选内容
struct Input {
            float2 uv_MainTex;//_MainTex纹理的uv
            float2 uv_BumpMap;//法线贴图uv
            float3 viewDir;//观察方向,为了计算视察、边缘光照等效果
            float4 screenPos;//屏幕坐标
            float3 worldPos;//世界坐标
            float3 worldRef1;//世界反射向量
            float3 worldNormal;//世界法线向量
        };
SurfaceShader输出结构体

官方提供了以下三种结构体,也可以自定义

struct SurfaceOutput{
        fixed3 Albedo;//基础颜色(漫反射或镜面反射)
        fixed3 Normal;//切线空间法线
        fixed3 Emission;//自发光颜色
        half Specular//镜面反射度
        fixed Gloss//光泽度
        fixed Alpha;//透明度
    };

    struct SurfaceOutputStandard
    {
        fixed3 Albedo;      // 基础颜色(漫反射或镜面反射)
        fixed3 Normal;      // 切线空间法线
        half3 Emission;     // 自发光颜色
        half Metallic;      // 0为非金属, 1为金属
        half Smoothness;    // 0为粗糙, 1为光滑
        half Occlusion;     // 遮挡(默认1)
        fixed Alpha;        // 透明度
    };

    struct SurfaceOutputStandardSpecular
    {
        fixed3 Albedo;      // 漫反射颜色
        fixed3 Specular;    // 镜面反射颜色
        fixed3 Normal;      // 切线空间法线,如果赋值的话
        half3 Emission;     // 自发光颜色
        half Smoothness;    // 0为粗糙, 1为光滑
        half Occlusion;     // 遮挡(默认1)
        fixed Alpha;        // 透明度
    };

版权声明:本文为eevee_1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。