类型
内置文件
三种精度
光照模型
标准光照模型:
只关心直接光照,光源发出的光线经过物体表面的一次反射直接进入相机的光线。
方法:
把进入相机的光线分为四个部分,每个部分用一种方法计算贡献度:
Phong模型: Blinn模型: 避免计算反射方向,将入射方向和光源方向去平均值并归一。然后用法线和新得到的向量去计算:
半兰伯特光照模型
高光反射光照模型(Phong光照模型):
高光反射是视线方向和反射方向的夹角余弦值
高光反射中反射方向计算:
高光反射光照模型(Blinn-Phong光照模型):
不关心反射光,将视角方向和入射光方向相加,然后归一化。
计算光照模型
逐像素光照:
逐像素计算漫反射光(兰伯特光照模型)
Shader "Mytest/DiffuseLightFragShader"
{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
struct v2f{
float4 pos: SV_POSITION;
float3 worldNormal:TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
o.worldNormal = normalize(normalWorld);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,i.worldNormal));
fixed3 color = diffuseLight+ambient;
return fixed4(color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素计算漫反射光(半兰伯特光照模型)
Shader "Mytest/DiffuseLightFragShader_HalfLambert"
{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
struct v2f{
float4 pos: SV_POSITION;
float3 worldNormal:TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
o.worldNormal = normalize(normalWorld);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float halfLMBT = dot(LightWorld,i.worldNormal)*0.5+0.5;
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *halfLMBT;
fixed3 color = diffuseLight+ambient;
return fixed4(color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素计算高光反射(Phong模型)
Shader "Mytest/SpecularLightFragShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos: SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
o.worldNormal = normalize(normalWorld);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,i.worldNormal));
fixed3 reflectDir = normalize(reflect(-LightWorld,i.worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
fixed3 specularLight = _LightColor0.rgb*_SpecularColor.rgb* pow(saturate(dot(reflectDir,viewDir)),_Gloss);
fixed3 color = diffuseLight + ambient + specularLight;
return fixed4(color,1);
}
ENDCG
}
}
FallBack "Specular"
}
逐像素计算高光反射(Blinn-Phong模型)
Shader "Mytest/SpecularLightFragShader_BlinnPhong"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos: SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
o.worldNormal = normalize(normalWorld);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,i.worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
float3 newDir =normalize( viewDir+LightWorld);
fixed3 specularLight = _LightColor0.rgb*_SpecularColor.rgb* pow(saturate(dot(newDir,i.worldNormal)),_Gloss);
fixed3 color = diffuseLight + ambient + specularLight;
return fixed4(color,1);
}
ENDCG
}
}
FallBack "Specular"
}
逐顶点光照:
逐顶点计算漫反射光(兰伯特光照模型)
Shader "Mytest/DiffuseLightShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
struct v2f{
float4 pos: SV_POSITION;
float3 color:COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
float3 NNormalWorld = normalize(normalWorld);
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,NNormalWorld));
o.color = diffuseLight+ambient;
return o;
}
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐顶点计算漫反射光(半兰伯特光照模型)
区别就只是half
Shader "Mytest/DiffuseLightShader_HalfLambert"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
struct v2f{
float4 pos: SV_POSITION;
float3 color:COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
float3 NNormalWorld = normalize(normalWorld);
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float halfLMBT = dot(LightWorld,NNormalWorld)*0.5 + 0.5;
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb * halfLMBT;
o.color = diffuseLight+ambient;
return o;
}
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐顶点计算高光反射(Phong模型)
Shader "Mytest/SpecularLightShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos: SV_POSITION;
fixed3 color:COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
float3 NNormalWorld = normalize(normalWorld);
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,NNormalWorld));
fixed3 reflectDir = normalize(reflect(-LightWorld,NNormalWorld));
fixed3 vertexWorldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-vertexWorldPos);
float3 specularLight = _LightColor0.rgb*_SpecularColor.rgb* pow(saturate(dot(reflectDir,viewDir)),_Gloss);
o.color = diffuseLight + ambient + specularLight;
return o;
}
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1);
}
ENDCG
}
}
FallBack "Specular"
}
逐顶点计算高光反射(Blinn-Phong模型)
Shader "Mytest/SpecularLightShader_BlinnPhong"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos: SV_POSITION;
fixed3 color:COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
float3 normalWorld = mul(v.normal,(float3x3)unity_WorldToObject);
float3 NNormalWorld = normalize(normalWorld);
float3 LightWorld = normalize( _WorldSpaceLightPos0.xyz);
float3 diffuseLight = _DiffuseColor.rgb* _LightColor0.rgb *saturate(dot(LightWorld,NNormalWorld));
fixed3 vertexWorldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-vertexWorldPos);
float3 newDir = normalize(viewDir + LightWorld);
float3 specularLight = _LightColor0.rgb*_SpecularColor.rgb* pow(saturate(dot(newDir,NNormalWorld)),_Gloss);
o.color = diffuseLight + ambient + specularLight;
return o;
}
fixed4 frag(v2f i):SV_Target{
return fixed4(i.color,1);
}
ENDCG
}
}
FallBack "Specular"
}
上边光照计算都是基于只有一个平行光,其他光源计算方式不同。且上边计算高光反射时,使用的漫反射都是兰伯特模型。
告别基础运算,使用内置方法
计算光照模型常用函数:
纹理!
模型的色彩通过纹理映射来展现,纹理坐标又称UV坐标(U横,V纵)范围是[0,1],存储在顶点信息中.
unity纹理的一些属性:
Texture Type纹理类型
Wrap Mode 决定纹理坐标超过[0,1]范围后的值
Repeat:超出部分计算小数部分采样。即不断重复 Clamp:超出1的都是1,小于0的都是0
Filter Mode 纹理由于变换产生拉伸时将会采用那种滤波模式
point,bilinear,trilinear 效果依次提升,但性能耗费增加
mipmapping 多级渐远纹理技术
抗锯齿问题:提前处理纹理,生成很多小的图像,像金字塔一样,每一层都是对上一层降级采样。 需要耗费空间去存储 多占用33%内存 空间换时间
纹理的最大尺寸
为不同平台选择不同纹理尺寸
纹理长宽尽量为2的幂 NPOT(non power of two)非2的幂
纹理格式:
纹理格式精度越高,效果越好,占用和耗费越大 不需要高精度时,尽量用压缩格式的纹理,例如漫反射纹理
OpenGL和DirectX中差异
OpenGL:原点在左下角 DirectX:原点在左上角
unity使用OpenGL的在左下角,且它已经处理好不同平台的问题
纹理实践
在shader中,properties中定义的纹理名称+_ST 可以获取到纹理的缩放xy和平移zw值
基本采样(纹理的使用):
Shader "Mytest/TextureBaseUseShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_DiffuseTexture("DiffuseTex",2D) = "white"{}
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256))=20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos:SV_POSITION;
float3 worldNormal: TEXCOORD0;
float4 worldPos:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize( UnityObjectToWorldNormal(v.normal));
o.worldPos = mul( unity_ObjectToWorld,v.vertex);
o.uv = v.texcoord.xy * _DiffuseTexture_ST.xy +_DiffuseTexture_ST.zw;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos) );
fixed3 albedo = tex2D(_DiffuseTexture,i.uv).rgb * _DiffuseColor.rgb;
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.xyz ;
fixed3 diffuseLight = albedo * _LightColor0.rgb * max(0,(dot(worldLightDir,i.worldNormal)));
fixed3 viewDir = normalize( UnityWorldSpaceViewDir(i.worldPos) );
fixed3 NewDir = normalize( viewDir + worldLightDir);
fixed3 specularLight = _SpecularColor.rgb * _LightColor0.rgb * pow( max(0,dot(NewDir,i.worldNormal)),_Gloss );
fixed3 color = ambientLight + diffuseLight + specularLight;
return fixed4(color,1);
}
ENDCG
}
}
FallBack "Specular"
}
凹凸纹理(使用纹理表现凹凸效果):
原理: 使用一张纹理来修改法线,让模型看起来是凹凸的,但顶点位置不变,也就是轮廓是不变的。
两种方式:
- 高度映射:
使用一张高度纹理,模拟表面位移,来得到一个模拟有位移的法线值。
高度纹理:存储强度值,表示模型表面局部的高度,越浅越凸起,越暗越凹陷;
优点:直观,看以看出凹凸 缺点:计算复杂,需要根据灰度值计算,耗费性能。
法线纹理:存储表面法线方向。 法线范围[-1,1] 像素分量[0,1] 所以需要映射 +1 /2; 所以在计算时,需要反向映射,获取原来法线的真实值 因为存储的时单位向量,所以只需要xy两个值即可,z可以通过计算得到
模型空间的法线纹理: 切线空间的法线纹理:顶点的切线空间
在切线空间下计算法线:
Shader "Mytest/NormalInTangentSpaceShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_DiffuseTexture("DiffuseTexture",2D) = "white"{}
_NormalMap("NormalMap",2D)="bump"{}
_BumpScale("BumpScale",Float)=1
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed3 _DiffuseColor;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
sampler2D _NormalMap;
float4 _NormalMap_ST;
float _BumpScale;
fixed3 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos:SV_POSITION;
float4 uv:TEXCOORD0;
float3 viewDir: TEXCOORD1;
float3 lightDir:TEXCOORD2;
};
v2f vert(appdata_tan v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy * _DiffuseTexture_ST.xy + _DiffuseTexture_ST.zw;
o.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
TANGENT_SPACE_ROTATION;
o.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex)).xyz;
o.viewDir = mul(rotation,ObjSpaceViewDir(v.vertex)).xyz;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 tangentLightDir = normalize(i.lightDir);
fixed3 tangentViewDir = normalize(i.viewDir);
fixed4 getNormal = tex2D(_NormalMap,i.uv.zw);
fixed3 tangentNormal;
tangentNormal = UnpackNormal(getNormal);
tangentNormal.xy *=_BumpScale;
tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy,tangentNormal.xy)));
fixed3 albedo = tex2D(_DiffuseTexture,i.uv.zy);
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 diffuseLight = _DiffuseColor.rgb * albedo * _LightColor0.rgb * saturate( dot(tangentNormal,tangentLightDir));
float3 newDir = normalize(tangentLightDir + tangentViewDir);
fixed3 specularLight = _SpecularColor.rgb * _LightColor0.rgb * pow( saturate(dot(newDir,tangentNormal)),_Gloss);
fixed3 color = ambientLight + diffuseLight +specularLight;
return fixed4(color.rgb,1);
}
ENDCG
}
}
FallBack "Specular"
}
在世界空间下计算法线:
Shader "Mytest/NormalInWorldSpaceShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_DiffuseTexture("DiffuseTexture",2D) = "white"{}
_NormalMap("NormalMap",2D) = "bump"{}
_BumpScale("BumpScale",Float) = 1
_SpecularColor("SpecularColor",Color)= (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
sampler2D _NormalMap;
float4 _NormalMap_ST;
float _BumpScale;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos: SV_POSITION;
float4 uv:TEXCOORD0;
float4 TtoW0:TEXCOORD1;
float4 TtoW1:TEXCOORD2;
float4 TtoW2:TEXCOORD3;
};
v2f vert(appdata_tan v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy * _DiffuseTexture_ST.xy + _DiffuseTexture_ST.zw;
o.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
float3 worldPos = mul(unity_ObjectToWorld,v.vertex).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{
fixed3 albedo = tex2D(_DiffuseTexture,i.uv.zy);
float3 worldPos = normalize( float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w) );
fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(worldPos));
fixed3 worldViewDir = normalize( UnityWorldSpaceViewDir(worldPos));
fixed3 normalMap = UnpackNormal( tex2D(_NormalMap,i.uv.zw) );
normalMap.xy *= _BumpScale;
normalMap.z = sqrt(1-max(0,dot(normalMap.xy,normalMap.xy)));
fixed3 worldNormal = normalize(half3(dot(i.TtoW0.xyz,normalMap),dot(i.TtoW1.xyz,normalMap),dot(i.TtoW2.xyz,normalMap)));
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 diffuseLight = _LightColor0.rgb * _DiffuseColor.rgb * albedo * max(0,dot(worldLightDir,worldNormal));
float3 newDir = normalize(worldLightDir + worldViewDir);
fixed3 specularLight = _LightColor0.rgb * _SpecularColor.rgb * pow( max(0,dot(newDir,worldNormal)) ,_Gloss);
fixed3 color = ambientLight + diffuseLight + specularLight;
return fixed4(color.rgb,1);
}
ENDCG
}
}
FallBack "Specular"
}
渐变纹理:
一开始纹理只是为了定义颜色,但后来发现,纹理可以存储任何表面信息。
使用渐变纹理,控制漫反射光照效果
Shader "Mytest/RampShader"{
Properties{
_DiffuseColor("DiffuseColor",Color)=(1,1,1,1)
_RampMap("RampMap",2D)="white"{}
_SpecularColor("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
sampler2D _RampMap;
float4 _RampMap_ST;
fixed4 _SpecularColor;
float _Gloss;
struct v2f{
float4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize( UnityObjectToWorldNormal(v.normal) );
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_RampMap);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 worldLight = UnityWorldSpaceLightDir(i.worldPos);
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed halfLMBT = dot(worldLight,i.worldNormal) * 0.5 + 0.5;
fixed3 changeColor = tex2D(_RampMap, fixed2(halfLMBT,halfLMBT)).rgb;
fixed3 diffuseLight = _LightColor0.rgb * _DiffuseColor.rgb * changeColor;
fixed3 worldView = normalize( UnityWorldSpaceViewDir(i.worldPos) );
fixed3 newDir = normalize( worldView + worldLight);
fixed3 specularLight = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0,dot(newDir,i.worldNormal)),_Gloss);
return fixed4(ambientLight+diffuseLight+specularLight,1);
}
ENDCG
}
}
FallBack "Specular"
}
遮罩纹理:
提供一种表面数据,来控制其他数据的变化。
Shader "Mytest/MaskTextureShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_SpecularColor("SpecularColor",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8,256)) = 20
_DiffuseTexture("DiffuseTexture",2D)="white"{}
_BumpMap("BumpMap",2D)="bump"{}
_BumpScale("BumpScale",Float)=1
_MaskMap("MaskMap",2D)="white"{}
_MaskScale("MaskScale",Float)=1
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed3 _DiffuseColor;
fixed3 _SpecularColor;
float _Gloss;
sampler2D _MaskMap;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
sampler2D _BumpMap;
float _BumpScale;
float _MaskScale;
struct v2f{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
float3 lightDir:TEXCOORD1;
float3 viewDir:TEXCOORD2;
};
v2f vert(appdata_tan v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy * _DiffuseTexture_ST.xy + _DiffuseTexture_ST.zw;
TANGENT_SPACE_ROTATION;
o.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex)).xyz;
o.viewDir = mul(rotation,ObjSpaceViewDir(v.vertex)).xyz;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 tangentLightDir = normalize(i.lightDir);
fixed3 tangentViewDir = normalize(i.viewDir);
fixed3 normalMapData = UnpackNormal( tex2D(_BumpMap,i.uv));
normalMapData.xy *= _BumpScale;
normalMapData.z = sqrt(1-max(0,dot(normalMapData.xy,normalMapData.xy)));
fixed3 albedo = tex2D(_DiffuseTexture,i.uv).rgb * _DiffuseColor.rgb;
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed3 diffuseLight = _LightColor0.rgb * albedo * max(0, dot(tangentLightDir,normalMapData));
fixed3 newDir = normalize(tangentLightDir + tangentViewDir);
float maskData = tex2D(_MaskMap,i.uv).r * _MaskScale;
fixed3 specularLight = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0,dot(newDir,normalMapData)),_Gloss) * maskData;
return fixed4(ambientLight + diffuseLight + specularLight,1);
}
ENDCG
}
}
FallBack "Specular"
}
透明
深度缓存(Z-Buffer)
解决物体可见性问题,物体的遮挡关系;
透明度测试(Alpha Test)
Shader "Mytest/AlphaTestShader"{
Properties{
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1)
_DiffuseTexture("DiffuseTexture",2D)="white"{}
_CutOff("cutoff",Range(0,1))=0.5
}
SubShader{
Tags{"Quene"="AlphaTest"
"IgnoreProjector"="True"
"RenderType"="TransparentCutout"
}
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed3 _DiffuseColor;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
float _CutOff;
struct v2f{
float4 pos:SV_POSITION;
float3 worldPos:TEXCOORD0;
fixed3 worldNormal:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize( UnityObjectToWorldNormal(v.normal));
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_DiffuseTexture);
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed3 worldLight = normalize( UnityWorldSpaceLightDir(i.worldPos) );
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed4 textureColor = tex2D(_DiffuseTexture,i.uv);
clip(textureColor.a - _CutOff);
if((textureColor.a - _CutOff)<0.0){
discard;
}
fixed3 diffuseLight = _LightColor0.rgb * _DiffuseColor.rgb * textureColor.rgb * max(0,dot(i.worldNormal,worldLight));
return fixed4(ambientLight + diffuseLight,1);
}
ENDCG
}
}
FallBack ""
}
透明度混合(Alpha Blending)
需要关闭深度写入 将当前像素作为混合因子和深度缓存里的像素做混合,混合方式可以配置
Shader "Mytest/AlphaBlendShader"{
Properties{
_DiffuseColor("DiffuseColor",Color)=(1,1,1,1)
_DiffuseTexture("DiffuseTexture",2D)="white"{}
_AlphaScale("AlphaScale",Range(0,1)) = 1
}
SubShader{
Tags{"Quene"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass{
Tags{"LightMode"="ForwardBase"}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
sampler2D _DiffuseTexture;
float4 _DiffuseTexture_ST;
float _AlphaScale;
struct v2f{
float4 pos:SV_POSITION;
float3 worldPos:TEXCOORD0;
fixed3 worldNormal:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.worldNormal = normalize( UnityObjectToWorldNormal(v.normal) );
o.uv.xy = v.texcoord.xy * _DiffuseTexture_ST.xy + _DiffuseTexture_ST.zw;
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos) );
fixed4 textureColor = tex2D(_DiffuseTexture,i.uv);
fixed3 ambientColor = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed3 diffuseColor = _LightColor0.rgb * _DiffuseColor.rgb * textureColor.rgb * max(0,dot(i.worldNormal,worldLightDir));
return fixed4(ambientColor + diffuseColor,textureColor.a* _AlphaScale);
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
开启深度写入的半透明效果
使用两个pass来渲染模型,第一个Pass开启深度写入,不输出颜色,只是为了把模型的深度值写入深度缓存;第二个Pass进行透明混合,上一个pass得到的深度信息,在这个pass中按照像素深度信息来进行混合。
Shader "Mytest/AlphaBlendUseZWriteShader"{
Properties{
_DiffuseColor("DiffuseColor",Color)=(1,1,1,1)
_DiffuseTexture("DiffuseTexture",2D)="white"{}
_AlphaScale("AlphaScale",Range(0,1)) = 1
}
SubShader{
Tags{"Quene"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass{
ZWrite On
ColorMask 0
}
Pass{
Tags{"LightMode"="ForwardBase"}
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _DiffuseColor;
sampler _DiffuseTexture;
float4 _DiffuseTexture_ST;
float _AlphaScale;
struct v2f{
float4 pos:SV_POSITION;
fixed3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize( UnityObjectToWorldNormal(v.normal) );
o.worldPos = mul(unity_ObjectToWorld,v.vertex ).xyz;
o.uv.xy = TRANSFORM_TEX(v.texcoord,_DiffuseTexture);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed4 textureColor = tex2D(_DiffuseTexture,i.uv);
fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos) );
fixed3 ambientLight = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed3 diffuseLight = _LightColor0.rgb * _DiffuseColor.rgb * textureColor.rgb * max(0,dot(worldLightDir,i.worldNormal));
return fixed4(ambientLight + diffuseLight,_AlphaScale * textureColor.a);
}
ENDCG
}
}
Fallback ""
}
混合
双面透明效果:
Cull 剔除某个面的渲染 Cull Back | Front | Off 剔除背面,前面,关闭剔除
透明度测试 直接关闭剔除 透明度混合 通过使用两个Pass 第一个关闭前面渲染 第二个关闭后面渲染 先渲染背面,再渲染前面
渲染顺序:
|