shader"Book/Chapter 6/Specular Pix-Level"
{
Properties
{
_Diffuse ("Diffuse",Color)=(1,1,1,1)
_Specular ("Specular",Color)=(1,1,1,1)
_Gloss ("Gloss",Range(8.0,256))=20
}
subshader
{
pass
{
Tags{ "LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct a2v
{
float4 vertex:POSITION;
float3 normal:NORMAL;
};
struct v2f
{
float4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLightDir));
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir, viewDir)), _Gloss);
return fixed4(ambient + diffuse + specular, 1.0);
}
ENDCG
}
}
Fallback"Specular"
}
在做逐像素高光shader的时候,我是在逐顶点代码基础上做的改变,主要原理就是把顶点着色器的代码移植到片元着色器里面,如下:
shader"Book/Chapter6/SpecularVertexLevel"{
properties{
_SpecularColor("Specular Color",color) = (1,1,1,1)
_DiffuseColor("Diffuse Color", color) = (1, 1, 1, 1)
_Gloss("Gloss",range(8.0,256))=20
}
subshader{
Tags{}
pass{
Tags{"LightMode" = "ForwardBase"}//get _LightColor
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"Lighting.cginc"
fixed3 _SpecularColor;
fixed3 _DiffuseColor;
float _Gloss;
struct a2v {
float4 vertex:POSITION;
fixed3 normal : NORMAL;
};
struct v2f {
float4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
// float3 color:COLOR;犯了一个错误,结构体里面没用到的变量不要留着,不然会报错
//说你的顶点着色器不合法
fixed3 viewDir : TEXCOORD1;
};
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize(UnityObjectToWorldNormal(v.normal));
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
float4 frag(v2f i):SV_Target {
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 reflectDir = normalize(reflect(-worldLightDir, i.worldNormal));
float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 diffuse = _DiffuseColor * saturate(dot(i.worldNormal, worldLightDir));
float3 specular = _LightColor0*_SpecularColor*pow(saturate(dot(i.viewDir,reflectDir) ),_Gloss);
float3 color = ambient+ diffuse + specular;
return float4(color, 1);
}
ENDCG
}
}
FallBack"specular"
}
- 移植的时候,首先考虑到顶点着色器哪些参数在片元着色器中取不到
那我们就把worldNormal 跟viewDir留在顶点着色器里面,相应的在v2f结构体中声明worldNormal跟viewDir,(所以o可以取到worldNormal跟viewDir)