一、Point
原文链接:https://catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/
- Point Light 距离衰减计算公式
- 灯光强度的范围衰减计算公式
二、SpotLight
- Spot Angle 计算公式


三、修改烘焙衰减算法
unity 默认的烘焙距离衰减并不是平方反比的方式,需要按造下面的方式进行修改
using Unity.Collections;
using UnityEngine;
using UnityEngine.Experimental.GlobalIllumination;
using LightType = UnityEngine.LightType;
namespace CustomRP
{
public partial class CustomRenderPipeline
{
partial void InitializeForEditor();
partial void DisposeForEditor();
#if UNITY_EDITOR
private static Lightmapping.RequestLightsDelegate _lightsDelegate =
(Light[] lights, NativeArray<LightDataGI> output) =>
{
LightDataGI lightData = new LightDataGI();
for (int i = 0; i < lights.Length; i++)
{
Light light = lights[i];
switch (light.type)
{
case LightType.Directional:
DirectionalLight directionalLight = new DirectionalLight();
LightmapperUtils.Extract(light, ref directionalLight);
lightData.Init(ref directionalLight);
break;
case LightType.Point:
PointLight pointLight = new PointLight();
LightmapperUtils.Extract(light, ref pointLight);
lightData.Init(ref pointLight);
break;
case LightType.Spot:
SpotLight spotLight = new SpotLight();
LightmapperUtils.Extract(light, ref spotLight);
spotLight.innerConeAngle = light.innerSpotAngle * Mathf.Deg2Rad;
spotLight.angularFalloff = AngularFalloffType.AnalyticAndInnerAngle;
lightData.Init(ref spotLight);
break;
case LightType.Area:
RectangleLight rectangleLight = new RectangleLight();
LightmapperUtils.Extract(light, ref rectangleLight);
rectangleLight.mode = LightMode.Baked;
lightData.Init(ref rectangleLight);
break;
default:
lightData.InitNoBake(light.GetInstanceID());
break;
}
lightData.falloff = FalloffType.InverseSquared; // 设置灯光衰减为距离平反反比
output[i] = lightData;
}
};
partial void InitializeForEditor()
{
Lightmapping.SetDelegate(_lightsDelegate);
}
partial void DisposeForEditor()
{
Lightmapping.ResetDelegate();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
DisposeForEditor();
_cameraRenderer.Dispose();
}
#endif
}
}
烘焙衰减修改前

烘焙衰减修改后

四、注意事项:
分离的 for 循环,最好使用不同的索引变量,否在在一些情况下 shader 编译会出问题
SpotLight的 inneAngle 需要使用 Light.innerSpotAngle 访问,他不包含在 VisibleLight里面