unity3D Shader<三>漫反射

一、漫反射的说明

         对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度有关,也就是入射光线与此点的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线强度和颜色,用N表示此点的发线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:

         Lum = C * max(0,cos<L,N>)

         <L,N>表示的是方向矢量L和N之间的夹角,其cos就是这两个方向的点乘积,在unity通过Cg的标准函数库dot(L,N)来完成。这个值对于背向光线的点来说为负,其实就是对其照明为0,因此使用标准函数库中的max(0,value)来对结果进行一些控制。计算到此为此我们叫按照这种方式对物体进行照明计算的模型叫做Lambert。

对应的代码段为#pragma surface surf Lambert。

(注意,这个Lambert可以命名为其他的名字,相应的写光照模型函数时,其命名也要改变比如Unity内置三个Lighting Model函数,

如果用#pragma surface surf Lambert命名光照模型函数的话

这三个的函数名为

              half4 LightingLambert(SurfaceOutput s, half3 lightDir, half atten){} 

      这个函数被用于forward rendering(正向渲染),但是不需要考虑view direction(观察角度)时。

    • [plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
      1. half4 LightingLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){}  

      这个函数被用于forward rendering(正向渲染),并且需要考虑view direction(观察角度)时。
    • [plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
      1. half4 LightingLambert_PrePass (SurfaceOutput s, half4 light){}  

      这个函数被用于需要使用defferred rendering(延迟渲染)时。

如果用#pragma surface surf BasicDiffuse命名,则后面书写这些函数时,就如下面所示

half4 LightingBasicDiffuse

half4 LightingBasicDiffuse_PrePass


二、具体漫反射代码

Shader "Custom/MyLightTest" {
	Properties {
		_EmissiveColor("自发光的颜色:",Color) = (1,1,1,1)
		_AmbientColor("环境光的颜色:",Color) = (1,1,1,1)
		_Change("改变的值:",Range(0,10)) = 2.5
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf BasicDiffuse 
		//对上面一行的解释
		//surface - 声明的是一个表面着色器
		//surf - 着色器代码的方法的名字
		//Lambert - 使用的光照模型。
		//规则#pragma surface surfaceFunction lightModel [optionalparams]
		//surface - 声明的是一个表面着色器
		//surfaceFunction - 着色器代码的方法的名字
		//lightModel - 使用的光照模型。
		
		//#pragma surface surf BasicDiffuse 自定义了光照模型为BasicDiffuse,
		//下面的函数为实现这个自定义的光照模型,函数命名规则为Lightin加上自定义的自定义的光照模型名称
		inline float4 LightingBasicDiffuse	(SurfaceOutput s,fixed3 lightDir,fixed atten)
		{
			//漫反射光的公式:I = Aintensity*Acolor + Dintensity*Dcolor *N.L 
			//前面的Aintensity*Acolor是环境光的公式(得到场景中光源的颜色)
			float difLight = max(0,dot(s.Normal,lightDir));//这里相当于漫反射公式的N.L
			float4 col;
			//_LightColor0.rgb(Unity提供)光源颜色
			//s.Albedo为当前材质反射率(从surf函数计算后输出)
			//atten表明了光线的衰减率根据DX中的衰减定义,这是固定衰减
			//这里用的乘法公司  物体自身的镜面放射*场景中光源的颜色*漫反射强度*衰减率*自行修改的值 
			col.rgb =  s.Albedo * _LightColor0.rgb * (difLight * atten * 2);  
			col.a = s.Alpha;  
    		return col; 
		}

		sampler2D _MainTex;
		float4 _EmissiveColor;
		float4 _AmbientColor;
		float _Change;
		
		struct Input {
			float2 uv_MainTex;
		};
		
		void surf (Input IN, inout SurfaceOutput o) {
			float4 c = pow((_EmissiveColor + _AmbientColor),_Change);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值