u3d shader着色器学习笔记(三)——光照

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

标准光照模型(在标准光照模型里,我们把进入摄像机的光分为下面四个部分):

自发光

高光反射(类似镜子的反射)

    specular = 直射光的颜色* pow(max(COS θ(反射光方向和视野方向的夹角), 0), 10);

漫反射(类似石头) 

    兰伯特光照模型:

        Diffuse = 直射光颜色 *  max(0,COS θ(光和法线的夹角))

    半兰伯特光照模型:

         Diffuse = 直射光颜色 *  (cosθ  *0.5 +0.5) θ为光和法线的夹角

环境光(均匀反射)


一些方法:

normalize() 用来把一个向量,单位化(原来的方向保持不表,长度为1)即向量的方向向量

max()用来取得函数中最大的一个

dot 用来取得两个向量的点积

_WorldSpaceLightPos0取得平行光的位置

_LightColor0取得平行光的颜色

UnityObjectToClipPos(*) 这个矩阵用来把一个坐标从模型空间转换到剪裁空间

_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间

UNITY_LIGHTMODEL_AMBIENT用来获取环境光

漫反射在顶点函数中:

Shader" Diffuse Vertex" {//漫反射
	Properties{
		_Diffuse("Diffuse Color",Color) = (1,1,1,1)
	}
		SubShader{
			Pass{
				CGPROGRAM
	#include "Lighting.cginc"//取得第一个直射光的颜色
	#pragma vertex vert
	#pragma fragment frag
			fixed4 _Diffuse;//每一次使用属性中的值在 CGPROGRAM中在引用一次
			struct a2v {
				float4 vertex: POSITION;
				float3 normal :NORMAL;//模型空间下
			};
			struct v2f {
				float4 position :SV_POSITION;
				fixed3 color : COLOR;
			};
			v2f vert(a2v v) {
				v2f f;
				f.position = UnityObjectToClipPos(v.vertex);

				fixed ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//取得环境光

				fixed3 normalDir = mul(v.normal, (float3x3)unity_WorldToObject);//从模型空间转换到世界空间

				fixed3 lightDir =  normalize(_WorldSpaceLightPos0.xyz);//第一个直射光的位置,光的位置就是光的方向

				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, -lightDir), 0)*_Diffuse.rgb;//直射光颜色* 法线和光线的点积*自身rgb色
				
				f.color = diffuse + ambient;//两个颜色叠加为加强,亮度增加,两个颜色融合为相乘亮度不变颜色变化

				return f;
			}

			fixed4 frag(v2f f) :SV_Target{
				return fixed4(f.color,1);
			}
			ENDCG
		}
	}
	Fallback"VertexLit"
}

漫反射在片元函数中:

Shader"Diffuse Fragment" {//漫反射
	Properties{
		_Diffuse("Diffuse Color",Color) = (1,1,1,1)
	}
		SubShader{
			Pass{
				CGPROGRAM
	#include "Lighting.cginc"//取得第一个直射光的颜色
	#pragma vertex vert
	#pragma fragment frag
			fixed4 _Diffuse;//每一次使用属性中的值在 CGPROGRAM中在引用一次
			struct a2v {
				float4 vertex: POSITION;
				float3 normal :NORMAL;//模型空间下
			};
			struct v2f {
				float4 position :SV_POSITION;
				fixed3 worldNormalDir : COLOR0;
			};
			v2f vert(a2v v) {
				v2f f;
				f.position = UnityObjectToClipPos(v.vertex);
				f.worldNormalDir = mul(v.normal, (float3x3)unity_WorldToObject);
				return f;
			}

			fixed4 frag(v2f f) :SV_Target{
				

				fixed ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//取得环境光

				fixed3 normalDir = normalize(f.worldNormalDir);//从模型空间转换到世界空间

				fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//第一个直射光的位置,光的位置就是光的方向

				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, -lightDir), 0)*_Diffuse.rgb;//直射光颜色* 法线和光线的点积*自身rgb色

				fixed3 tempColor = diffuse + ambient;

				return fixed4(tempColor, 1);
			}
			ENDCG
		}
	}
	Fallback"VertexLit"
}

高光反射在顶点函数中

Shader"Custom/ 08 specular vertex" {//漫反射
	Properties{
		_Diffuse("Diffuse Color",Color) = (1,1,1,1)
	}
		SubShader{
			Pass{
				CGPROGRAM
	#include "Lighting.cginc"//取得第一个直射光的颜色
	#pragma vertex vert
	#pragma fragment frag
				fixed4 _Diffuse;//每一次使用属性中的值在 CGPROGRAM中在引用一次
			struct a2v {
				float4 vertex: POSITION;
				float3 normal :NORMAL;//模型空间下
			};
			struct v2f {
				float4 position :SV_POSITION;
				fixed3 color : COLOR;
			};
			v2f vert(a2v v) {
				v2f f;

				f.position = UnityObjectToClipPos(v.vertex);

				fixed ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//取得环境光

				fixed3 normalDir = mul(v.normal, (float3x3)unity_WorldToObject);//从模型空间转换到世界空间

				fixed3 lightDir =  normalize(_WorldSpaceLightPos0.xyz);//第一个直射光的位置,光的位置就是光的方向

				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, -lightDir), 0)*_Diffuse.rgb;//直射光颜色* 法线和光线的点积*自身rgb色
				
				fixed3 reflectDir  =  normalize(reflect(lightDir, normalDir));//取到平行光方向 和法线方向 得到反射光方向

				fixed3 viewDir =	normalize(_WorldSpaceCameraPos.xyz - mul(v.vertex, (float3x3)unity_WorldToObject).xyz);//相机坐标 减去 当前物体坐标点的位置 得到视野坐标向量即方向

				fixed3 specular = _LightColor0.rgb * pow(max(dot(viewDir, reflectDir), 0), 10);//得到高光

				f.color = diffuse + ambient+ specular;//两个颜色叠加为加强,亮度增加,两个颜色融合为相乘亮度不变颜色变化

				return f;
			}

			fixed4 frag(v2f f) :SV_Target{
				return fixed4(f.color,1);
			}
			ENDCG
		}
	}
	Fallback"Diffuse"
}


 
 

猜你喜欢

转载自blog.csdn.net/nihao561/article/details/80452487