Shader编程(三)纹理贴图、法线映射与Alpha透明度
2017-08-22 本文已影响18人
_凉笙
Shader"Texture"{
properties{
_Color("Color",Color) = (1,1,1,1)
_MainText("Main Tex",2D) = "White"{}
_Specular("Specular Color",Color) = (1,1,1,1)//控制高光颜色
_Gloss("Gloss",Range(8,200)) = 10//控制高光强度
}
SubShader{
Pass {
//定义正确的LightMode得到内置的光照变量
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
//包含unity的内置的文件,才可以使用unity内置的一些变量 相当于引入内置的光照模型
#include "Lighting.cginc"//取得第一个直射光的颜色 _LightColor0第一个值是光的位置_WorldSpaceLightPos0
#pragma vertex vert
#pragma fragment frag
// fixed4 _Diffuse;
sampler2D _MainText;
fixed4 _Color;
float4 _MainText_ST;//固定写法定义UV贴图偏移值缩放值
half _Gloss;
fixed4 _Specular;
struct a2v {
float4 vertex:POSITION;
float3 normal:NORMAL;
float2 texcoord:TEXCOORD0;
};
struct v2f {
float4 position:SV_POSITION;
float3 WorldNomormal : TEXCOORD0;
float3 WorldVertex:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(a2v v) {
v2f f;
//UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);
f.WorldVertex = mul(v.vertex,unity_WorldToObject).xyz;
f.uv = v.texcoord.xy* _MainText_ST.xy+ _MainText_ST.zw;//计算纹理的偏移值和缩放值
return f;
};
fixed4 frag(v2f f) :SV_Target{
//_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//对于每一个顶点来说 光的位置就是光的方向 因为光是平行光
fixed3 texColor=tex2D(_MainText,f.uv.xy)*_Color.rgb;
fixed3 diffuse = _LightColor0.rgb*texColor*max(dot(normalDir, lightDir),0);//取得漫反射的颜色
fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
fixed3 vlewDir = normalize(_WorldSpaceCameraPos.xyz - f.WorldVertex);
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(dot(reflectDir, vlewDir), 0), _Gloss);//计算高光
fixed3 tempColor = diffuse + specular+ UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
return fixed4(tempColor,1);
}
ENDCG
}
}
Fallback"Diffuse"
}
Paste_Image.png
纹理材质.gif
法线贴图与凹凸映射的强度
Shader"Rock"{
properties{
_Color("Color",Color) = (1,1,1,1)
_MainTex("Main Tex",2D) = "White"{}
_NormalMap("Normal Map",2D) = "bump"{}//bump使用顶点里面自带的法线贴图
_BumpScale("Bump Scale",Float)=1
}
SubShader{
Pass {
//定义正确的LightMode得到内置的光照变量
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#include "Lighting.cginc"//取得第一个直射光的颜色 _LightColor0第一个值是光的位置_WorldSpaceLightPos0
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;//固定写法定义UV贴图偏移值缩放值
sampler2D _NormalMap;
float4 _NormalMap_ST;//固定写法定义UV贴图偏移值缩放值
float _BumpScale;
struct a2v {
float4 vertex:POSITION;
//切线空间的确定是通过(存储到模型里面的)法线和(存储到模型里面的)切线确定的
float3 normal:NORMAL;
float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的
float2 texcoord:TEXCOORD0;
};
struct v2f {
float4 position:SV_POSITION;
//float3 WorldNomormal : TEXCOORD0;
float3 lightDir : TEXCOORD0;//切线空间下 平行光的方向
float4 uv:TEXCOORD1;//xy用来存储MainTex的纹理坐标, zw用来存储法线贴图的纹理坐标
};
v2f vert(a2v v) {
v2f f;
//UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
/*f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);*/
f.uv.xy = v.texcoord.xy * _MainTex_ST.xy+ _MainTex_ST.zw;//计算纹理的偏移值和缩放值
f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
TANGENT_SPACE_ROTATION;//调用这个后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向装换成切线空间下
//ObjspaceLightDir(v.vertex)//得到模型空间下的平行光方向
f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
return f;
};
//把所有的跟法线方向有关的运算都放在切线空间下
//从法线贴图里面取得的法线方向是在切线空间下的
fixed4 frag(v2f f) :SV_Target{
//_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
//fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间
fixed4 normalColor= tex2D(_NormalMap,f.uv.zw);
//pixel = (normal + 1) / 2
//normal = pixel * 2 - 1
fixed3 tangentNormal = UnpackNormal( normalColor); //切线空间下的法线
tangentNormal.xy = tangentNormal.xy*_BumpScale;
tangentNormal = normalize(tangentNormal);
fixed3 lightDir = normalize(f.lightDir);//对于每一个顶点来说 光的位置就是光的方向 因为光是平行光
fixed3 texColor=tex2D(_MainTex,f.uv.xy)*_Color.rgb;
fixed3 diffuse = _LightColor0.rgb*texColor*max(dot(tangentNormal, lightDir),0);//取得漫反射的颜色
fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
return fixed4(tempColor,1);
}
ENDCG
}
}
Fallback"Spacular"
}
凹凸贴图.gif
编写透明的Shader
Shader"Rock Alpha" {
properties{
_Color("Color",Color) = (1,1,1,1)
_MainTex("Main Tex",2D) = "White"{}
_NormalMap("Normal Map",2D) = "bump"{}//bump使用顶点里面自带的法线贴图
_BumpScale("Bump Scale",Float)=1
_Alpha("Alpha",Float)=1
}
SubShader{
Tags{"Queue"="Transparent""IngnoreProjector"="True""RanderType"="Transparent"}//"Queue"="Transparent"透明的渲染队列 "IngnoreProjector"="True"是否忽略投影 "RanderType"="Transparent"类型
Pass {
//定义正确的LightMode得到内置的光照变量
Tags{"LightMode" = "ForwardBase"}
ZWrite off//写入透明深度
Blend SrcAlpha OneMinusSrcAlpha//透明混合参数
CGPROGRAM
#include "Lighting.cginc"//取得第一个直射光的颜色 _LightColor0第一个值是光的位置_WorldSpaceLightPos0
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;//固定写法定义UV贴图偏移值缩放值
sampler2D _NormalMap;
float4 _NormalMap_ST;//固定写法定义UV贴图偏移值缩放值
float _BumpScale;
float _Alpha;
struct a2v {
float4 vertex:POSITION;
//切线空间的确定是通过(存储到模型里面的)法线和(存储到模型里面的)切线确定的
float3 normal:NORMAL;
float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的
float2 texcoord:TEXCOORD0;
};
struct v2f {
float4 position:SV_POSITION;
//float3 WorldNomormal : TEXCOORD0;
float3 lightDir : TEXCOORD0;//切线空间下 平行光的方向
float4 uv:TEXCOORD1;//xy用来存储MainTex的纹理坐标, zw用来存储法线贴图的纹理坐标
};
v2f vert(a2v v) {
v2f f;
//UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
/*f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);*/
f.uv.xy = v.texcoord.xy * _MainTex_ST.xy+ _MainTex_ST.zw;//计算纹理的偏移值和缩放值
f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
TANGENT_SPACE_ROTATION;//调用这个后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向装换成切线空间下
//ObjspaceLightDir(v.vertex)//得到模型空间下的平行光方向
f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
return f;
};
//把所有的跟法线方向有关的运算都放在切线空间下
//从法线贴图里面取得的法线方向是在切线空间下的
fixed4 frag(v2f f) :SV_Target{
//_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
//fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间
fixed4 normalColor= tex2D(_NormalMap,f.uv.zw);
//pixel = (normal + 1) / 2
//normal = pixel * 2 - 1
fixed3 tangentNormal = UnpackNormal( normalColor); //切线空间下的法线
tangentNormal.xy = tangentNormal.xy*_BumpScale;
tangentNormal = normalize(tangentNormal);
fixed3 lightDir = normalize(f.lightDir);//对于每一个顶点来说 光的位置就是光的方向 因为光是平行光
fixed4 texColor=tex2D(_MainTex,f.uv.xy)*_Color;
fixed3 diffuse = _LightColor0.rgb*texColor.rgb*max(dot(tangentNormal, lightDir),0);//取得漫反射的颜色
fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
return fixed4(tempColor, _Alpha*texColor.a);
}
ENDCG
}
}
Fallback"Spacular"
}
写入透明度.gif