法线映射
实现原理:
按纹理映射方式先获取纹理坐标上的像素颜色值,由于颜色值范围在[0,1],法线值为[-1,1],可以使用UnpackNormal函数获取法线值
这里需要注意的是获取的法线值是在切线空间下的值,在使用漫反射公式时,直射光也需要统一转化为在切线坐标下
代码如下:
Shader "LJL/06-Normal"
{
Properties
{
_Color("_Color",Color)=(1,1,1,1)
_MainTex("_MainTex",2D)="white"{}
_NormalTex("_NormalTex",2D)="bump"{}
_BumpScale("_BumpScale",float)=1
}
SubShader
{
Pass
{
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members wordSpacePosition)
#pragma exclude_renderers d3d11 xbox360
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
sampler2D _NormalTex;
fixed4 _Color;
float4 _MainTex_ST;
float4 _NormalMap_ST;
float _BumpScale;
struct a2v
{
float4 position:POSITION ;
float3 normal:NORMAL;//固定写法,在调用TANGENT_SPACE_ROTATION宏时会调用
float4 tangent:TANGENT;//同上
float4 texcoord:TEXCOORD0 ;
};
struct v2f
{
float4 position:SV_POSITION ;
float4 texcoord:TEXCOORD0 ;
float3 tangentLightDir:TEXCOORD1 ;
};
v2f vert(a2v v)
{
v2f f;
f.position=mul(UNITY_MATRIX_MVP,v.position) ;
f.texcoord.xy = v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
f.texcoord.zw = v.texcoord.xy*_NormalMap_ST.xy+_NormalMap_ST.zw;
TANGENT_SPACE_ROTATION ;//得到矩阵rotation,将模型空间转化为切线空间
//将模型空间的光方向转化为切线空间下的方向
f.tangentLightDir = normalize(mul(rotation,ObjSpaceLightDir(v.position)));
return f;
}
fixed4 frag(v2f f):SV_Target
{
//获取主纹理颜色值
fixed3 mainTexColor = tex2D(_MainTex,f.texcoord.xy)*_Color;
//获取法线贴图颜色值
fixed4 normalTexColor = tex2D(_NormalTex,f.texcoord.zw);
float3 normalDir = UnpackNormal(normalTexColor);//将颜色值转化为法线值(切线空间下),其中normalDir.z的方向与法线方向一致(法线与切线垂直),normalDir.w决定切线空间方向
normalDir.xy = normalDir.xy*_BumpScale;//改变xy的值将改变凹凸效果
normalDir = normalize(normalDir);
float3 diffuse = _LightColor0.rgb*mainTexColor*max(dot(normalDir,f.tangentLightDir),0);
float3 temp = diffuse+_LightColor0.rgb*mainTexColor;
return fixed4 (temp,1);
}
ENDCG
}
}
Fallback "Diffuse"
}
透明效果
实现原理:
控制SV_Target的aphla值,但是在改变aphla中的值时需要对其Pass块加入一些Tags属性
代码如下:
Shader "LJL/07_Aphla"
{
Properties
{
_Color("_Color",Color)=(1,1,1,1)
_AphlaScale("_AphlaScale",Range(0.0, 1.0)) = 0.5
}
SubShader
{
Tags{ "Queue"="Transparent" "IngnoreProjector"="True" "RenderType"="Transparent" }
Pass
{
Tags{ "LightMode" = "ForwardBase" }
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed _AphlaScale;
fixed4 _Color;
struct a2v
{
float4 position:POSITION ;
};
struct v2f
{
float4 position:SV_POSITION ;
};
v2f vert(a2v v)
{
v2f f;
f.position=mul(UNITY_MATRIX_MVP,v.position);
return f;
}
fixed4 frag(v2f f):SV_Target
{
fixed aphla=_Color.a*_AphlaScale;
return fixed4(_Color.rgb,aphla);
}
ENDCG
}
}
Fallback "Diffuse"
}
效果如下图: