卜若的代码笔记-unityshader系列-第十六章:光照模型的物理意义及高光反射模型&逐像素计算光照模型

1.光照模型的物理意义

我们先看一下漫反射的定义

漫反射颜色值 = (光源的rgb*定义的漫反射强度rgb)*max(0,dot(基于世界坐标系的模型法线,光源在世界空间坐标系下的位置))

 

先解释一下:

(光源的rgb*定义的漫反射强度rgb)

意味着:光源的rgb,和强度rgb的一种单存的颜色叠加。

其实到这一步,我们看到的渲染的模型的颜色就已经和光照挂钩了。我们可以这样写

 

saturate函数是一个饱和度计算函数,如果dot(objectNormal,lightPos)<0就会返回0,否则返回dot(objectNormal,lightPos);

 

那么最后一项,dot(objectNormal,lightPos),意味着什么?

我们可以将它视为一种强度变化。

 

黄色是光向量,指向光源,红色是模型在世界的法线。

这个一乘下来就相当于于什么呢,相当于光在法线上的投影。也就是光照在它身上应该显示多强的颜色。

_WorldSpaceLightPos0.xyz指的就是光向量。

 

所以,投影的话,最好还是normal一下,两个的长度都是1,投影的意义才会标准,当然,不加normal目前我没看到什么太大的问题。

2. 高光反射模型

反射的高光色= (叠加色:自发光颜色*光源颜色)*pow(归1化(反射光在视线方向的投影),高光强度)

叠加色很容易理解

			//来自于CG函数库的_LightColor0.rgb
			float3 lightColor = _LightColor0.rgb;
			//自定义的_Color
			float3 emmisiveColor = _Color.rgb;

			

			float3 overLayColor = float3((lightColor.r*colorPower.r), (lightColor.g*colorPower.g)
				, (lightColor.b*colorPower.b));

pow函数,就是一个求次方函数

归1化(观察角度在反射光的投影) ->max(0,dot(reflectLightDir,viewDir))

2.1reflectLightDir 的计算:

fixed3 reflectDir = normalize(reflect(-worldlight,worldnormal));

画一张图

入射光其实等于反向的

2.2viewDir的计算

viewDir = 观察摄像机的位置 - 顶点在世界坐标的位置

 

fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex).xyz);

看下实验吧:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Unlit/Mesh7"
{
	Properties
	{
		_Color("Color",Color) = (1,1,1,1)
		_MainTex("Texture", 2D) = "white" {}
		_Gloss("Gloss",Range(0,10)) = 1
	}
		SubShader
	{
		Tags {"LightModel" = "ForwardBase" }
		LOD 100

		Pass
		{

		//ZWrite Off
		//Blend SrcAlpha OneMinusSrcAlpha

		CGPROGRAM
		#pragma vertex vertex
		#pragma fragment fragment
		// make fog work
		// #pragma multi_compile_fog

		#include "UnityCG.cginc"
		#include "Lighting.cginc"
		struct fromCpu
		{
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
			float3 normal:NORMAL;
		};

		struct v2f
		{
			float2 uv : TEXCOORD0;
			float4 vertex : POSITION;
			float4 color: COLOR0;
			float3 normal:TEXCOORD1;
			float3 wPos :TEXCOORD2;
		};

		sampler2D _MainTex;
		float4 _MainTex_ST;
		fixed4 _Color;
		fixed _Gloss;

		half4 c1;
		v2f vertex(fromCpu v)
		{
			v2f o;
			float3 objectNormal = UnityObjectToWorldNormal(v.normal);	
			float3 lightDir = _WorldSpaceLightPos0.xyz;
			objectNormal = normalize(objectNormal);
			lightDir = normalize(lightDir);

			//来自于CG函数库的_LightColor0.rgb
			float3 lightColor = _LightColor0.rgb;
			//自定义的_Color
			float3 emmisiveColor = _Color.rgb;

			

			float3 overlayColor = float3((lightColor.r*_Color.r), (lightColor.g*_Color.g)
				, (lightColor.b*_Color.b));
			
			
			float3 reflectDir = reflect(-lightDir, objectNormal);
			reflectDir = normalize(reflectDir);
			float3 cameraPos = _WorldSpaceCameraPos.xyz;
			float3 viewDir = cameraPos - v.vertex.xyz;
			viewDir = normalize(viewDir);


			//高光反射公式
			float3 glossColor = overlayColor * pow(saturate(dot(viewDir, reflectDir)), _Gloss);

			o.normal = UnityObjectToWorldNormal(v.normal);
			o.vertex = UnityObjectToClipPos(v.vertex);
			o.color.rgb = glossColor;
			o.color.rgb += UNITY_LIGHTMODEL_AMBIENT.xyz;
			return o;
		}

		fixed4 fragment(v2f i) : SV_Target
		{
			
			return i.color;
		}
		ENDCG
	}
	}
}

看下效果:

 

这个效果感觉不够丝滑,看它那个光斑一块一块的,我决定放在片元着色器上去计算

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Unlit/Shader8"
{
	Properties
	{
		_Color("Color",Color) = (1,1,1,1)
		_MainTex("Texture", 2D) = "white" {}
		_Gloss("Gloss",Range(0,10)) = 1
	}
		SubShader
		{
			Tags {"LightModel" = "ForwardBase" }
			LOD 100

			Pass
			{

			//ZWrite Off
			//Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
			#pragma vertex vertex
			#pragma fragment fragment
			// make fog work
			// #pragma multi_compile_fog

			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			struct fromCpu
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal:NORMAL;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : POSITION;
				float4 color: COLOR0;
				float3 normal:TEXCOORD1;
				float3 wPos :TEXCOORD2;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			fixed _Gloss;

			half4 c1;
			v2f vertex(fromCpu v)
			{
				v2f o;
				float3 objectNormal = UnityObjectToWorldNormal(v.normal);
				objectNormal = normalize(objectNormal);

				
				
				o.normal = objectNormal;
				o.vertex = UnityObjectToClipPos(v.vertex);
				
				o.color.rgb = UNITY_LIGHTMODEL_AMBIENT.xyz;
				return o;
			}

			fixed4 fragment(v2f i) : SV_Target
			{	
				//光向量,指向光
				float3 lightDir = _WorldSpaceLightPos0.xyz;
				lightDir = normalize(lightDir);
				//光色
				float3 lightColor = _LightColor0.rgb;
				//自发光
				float3 emmisiveColor = _Color.rgb;


				//叠加光
				float3 overlayColor = float3((lightColor.r*emmisiveColor.r), (lightColor.g*emmisiveColor.g)
					, (lightColor.b*emmisiveColor.b));


				//反射光
				float3 reflectDir = reflect(-lightDir, i.normal);
				reflectDir = normalize(reflectDir);
				
				//摄像机位置
				float3 cameraPos = _WorldSpaceCameraPos.xyz;
				//观察向量
				float3 viewDir = cameraPos - i.vertex.xyz;
				viewDir = normalize(viewDir);


				//高光反射公式
				float3 glossColor = overlayColor * pow(saturate(dot(viewDir, reflectDir)), _Gloss);

				i.color.rgb += glossColor;
				return i.color;
			}
			ENDCG
		}
		}
}

众享丝滑~

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值