渐变纹理控制漫反射的光照强度
遮罩纹理控制高光反射的光照强度
代码承接上个博客 -> 法线纹理
Shader "Lit/DiffuseLitShader3"
{
Properties
{
_MainTex("Main Tex", 2D) = "white"{}
_BumpMap("Bump Map", 2D) = "bump"{}
_BumpScale("Bump Scale", Float) = 1.0
[NoScaleOffset] _RampTex("Ramp Tex", 2D) = "white"{}
_SpecularMask("Specular Mask", 2D) = "white"{}
_SpecularScale("Specular, Scale", Float) = 1.0
_Color("Color", Color) = (1, 1, 1, 1)
_Specular ("Specular", Color) = (1, 1, 1, 1)
_Gloss ("Gloss", Range(8.0, 256.0)) = 20
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include <UnityCG.cginc>
#include <UnityShaderUtilities.cginc>
#include <UnityLightingCommon.cginc>
struct a2v
{
float4 pos : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 TtoW0 : TEXCOORD2;
float4 TtoW1 : TEXCOORD3;
float4 TtoW2 : TEXCOORD4;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMap;
float4 _BumpMap_ST;
float _BumpScale;
sampler2D _RampTex;
sampler2D _SpecularMask;
float4 _SpecularMask_ST;
float _SpecularScale;
fixed4 _Color;
fixed4 _Specular;
float _Gloss;
v2f vert(a2v v)
{
v2f o;
//得到裁剪空间
o.pos = UnityObjectToClipPos(v.pos.xyz);
//一个 texcoord 的 uv 的 xy 存主纹理, zw 存法线纹理,减少插值计算
//o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
//o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);
//o.uv1 = v.texcoord.xy * _RampTex_ST.xy + _RampTex_ST.zw;
o.uv1 = TRANSFORM_TEX(v.texcoord, _SpecularMask);
float3 worldPos = mul(unity_ObjectToWorld, v.pos).xyz;
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//在世界坐标系中
float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);
fixed3 litDir = normalize(UnityWorldSpaceLightDir(worldPos));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
//读取纹理像素,并算出对于的法线方向,
// fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw);
// fixed3 tangentNormal;
//我们通过对 法线的 xy 进行缩放,来控制凹凸程度,在由 xy 来得到对应的 z 值
// tangentNormal.xy = (packedNormal.xy * 2 - 1) * _BumpScale;
// tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
//我不推荐自己解法线方向,由于不同的法线贴图的格式不同,会采用不同的解法,使用 Unity 的内置函数,可以避免这样的情况。
//此时提取的是切线坐标系的法向量
fixed3 tangentNormal = UnpackNormalWithScale(tex2D(_BumpMap, i.uv.zw), _BumpScale);
//需要从切线坐标系转换为世界坐标系
tangentNormal = normalize(half3(dot(i.TtoW0.xyz, tangentNormal),
dot(i.TtoW1.xyz, tangentNormal), dot(i.TtoW2.xyz, tangentNormal)));
//获得主纹理颜色
fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _Color.rgb;
//得到 ambient
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
//使用 半兰伯特定律
fixed halfLambert = dot(tangentNormal, litDir) * 0.5 + 0.5;
//使用了渐变纹理,修改漫反射
fixed3 diffuse = _LightColor0.rgb * albedo * tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb;
//高光反射 使用 Blinn - Phong 模型
fixed3 halfDir = normalize(litDir + viewDir);
//提取遮罩纹理的遮罩值
fixed specularMask = tex2D(_SpecularMask, i.uv1).r * _SpecularScale;
//应用遮罩值
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal, halfDir)), _Gloss) * specularMask;
return fixed4(diffuse + ambient + specular, 1.0);
}
ENDCG
}
}
FallBack "Specular"
}