unity的光源类型9.2.2


// Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight'

Shader "Unlit/Chapter9-ForwardRendering"
{
	Properties{
		_Diffuse("Diffuse",Color) = (1,1,1,1)
		_Specular("Specular",Color) = (1,1,1,1)
		_Gloss("Gloss",Range(8.0,256)) = 20
	}
		SubShader
	{

		//Base Pass
		Pass
	{
		//pass for ambient light & first pixel light(directional light)
		Tags{ "LightMode" = "ForwardBase" }
		CGPROGRAM

		//Apparently need to add this declaration
#pragma multi_computer_fwdbase

#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"


		fixed4 _Diffuse;
		fixed4 _Specular;
		float _Gloss;

		struct a2v {
			float4 vertex:POSITION;
			float3 normal:NORMAL;
		};
		struct v2f {
			float4 pos:SV_POSITION;
			float3 worldNormal : TEXCOORD0;
			float3 worldPos : TEXCOORD1;
		};
		v2f vert(a2v v) {
			v2f o;
			o.pos = UnityObjectToClipPos(v.vertex);
			o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
			o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
			return o;
		}
		fixed4 frag(v2f i) :SV_Target{

			//Get ambient term
			fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

			fixed3 worldNormal = normalize(i.worldNormal);
			fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

			//compute diffuse term
			fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLightDir));

			fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
			fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
			//Blinn-Phong光照模型
			fixed3 halfDir = normalize(worldLightDir + viewDir);

			//compute specular term
			fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(worldNormal, halfDir)), _Gloss);

			//The attenution of directional light is always1
			fixed attent = 1.0;


			//
			return fixed4(ambient + (diffuse + specular)*attent, 1.0);
			}


				ENDCG

			}



		//Additional pass
Pass
{
	//pass for other pixel lights
	Tags{ "LightMode" = "ForwardAdd" }
	Blend One One
	//如果没有Blend命令,Additional pass会直接覆盖之前的光照结果

	CGPROGRAM

	//Apparently need to add this declaration
#pragma multi_computer_fwdadd

#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"


	fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;

struct a2v {
	float4 vertex:POSITION;
	float3 normal:NORMAL;
};
struct v2f {
	float4 pos:SV_POSITION;
	float3 worldNormal : TEXCOORD0;
	float3 worldPos : TEXCOORD1;
};
v2f vert(a2v v) {
	v2f o;
	o.pos = UnityObjectToClipPos(v.vertex);
	o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
	o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
	return o;
}
//片元着色器
fixed4 frag(v2f i) :SV_Target{
	fixed3 worldNormal = normalize(i.worldNormal);

//计算不同光源的方向

//通过判断是否定义了USING_DIRECTIONAL_LIGHT来决定当前处理的逐像素光源类型,是否是平行光源
#ifdef USING_DIRECTIONAL_LIGHT
//是平行光源的话直接获得光源方向
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
#else
//如果不是,需要用世界空间下的光源位置减去世界空间下的顶点位置
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
#endif





//compute diffuse term
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLightDir));

//fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
//Blinn-Phong光照模型
fixed3 halfDir = normalize(worldLightDir + viewDir);

//compute specular term
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(worldNormal, halfDir)), _Gloss);



//判断光源类型
#ifdef USING_DIRECTIONAL_LIGHT
//是平行光的话衰减值为1
fixed atten = 1.0;
#else


//不是平行光的话unity选择用一张纹理作为查找表(Lookup Table,LUT)以在片元着色器中得到光源的衰减
//得到光源空间下的坐标
//float3 lightCoord = mul(_LightMatrix0, float4(i.worldPos, 1)).xyz;
//使用该坐标对衰减纹理进行采样得到衰减值
//fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;


/*float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz;

fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;*/

//然而,为什么注释掉了!!!!因为不知道什么原因运行不了!!数学公式计算倒是可以的

float distance = length(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
//线性衰减
fixed atten = 1.0 / distance;





#endif

//
return fixed4((diffuse + specular) * atten, 1.0);
//return fixed4(ambient + (diffuse + specular)*attent, 1.0);
}

ENDCG

}
}
}

非常痛苦,没有多少代码,也不是很难理解,用了一天的时间才弄出来。。一个是Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight'比较无语,再有目前还没找出来原因,用纹理来计算没成功,公式计算倒是可以运行,可能也是版本的原因吧。

帧调试器(Frame Debugger)

位置:window->Frame Debugger

猜你喜欢

转载自blog.csdn.net/ABigDeal/article/details/82791864