PhongAndBelinnPhong光照模型

原理

Phong光照模型

Shader "QStudyShader/Phong"
{
	Properties
	{
		_BaseColor("Base Color",Color) = (1.0,1.0,1.0,1.0)
		_Gloss("Gloss",Range(8,100)) = 20.0
	}
		SubShader
	{
		Pass{
			//我们需要先根据入射光方向和法线方向计算出反射光方向,然后通过反射光方向的和视角方向夹角的余弦值来决定高光的强度。
			Tags { "LightModel" = "ForwardBase"}
			CGPROGRAM
			#include "Lighting.cginc"
			#pragma vertex Vertex
			#pragma fragment Fragment
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
			};
			fixed4 _BaseColor;
			float _Gloss;
			v2f Vertex(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				//将定点从模型转换到世界空间下 用于计算视角方向
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				return o;
			}
			fixed4 Fragment(v2f i) : SV_TARGET {
				//世界空间下法线方向
				fixed3 worldNormal = normalize(i.worldNormal);
				//世界空间下光源方向
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				//反射方向 至于这里为什么要传入-的光源向量 可以看图 因为内置的算法
				fixed3 reflectDir = reflect(-worldLightDir, worldNormal);
				//视角方向
				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));

				//环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _BaseColor.xyz;

				//漫反射
				fixed3 diffuse = _LightColor0.xyz * _BaseColor.xyz * saturate(dot(worldNormal,worldLightDir));

				//高光 [公式] = I * Max(0,r.v)的Gloss次方 r = 反射向量 v = 视角向量
				fixed3 specular = _LightColor0.xyz * pow(saturate(dot(reflectDir,worldNormal)),_Gloss);
				//最后高光 + 环境光 + 漫反射
				return fixed4(specular + ambient + diffuse, 1.0);
			}
			ENDCG
		}
	}
}


BelinnPhong光照模型

Shader "QStudyShader/BelinnPhong"
{
	Properties
	{
		_BaseColor("Base Color",Color) = (1.0,1.0,1.0,1.0)
		_Gloss("Gloss",Range(8,100)) = 20.0
	}
		SubShader
	{
		
		Pass{
			Tags{ "LightModel" = "FrowardBase"}
			CGPROGRAM
			#include "Lighting.cginc"
			#pragma vertex Vertex
			#pragma fragment Fragment
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
			};
			fixed4 _BaseColor;
			float _Gloss;
			v2f Vertex(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				return o;
			}
			fixed4 Fragment(v2f i) : SV_TARGET{
				//法线方向
				fixed3 worldNormal = normalize(i.worldNormal);
			//需要求半程向量 = 光源方向 + 视角方向
			//光源方向
			fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
			//视角方向 需要根据模型世界坐标位置 计算
			fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
			//半程方向
			fixed3 halfDir = normalize(viewDir + worldLightDir);
			//环境光
			fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _BaseColor.xyz;
			//漫反射
			fixed3 diffuse = _LightColor0.xyz * _BaseColor.xyz * saturate(dot(worldLightDir,worldNormal));
			//高光
			fixed3 specular = _LightColor0.xyz * pow(saturate(dot(halfDir, worldNormal)), _Gloss);
			return fixed4(ambient + diffuse + specular,1.0);
			}
			ENDCG
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值