Unity - 搬砖日志 - BRP 管线下的自定义阴影尺寸(脱离ProjectSettings/Quality/ShadowResolution设置)


环境

Unity : 2020.3.37f1
Pipeline : BRP


原因

(好久没搬砖了,偶尔健身一下,顺便将这些无技术含量的内容,记到 blog,不要记在脑子)

最近给项目做优化的过程中
发现 BRP 管线下的 Shadow Resolution 只能在 Project Settings/Quality/Shadow Resolution 去设置
而且发现
Shadow Resolution 的一些枚举为:

  • Low Resolution - 1K
  • Medium Resolution - 2K
  • High Resolution - 4K
  • Very High Resolution - 4K (这个可能因硬件不同而不同)

在这里插入图片描述

在这里插入图片描述


解决

但是如果想要设置更小的 shadow resolution 的话,这步就没辙了?
还好我去公司中台请教了 TA 专家,他说 BRP 中一样是可以设置的

在这里插入图片描述


CSharp 脚本

// jave.lin 2023/03/06 custom shadow resolution
// refer to : https://docs.unity3d.com/Manual/shadow-mapping.html

using UnityEngine;

public enum eCustomShadowResolution
{
    
    
    UsingQualitySettings = 0,
    Low = 128,
    Medium = 256,
    High = 512,
    VeryHigh = 1024,
}

[ExecuteInEditMode]
public class LightCustomShadowResolution : MonoBehaviour
{
    
    
    public bool runInUpdate = true;
    public eCustomShadowResolution shadowSize = eCustomShadowResolution.High;
    private Light lightComp;
    private void Update()
    {
    
    
        if (runInUpdate)
        {
    
    
            if (lightComp == null)
            {
    
    
                lightComp = GetComponent<Light>();
            }
            if (lightComp == null)
            {
    
    
                return;
            }
            lightComp.shadowCustomResolution = (int)shadowSize;
        }
    }
}


效果预览 - Light.shadowCustomResolution

Light.shadowCustomResolution = val

  • 这个 val 不等于 0 的话,就是自定义设置,这个 val 会自动 mostest NPOT == Mostest Next Power Of Tow
  • 这个 val 等于 0 的话,就是使用 Quality Settings 的全局配置
    请添加图片描述

效果预览 - Using Quality Settings

请添加图片描述


应用

只需要编写工具,批量对项目中的 Scene、Prefab,遍历其下所有 Light 的 GameObject 添加 改组件即可


ControlLightShadowResolution.cs Component

// jave.lin 2023/03/06 control light shadow resolution, [attach to light]

using UnityEditor.SearchService;
using UnityEngine;
using War.Script;

[ExecuteInEditMode]
public class ControlLightShadowResolution : MonoBehaviour
{
    
    
    public eLightShadowResolutionFollowQualitySetting followQualitySetting;
    public int shadowSize;

#if UNITY_EDITOR
    public bool runInUpdate = true;
#endif

    private Light lightComp;

    private void Start()
    {
    
    
        int level = UIInterface.GetCsharpEventCenterLevel();
        OnQualityLevelChanged(level);
        // TODO: xxx 修改为对应的时间名
        EventMgr.Instance.RemoveEvent<int>("xxx", OnQualityLevelChanged);
        EventMgr.Instance.AddEvent<int>("xxx", OnQualityLevelChanged);
    }

    private void OnDestroy()
    {
    
    
        // TODO: xxx 修改为对应的时间名
        EventMgr.Instance.RemoveEvent<int>("xxx", OnQualityLevelChanged);
    }

#if UNITY_EDITOR
    private void Update()
    {
    
    
        if (runInUpdate)
        {
    
    
            ApplyChanged();
        }
    }
#endif

    private void OnQualityLevelChanged(int lv)
    {
    
    
        if (followQualitySetting == eLightShadowResolutionFollowQualitySetting.On)
        {
    
    
            shadowSize = 0;
        }
        else
        {
    
    
            eQualityLevel level = (eQualityLevel)lv;
            switch (level)
            {
    
    
                case eQualityLevel.VeryLow:
                    shadowSize = (int)eLightCustomShadowResolutionSize.VeryLow;
                    break;
                case eQualityLevel.Low:
                    shadowSize = (int)eLightCustomShadowResolutionSize.Low;
                    break;
                case eQualityLevel.Medium:
                    shadowSize = (int)eLightCustomShadowResolutionSize.Medium;
                    break;
                case eQualityLevel.High:
                    shadowSize = (int)eLightCustomShadowResolutionSize.High;
                    break;
                default:
                    break;
            }
        }
        ApplyChanged();
    }

    private void ApplyChanged()
    {
    
    
        if (lightComp == null)
        {
    
    
            lightComp = GetComponent<Light>();
        }
        if (lightComp == null)
        {
    
    
            return;
        }
        lightComp.shadowCustomResolution = shadowSize;
    }
}


Tools Batching add the Component to all Light

// 伪代码
var scene = EditorSceneManager.xxxByPath("xxx");
var roots = scene.GetxxxxRoots();
foreach (var root in roots)
{
    
    
	var lights = root.GetComponents<Light>();
	// 剩下的同下代码
}
    public static void AddControlLightShadowResolution()
    {
    
    
        var lights = GameObject.FindObjectsOfType<Light>();

        foreach (var light in lights)
        {
    
    
            if (light == null)
                continue;

            ControlLightShadowResolution comp = light.transform.GetComponent<ControlLightShadowResolution>();

            if (light.lightmapBakeType == LightmapBakeType.Realtime)
            {
    
    
                if (comp == null)
                {
    
    
                    light.gameObject.AddComponent<ControlDepthMode>();
                }
            }
            else
            {
    
    
                if (comp != null)
                {
    
    
                    if (Application.isPlaying)
                        GameObject.Destroy(comp);
                    else
                        GameObject.DestroyImmediate(comp);
                }
            }
        }
    }

References

猜你喜欢

转载自blog.csdn.net/linjf520/article/details/129370776