SRP_09_PointAndSpotLight


一、Point

原文链接:https://catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/

  • Point Light 距离衰减计算公式

image-20221215212554013

  • 灯光强度的范围衰减计算公式
  • image-20221215212756218

二、SpotLight

  • Spot Angle 计算公式

image-20221215213146478

image-20221215213640089

三、修改烘焙衰减算法

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
    }
}

烘焙衰减修改前

aa

烘焙衰减修改后

未命名图片1

四、注意事项:

  • 分离的 for 循环,最好使用不同的索引变量,否在在一些情况下 shader 编译会出问题
    image-20221215212350878

  • SpotLight的 inneAngle 需要使用 Light.innerSpotAngle 访问,他不包含在 VisibleLight里面

image-20221215214724402


文章作者: 血魂S
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 血魂S !
  目录