主要使用 LightingLambert_GI(o,giInput,gi) 采样光照贴图来实现间接光照和阴影的效果
使用 LightingLambert(o,gi) 来实现间接光照和直接光照的混合
一、LightingLambert_GI(o,giInput,gi)
unityGI_Base中实现不同类型的分支来采样光照贴图
例如 #if defined(LIGHTMAP_ON)代表当打开烘焙全局光照采样光照贴图(lightmapUV.xy)来实现光照效果
#ifdef DYNAMICLIGHTMAP_ON代表当打开实时全局光照采样光照贴图(lightmapUV.zw)来实现光照效果
unity中与LightingLambert()函数相关的内置的宏
inline UnityGI UnityGI_Base(UnityGIInput data, half occlusion, half3 normalWorld)
{
//声明了一个UnityGI类型的变量o_gi,用来存储最终计算的GI信息
UnityGI o_gi;
//重置UnityGI
ResetUnityGI(o_gi);
//计算在Distance Shadowmask中实时阴影与烘焙阴影的混合过度
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
data.atten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
#endif//将主平行灯传入GI中 UnityGIInput giInput; data=giInput
o_gi.light = data.light;
//将衰减加入到灯光的颜色中
o_gi.light.color *= data.atten;#if UNITY_SHOULD_SAMPLE_SH
o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
#endif//当使用Baked GI时
#if defined(LIGHTMAP_ON)
// Baked lightmaps
//用lightmapUV.xy的UV坐标对unity_Lightmap贴图进行采样存储到bakedColorTex这个变量中
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
//DecodeLightmap对采样后的贴图进行解码
half3 bakedColor = DecodeLightmap(bakedColorTex);//当directional(定向光)模式开启时
#ifdef DIRLIGHTMAP_COMBINED
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif#else // not directional lightmap
o_gi.indirect.diffuse += bakedColor;#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap(o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif#endif
#endif
//当采用Realtime GI时
#ifdef DYNAMICLIGHTMAP_ON
// Dynamic lightmaps
//采样unity_DynamicLightmap贴图
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);#ifdef DIRLIGHTMAP_COMBINED
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);
#else
o_gi.indirect.diffuse += realtimeColor;
#endif
#endifo_gi.indirect.diffuse *= occlusion;
//最终的计算结果
return o_gi;
}inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld)
{
return UnityGI_Base(data, occlusion, normalWorld);
}
inline void LightingLambert_GI (SurfaceOutput s,UnityGIInput data,inout UnityGI gi)
{
gi = UnityGlobalIllumination (data, 1.0, s.Normal);
}
二、LightingLambert_GI(o,giInput,gi)(LightingLambert_GI中的参数属性)
有 SurfaceOutput o, UnityGIInput giInput , UnityGI gi
SurfaceOutput o
定义模型的顶点数据
struct SurfaceOutput {
fixed3 Albedo; //漫反射
fixed3 Normal; //法线
fixed3 Emission; //自发光
half Specular; //高光
fixed Gloss; //光滑度
fixed Alpha; //透明度
};
UnityGIInput giInput
struct UnityGIInput
{
直接光照
UnityLight light; //pixel light, sent from the engine
float3 worldPos;
half3 worldViewDir; //世界空间下的视角方向
half atten; //衰减
half3 ambient; //环境色
用来采样纹理贴图的UV坐标
float4 lightmapUV; //.xy = static lightmap UV, .zw = dynamic lightmap UV
....
}
UnityGI gi
直接光照
struct UnityLight
{
half3 color; //光照颜色
half3 dir; //光照方向
};
间接光照
struct UnityIndirect
{
half3 diffuse; //漫反射颜色
half3 specular; //高光色
};
struct UnityGI
{
UnityLight light; //直接光照
UnityIndirect indirect; //间接光照
};
三、fixed4 c=LightingLambert(o,gi);(直接光照与间接光照的混合)
LightingLambert(o,gi)函数需要使用到的内置宏
#if defined(UNITY_SHOULD_SAMPLE_SH) || defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
#define UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
#endif//实现lambert光照模型
inline fixed4 UnityLambertLight(SurfaceOutput s,UnityLight light)
{
fixed diff = max(0, dot(s.Normal, light.dir));fixed4 c;
c.rgb = s.Albedo * light.color * diff;
c.a = s.Alpha;
return c;
}inline fixed4 LightingLambert(SurfaceOutput s, UnityGI gi)
{
fixed4 c;
c = UnityLambertLight(s, gi.light);
//是否要应用间接光 将间接光照与直接光照进行混合
#ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
c.rgb += s.Albedo * gi.indirect.diffuse;
#endifreturn c;
}
四、在片元着色器中对函数的参数进行初始化操作
初始化函数(初始化为0)
UNITY_INITIALIZE_OUTPUT();
fixed4 frag (v2f i) : SV_Target
{
//顶点的表面数据
SurfaceOutput o;
UNITY_INITIALIZE_OUTPUT(SurfaceOutput,o) // 使SurfaceOutPut中的参数初始化为0
o.Normal=i.worldNormal; //定义NORMAL的值
o.Albedo=1; //定义Albedo漫反射UnityGI gi;
// 初始化GI
UNITY_INITIALIZE_OUTPUT(UnityGI,gi)// 定义主直接光照(平行灯)的灯光颜色
gi.light.color=_LightColor0;// 定义主直接光照(平行灯)的位置方向
gi.light.dir=_WorldSpaceLightPos0;// 定义间接光照的漫反射
gi.indirect.diffuse=1;// 定义间接光照的高光
gi.indirect.specular=0;//实时的阴影贴图纹理采样
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);UnityGIInput giInput;
// 初始化操作
UNITY_INITIALIZE_OUTPUT(UnityGIInput,giInput);
giInput.light=gi.light; // 主平行灯 直接光照giInput.worldPos=i.worldPos;
giInput.worldViewDir=normalize(_WorldSpaceCameraPos-i.worldPos);
//将实时的阴影赋予giInput.atten,将实时阴影与采样阴影进行混合
giInput.atten=atten;giInput.ambient=0;
// 在实时全局光照或烘焙全局光照开启的情况下才会用到lightmapUV,所以要进行分支判断
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
giInput.lightmapUV=i.lightmapUV;
#endif//GI 间接光照的计算
LightingLambert_GI1(o,giInput,gi);
//UnityGI UnityGI_Base1(UnityGIInput data, half occlusion, half3 normalWorld)
// gi=UnityGI_Base1(giInput,1,o.Normal); 与LightingLambert_GI1(o,giInput,gi)功能相同//GI直接光照的计算
fixed4 c=LightingLambert1(o,gi);return c;
}
五、关于lightmapUV的使用
只有在开启了烘焙全局光照(Baked GI)和实时全局光照(Realtime GI)的情况下才会使用lightmapUV来采样光照贴图
所以在Shader中对lightmapUV声明时需进行分支判断
在顶点着色器的输入输出结构体中都添加下面语句(当开启烘焙GI和实时GI时声明lightmapUV)
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
float4 lightmapUV:TEXCOORD1;
#endif
所以需要在结构体前添加宏开关#pragma multi_compile_fwdbase
需要注意的是lightmapUV不能使用第一套UV,否则会出现错误
在顶点着色器中使用相关的语句使lightmapUV的平铺和偏移有效
//Baked GI(静态)//使UV的平铺和偏移有效
#if defined(LIGHTMAP_ON)
o.lightmapUV.xy=v.lightmapUV*unity_LightmapST.xy+unity_LightmapST.zw;
#endif//LightMapUV中的zw代表的是动态的GI(Realtime GI)
#if defined(DYNAMICLIGHTMAP_ON) o.lightmapUV.zw=v.lightmapUV*unity_DynamicLightmapST.xy+unity_DynamicLightmapST.zw;
#endif
o.lightmapUV.xy 代表Baked GI的光照贴图
o.lightmapUV.zw代表Realtime GI的光照贴图
在片段着色器中将lightmapUV传给UnityGIInput中的lightmapUV
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
giInput.lightmapUV=i.lightmapUV;
#endif
六、添加实时的阴影效果
此时的Shader中并没有添加实时的阴影效果,(赋予该Shader的模型只有烘焙阴影,并不会产生跟随平行灯光而产生的实时阴影),所以要通过添加ShadowCaster Pass和实时的阴影采样语句来实现实时的阴影效果(利用之前学习的知识,忘记的话可以看前面的文章)
需要添加与阴影接收相关的变体
#pragma multi_compile SHADOWS_SCREEN DIRECTIONAL
1.在顶点着色器的输出结构体中添加
UNITY_LIGHTING_COORDS(2,3)
//定义了两个变量,同时定义灯光衰减和实时阴影采样的变量
2.在顶点着色器中添加
UNITY_TRANSFER_LIGHTING(o,v.lightmapUV.xy);
3.在片元着色器中添加
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);
//实时的阴影贴图纹理采样以及灯光衰减的计算
七、自定义的.cginc文件
如何创建自己的cginc文件?
首先创建一个文件夹(Folder),用来存放自定义的cginc文件,然后再创建一个Shader
然后右击Shader,选择在文件夹中打开Shader文件
最后将文件重命名为.cginc后缀的文件即可
如何引用自定义的cginc文件?
自定义的cginc文件代码
#ifndef MYGLOBAL_CGINCLUDE
#define MYGLOBAL_CGINCLUDE
//将UnityGI的相关方法都添加到自定义的cginc文件中,并将unity中内置的函数名更改一下,以便区分
// 计算Lambert光照模型的式子
//SurfaceOutput表面的输出数据
#if defined(UNITY_SHOULD_SAMPLE_SH) || defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
#define UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
#endif
//直接光照Lambert的计算结果
inline fixed4 UnityLambertLight1(SurfaceOutput s,UnityLight light)
{
fixed diff = max(0, dot(s.Normal, light.dir));
fixed4 c;
c.rgb = s.Albedo * light.color * diff;
c.a = s.Alpha;
return c;
}
inline fixed4 LightingLambert1(SurfaceOutput s, UnityGI gi)
{
fixed4 c;
c = UnityLambertLight1(s, gi.light);
//是否要应用间接光 将间接光照与直接光照进行混合
#ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
c.rgb += s.Albedo * gi.indirect.diffuse;
#endif
return c;
}
inline void ResetUnityLight1(out UnityLight outLight)
{
outLight.color = half3(0, 0, 0);
outLight.dir = half3(0, 1, 0); // Irrelevant direction, just not null
outLight.ndotl = 0; // Not used
}
inline void ResetUnityGI1(out UnityGI outGI)
{
ResetUnityLight(outGI.light);
outGI.indirect.diffuse = 0;
outGI.indirect.specular = 0;
}
inline UnityGI UnityGI_Base1(UnityGIInput data, half occlusion, half3 normalWorld)
{
UnityGI o_gi;
ResetUnityGI1(o_gi);
// Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
data.atten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
#endif
o_gi.light = data.light;
o_gi.light.color *= data.atten;
#if UNITY_SHOULD_SAMPLE_SH
o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
#endif
#if defined(LIGHTMAP_ON)
// Baked lightmaps
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
half3 bakedColor = DecodeLightmap(bakedColorTex);
#ifdef DIRLIGHTMAP_COMBINED
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif
#else // not directional lightmap
o_gi.indirect.diffuse += bakedColor;
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap(o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif
#endif
#endif
#ifdef DYNAMICLIGHTMAP_ON
// Dynamic lightmaps
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap,data.lightmapUV.zw);
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);
#ifdef DIRLIGHTMAP_COMBINED
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);
#else
o_gi.indirect.diffuse += realtimeColor;
#endif
#endif
o_gi.indirect.diffuse *= occlusion;
return o_gi;
}
/*inline UnityGI UnityGI_Base1(UnityGIInput data, half occlusion, half3 normalWorld)
{
//声明了一个UnityGI类型的变量o_gi,用来存储最终计算的GI信息
UnityGI o_gi;
//重置UnityGI
ResetUnityGI(o_gi);
// Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
//计算在Distance Shadowmask中实时阴影与烘焙阴影的混合过度
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
data.atten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
#endif
//将主平行灯传入GI中 UnityGIInput giInput; data=giInput
o_gi.light = data.light;
//将衰减加入到灯光的颜色中
o_gi.light.color *= data.atten;
#if UNITY_SHOULD_SAMPLE_SH
o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
#endif
//当使用Baked GI时
#if defined(LIGHTMAP_ON)
// Baked lightmaps
//用lightmapUV.xy的UV坐标对unity_Lightmap贴图进行采样存储到bakedColorTex这个变量中
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
//DecodeLightmap对采样后的贴图进行解码
half3 bakedColor = DecodeLightmap(bakedColorTex);
//当directional(定向光)模式开启时
#ifdef DIRLIGHTMAP_COMBINED
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif
#else // not directional lightmap
o_gi.indirect.diffuse += bakedColor;
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
ResetUnityLight(o_gi.light);
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap(o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
#endif
#endif
#endif
//当采用Realtime GI时
#ifdef DYNAMICLIGHTMAP_ON
// Dynamic lightmaps
//采样unity_DynamicLightmap贴图
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);
#ifdef DIRLIGHTMAP_COMBINED
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);
#else
o_gi.indirect.diffuse += realtimeColor;
#endif
#endif
o_gi.indirect.diffuse *= occlusion;
//最终的计算结果
return o_gi;
}*/
inline UnityGI UnityGlobalIllumination1(UnityGIInput data, half occlusion, half3 normalWorld)
{
return UnityGI_Base1(data, occlusion, normalWorld);
}
//该函数的目的是传出gi参数
inline void LightingLambert_GI1(SurfaceOutput s,UnityGIInput data,inout UnityGI gi)
{
gi = UnityGlobalIllumination1(data, 1.0, s.Normal);
}
#endif
八、Shader
Shader "unity/Global"
{
Properties
{
}
SubShader
{
Pass
{
Tags{"LightMode"="ForWardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile SHADOWS_SCREEN DIRECTIONAL
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
//在做光照时一般都需要引用下面两个文件
#include "AutoLight.cginc"
#include "Lighting.cginc"
//引用自定义的cginc文件
#include"../CGincludes/MyGlobal.cginc"
struct appdata
{
float4 vertex : POSITION;
//定义LightMapUV (或判断)
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
float4 lightmapUV:TEXCOORD1;
#endif
half3 normal:NORMAL;
};
struct v2f
{
float4 pos: SV_POSITION;
float4 worldPos:TEXCOORD;
//DYNAMICLIGHTMAP_ON动态GI(Realtime GI)或静态GI(Baked GI)LIGHTMAP_ON
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
float4 lightmapUV:TEXCOORD1;
#endif
half3 worldNormal:NORMAL;
//定义了两个变量,同时定义灯光衰减和实时阴影采样的变量
UNITY_LIGHTING_COORDS(2,3)
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos=mul(unity_ObjectToWorld,v.vertex);
o.worldNormal=UnityObjectToWorldNormal(v.normal);
//Baked GI(静态)//使UV的平铺和偏移有效
#if defined(LIGHTMAP_ON)
o.lightmapUV.xy=v.lightmapUV*unity_LightmapST.xy+unity_LightmapST.zw;
#endif
//LightMapUV中的zw代表的是动态的GI(Realtime GI)
#if defined(DYNAMICLIGHTMAP_ON)
o.lightmapUV.zw=v.lightmapUV*unity_DynamicLightmapST.xy+unity_DynamicLightmapST.zw;
#endif
UNITY_TRANSFER_LIGHTING(o,v.lightmapUV.xy);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// #if defined(LIGHTMAP_ON)
// #if defined(DYNAMICLIGHTMAP_ON)
// return 1;
// #else
// return 0;
// #endif
//顶点的表面数据
SurfaceOutput o;
// 使SurfaceOutPut中的参数初始化为0
UNITY_INITIALIZE_OUTPUT(SurfaceOutput,o)
//定义NORMAL的值
o.Normal=i.worldNormal;
//定义Albedo漫反射
o.Albedo=1;
//实时的阴影贴图纹理采样
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);
UnityGI gi;
// 初始化GI
UNITY_INITIALIZE_OUTPUT(UnityGI,gi)
// 定义主直接光照(平行灯)的灯光颜色
gi.light.color=_LightColor0;
// 定义主直接光照(平行灯)的位置方向
gi.light.dir=_WorldSpaceLightPos0;
// 定义间接光照的漫反射
gi.indirect.diffuse=1;
// 定义间接光照的高光
gi.indirect.specular=0;
UnityGIInput giInput;
// 初始化操作
UNITY_INITIALIZE_OUTPUT(UnityGIInput,giInput);
// 主平行灯
giInput.light=gi.light; //直接光照
giInput.worldPos=i.worldPos;
giInput.worldViewDir=normalize(_WorldSpaceCameraPos-i.worldPos);
//将实时的阴影赋予giInput.atten,将实时阴影与采样阴影进行混合
giInput.atten=atten;
giInput.ambient=0;
// 在特定的情况下才会用到lightmapUV,所以要进行分支判断
#if defined(LIGHTMAP_ON)||defined(DYNAMICLIGHTMAP_ON)
giInput.lightmapUV=i.lightmapUV;
#endif
// 更改Shader中调用的内置函数名和自定义cginc中的函数名,来以区别
// LightingLambert_GI改为 LightingLambert_GI1
//GI 间接光照的计算
LightingLambert_GI1(o,giInput,gi);
//UnityGI UnityGI_Base1(UnityGIInput data, half occlusion, half3 normalWorld)
// gi=UnityGI_Base1(giInput,1,o.Normal); 与LightingLambert_GI1(o,giInput,gi)功能相同
//返回间接光照的漫反射颜色
// return fixed4(gi.indirect.diffuse,1);
//GI直接光照的计算
fixed4 c=LightingLambert1(o,gi);
return c;
}
ENDCG
}
} FallBack "Specular"
}