Shader学习笔记(五)

来源:互联网 发布:扑克记忆训练软件 编辑:程序博客网 时间:2024/05/01 21:31

编写漫反射Shader代码

什么是光照模型
光照模型就是一个公式,使用这个公式来计算在某个点的光照效果


漫反射 Diffuse = 直射光颜色* max(0,Cos夹角)(光和法线的夹角)当夹角为1是光是直射,小于零则是光照射不到的地方
Shader"MyShader/Demo4"{Properties{_Diffuse("Diffuse",Color) = (1,1,1,1)}SubShader{Pass{Tags{"LightMode" = "ForwardBase"}//只有定义了正确的LightMode才能得到一些Unity的内置光照变量CGPROGRAM// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices#pragma exclude_renderers gles#include "Lighting.cginc"//将Light.cgine引入,相当于引入dll命名空间,包含unity的内置文件,才可以使用Unity的内置函数//取得第一个直射光的颜色_LightColor0  Unity内置变量,在Light.cginc中定义了#pragma vertex vert#pragma fragment fragfixed3 _Diffuse;struct a2v {float4 vertex:POSITION;//语义:把模型空间下的顶点坐标填充给vertexfloat3 normal:NORMAL;//语义:吧模型空间下的法线方向填充给normalfloat4 texcoord:TEXCOORD0;//语义:告诉unity把第一套纹理坐标填充给texcoord};//struct v2f {float4 position:SV_POSITION;float3 temp:COLOR;};v2f vert(a2v v) {v2f f;f.position = UnityObjectToClipPos(v.vertex);fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;fixed3 normalDir = mul(v.normal, (float3x3)unity_WorldToObject);//这个矩阵用来把一个方向从世界空间转换到模型空间//对于每个顶点来说,光的位置就是光的方向,因为光是平行光fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1)fixed3 diffuse = _LightColor0.rgb*max(0,dot(normalDir,lightDir))*_Diffuse.rgb;//取得每个顶点漫反射的颜色值f.temp = diffuse+ ambient;return f;}fixed4 frag(v2f f) :SV_Target{return fixed4(f.temp,1);}ENDCG}}FallBack "VertexLit"}
颜色叠加直接相加一般亮度会增加

颜色融合直接相乘 亮度不会改变颜色会改变

在标准光照模型里面,我们把进入摄像机的光分为下面四个部分
自发光
高光反射
漫反射
环境光

Shader中用到的一些函数
normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1)
max() 用来取得函数中最大的一个
dot 用来取得两个向量的点积
_WorldSpaceLightPos0 取得平行光的位置
_LightColor0取得平行光的颜色
UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
UNITY_LIGHTMODEL_AMBIENT用来获取环境光

半兰伯特光照模型
Diffuse = 直射光颜色 *( cosθ *0.5 +0.5 ) Cos的值为-1到1,乘以0.5范围在-0.5-0.5之间再加上0.5则将范围限制在了0-1之间。
兰伯特光照模型
Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) )  cosθ = 光方向· 法线方向

原创粉丝点击