// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//单张纹理,纹理映射
Shader "Unlit/Chapter7-SingleTexture"
{
Properties
{
_Color("Color Tint",Color)=(1,1,1,1)
_MainTex ("Main Tex",2D)="White"{}
//添加纹理属性
_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 _Color;
sampler2D _MainTex;
//纹理名_ST 的方式方式来声明某个属性
/*其中ST是缩放和平移的缩写
_MainTex_ST可以让我们得到该纹理的缩放和平移值,
_MainTex_ST.xy 储存的是缩放值
_MainTex_ST.zw 储存的是偏移值
*/
float4 _MainTex_ST;
fixed4 _Specular;
float _Gloss;
struct a2v {
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
struct v2f {
float4 pos:SV_POSITION;
float3 worldNormal:TECOOR0;
float3 worldPos:TEXCOORD1;
float2 uv:TEXCOOD2;
};
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v. vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
//_MainTex_ST.xy顶点进行缩放,再用_MainTex_ST.zw进行偏移
o.uv = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw;
//Or just call the built-in function
//o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
/*unity提供了一个内置宏TRANSFORM_TEX来帮我们计算上述过程,
TRANSFORM_TEX在 UnityCG.cginc中定义*/
return o;
}
//Transfrom 2D UV by scale/bias property
#define TRANSFORM_TEX(ten,name)(tex.xy*name##_ST.xy+name##_ST.zw)
//他接受两个参数,第一个参数是顶点的纹理坐标,,第二个是纹理名
fixed4 frag(v2f i) :SV_Target{
//计算世界空间下的法线方向
fixed3 worldNormal = normalize(i.worldNormal);
//计算世界空间下的光照方向
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
//使用Tex2D函数对纹理进行采样
/*tex2D(第一个参数是需要被采样的纹理,第二个参数是float23类型的纹理坐标)
使用采样结果和_Color的乘积来作为材质的反射率albedo*/
fixed3 albedo = tex2D(_MainTex, i.uv).rgb*_Color.rgb;
//材质的反射率albedo和环境光照相乘得到环境光部分
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
//使用albedo计算漫反射光的结果
fixed3 diffuse = _LightColor0.rgb*albedo*max(0, dot(worldNormal, worldLightDir));
//用Blinn-Phong光照模式计算高光反射
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(worldNormal, halfDir)), _Gloss);
//返回环境光+漫反射+高光反射
return fixed4(ambient + diffuse + specular, 1.0);
}
ENDCG
}
}
Fallback"Specular"
}
- 纹理映射坐标(texture-mapping coordinates):定义了该顶点在纹理中对应的2D坐标,也被成为UV坐标
- unity使用的纹理空间是符合OpenGL的传统的,也就是说原点位于纹理左下角