005-基础Shader-Blinn光照的实现

 用于学习《Unity Shader 入门精要》过程记录

注意点:

1.顶点法线转换至三维空间中,比较特殊,与一般转换不同。

2.Blinn关照计算与理想的反射计算不同。采用:视角向量+主光线向量

在场景中添加一个球体,将Blinn光照赋值给其Material,具体效果如下图

 

Shader "ShaderStudy/005"
{
	//属性
	Properties
	{
		//定义一个颜色属性 ColorDiffuse
		_ColorDiffuse ("ColorDiffuse",Color)=(1,1,1,1)
		//定义一个颜色属性 ColorSpecular 用于高光反射
		_ColorSpecular("ColorSpecular",Color)=(1,1,1,1)
		//定义一个数值 FloatGloss 用于控制高光区域大小	(值越大,反射区域越小)
		_FloatGloss("FloatGloss",Range(1,200))=3
	}

	SubShader
	{
		Pass
		{
			//定义光照模型为 ForwardBase
			Tags{"LightMode"="ForwardBase"}

			//CG 程序开始
			CGPROGRAM

			//编译指令 顶点着色器代码在 name(vert)中
			#pragma vertex vert
			//编译指令 片元着色器代码在 name(frag)中
			#pragma fragment frag

			//添加Lighting.cginc库文件 包含_LightColor0
			#include "Lighting.cginc"

			//声明颜色属性变量  _ColorDiffuse
			fixed4 _ColorDiffuse;
			//声明颜色属性变量  _ColorSpecular
			fixed4 _ColorSpecular;
			//声明Float属性变量  _FloatGloss
			float _FloatGloss;

			//定义结构体 用于顶点着色器的输入数据
			struct v2a
			{
				//定义 pos 为模型顶点位置信息
				float4 pos:POSITION;
				//定义 normal 为模型顶点法线信息
				float3 normal:NORMAL;
			};


			//定义一个结构,用于顶点着色器的输出数据
			struct v2f
			{
				//定义 posSV 为存放顶点的裁剪空间位置
				float4 posSV:SV_POSITION;
				//定义 normalWorld 为存放顶点的法线在三维空间中的单位向量 存贮于TEXCOORD0中
				float3 normalWorld:TEXCOORD0;
				//定义 posWorld 为存放顶点在三维空间中的位置 存贮于TEXCOORD1中
				float3 posWorld:TEXCOORD1;
			};

			//顶点着色器 输入参数为结构体v2a(name)  输出参数为结构体 v2f(name)
			v2f vert(v2a v)
			{
				v2f o;
				//计算顶点坐标在 裁剪空间中的位置
				o.posSV=UnityObjectToClipPos(v.pos);
				//计算顶点法线在三维空间中的单位向量
				//法线在空间中的单位向量算法,不同于一般的换算,主要时因为当模型进行缩放时,采用一般方式会算出错误的值
				o.normalWorld=normalize( mul(v.normal,(float3x3)unity_WorldToObject));
				//计算顶点在三维空间中的位置
				o.posWorld=mul(unity_ObjectToWorld,v.pos);
				return o;
			}


			//片元着色器 输入参数为结构体 v2f(name) 输出存贮到渲染目标
			fixed4  frag(v2f i) : SV_Target
			{
				//获取环境光信息
				fixed3 colorAmblent=UNITY_LIGHTMODEL_AMBIENT.xyz;

				//获取主平行光在空间坐标系下的单位向量
				fixed3 normalWorldLightDir=normalize(_WorldSpaceLightPos0.xyz);

				//片元光照强度*自定义颜色属性*saturate(两向量的投影值Float)
				//片元向量和平行光之间的关系决定顶点光照的强度,平行时最强,垂直时最弱
				fixed3 colorDiffuse=_LightColor0.rgb*_ColorDiffuse.rgb*saturate(dot(i.normalWorld,normalWorldLightDir));
				//半兰伯特光照效果,使物体暗的地方更亮
				//fixed3 colorDiffuse=_LightColor0.rgb*_ColorDiffuse.rgb*(dot(i.normalWorld,normalWorldLight)*0.5+0.5);
				
				//正常的反射效果实现
				//{
				//	//顶点的反射向量
				//	fixed3 normalReflect=normalize(reflect(-normalWorldLight,i.normalWorld));
				//	//顶点指向摄像机的单位向量  
				//	fixed3 normalView=normalize(_WorldSpaceCameraPos.xyz-i.posWorld.xyz);
				//	//片元反射颜色
				//	fixed3 colorSpecular=_LightColor0.rgb*_ColorSpecular.rgb*pow(saturate(dot(normalReflect,normalView)),_FloatGloss);
					//环境光的颜色+片元光照颜色
					//return fixed4(colorAmblent+colorDiffuse+colorSpecular,1.0);
				//}

				//Blinn 光照效果
				{
					//顶点指向摄像机的单位向量  
					fixed3 normalView=normalize(_WorldSpaceCameraPos.xyz-i.posWorld.xyz);
					//场景中的主光线向量+视角向量  根据经验这样计算出的效果比较理想
					fixed3 normalHalf=normalize(normalWorldLightDir+normalView);
					fixed3 colorSpecular=_LightColor0.rgb*_ColorSpecular.rgb*pow(saturate(dot(i.normalWorld,normalHalf)),_FloatGloss);
					//环境光的颜色+片元光照颜色+反光颜色
					return fixed4(colorAmblent+colorDiffuse+colorSpecular,1.0);
				}
			}
			//CG程序结束
			ENDCG
		}
	}
	FallBack "Specular"
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值