Unity内置Shader解读2——Bumped Specula
2021-04-29 本文已影响0人
ShawnWeasley
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; // 透明度
};