当前位置: 首页 > article >正文

Unity中动态切换光照贴图LightProbe的方法

关键代码:LightmapSettings.lightmaps = lightmapDatas;

LightmapData中操作三张图:lightmapColor,lightmapDir,以及一张ShadowMap

这里只操作前两张:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class LightingSwitchBtn : MonoBehaviour
{
    public bool IsTurnOn = false;

    // / 光照信息
    LightmapData[] lightmapDatas;

    /// 暗的时候的贴图
    public Texture2D[] lightmapDark;
    public Texture2D[] lightmapDarkDir;

    /// 亮的时候的贴图
    public Texture2D[] lightmapLight;
    public Texture2D[] lightmapLightDir;

    void Awake()
    {
    }
    public void OnPointerClick()
    {
        Debug.Log("1111");
        SwichState();
    }
    public void SwichState()
    {
        Debug.Log("2222");
        bool ClickState = !IsTurnOn;
        if (ClickState)
        {
            SetLightMap(lightmapLight, lightmapLightDir);
        }
        else
        {
            SetLightMap(lightmapDark, lightmapDarkDir);
        }
        IsTurnOn = ClickState;
    }

    public void SetLightMap(Texture2D[] lightmapTex, Texture2D[] lightmapDir)
    {
        if (lightmapTex == null)
        {
            return;
        }
        lightmapDatas = new LightmapData[lightmapTex.Length];
        for (int i = 0; i < lightmapTex.Length; i++)
        {
            LightmapData lmd = new LightmapData();
            lmd.lightmapColor = lightmapTex[i];
            lmd.lightmapDir = lightmapDir[i];
            lightmapDatas[i] = lmd;
        }
        LightmapSettings.lightmaps = lightmapDatas;
    }

}

更新光照贴图后,还需要更新天空球,这里以HDRP管线为例,URP和build in同理:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

public class LightingSwitchBtn : MonoBehaviour
{
    public bool IsTurnOn = false;

    LightmapData[] lightmapDatas;   /// 光照信息

    [Header("上午")] /// 亮的时候的贴图
    public Texture2D[] lightmapLightDir;
    public Texture2D[] lightmapLight;

    [Header("下午")]  /// 暗的时候的贴图
    public Texture2D[] lightmapDarkDir;
    public Texture2D[] lightmapDark;

    [Header("晚上")]/// 晚上的贴图
    public Texture2D[] lightmapNightDir;
    public Texture2D[] lightmapNight;

    [Header("天空")]
    public Texture SkyAM;
    public Texture SkyPM;
    public Texture SkyNight;
    [Header("Volume组件")]
    public Volume myVolume;
    public Texture mySkyTex;
    private HDRISky hdriSky;
    [Range(0,1)]
    public float TimeSwitch = 0;

    #region BoolIsTurnOn
    // public void SwichState()
    // {
    //     Debug.Log("啊啊啊");
    //     bool ClickState = !IsTurnOn;
    //     if (ClickState)
    //     {
    //         SetLightMap(lightmapLight, lightmapLightDir);
    //     }
    //     else
    //     {
    //         SetLightMap(lightmapDark, lightmapDarkDir);
    //     }
    //     IsTurnOn = ClickState;
    // }
    #endregion

    //天空切换
    void Awake()
    {
        VolumeProfile volumeProfile = myVolume.profile;
        volumeProfile.TryGet<HDRISky>(out hdriSky);
        mySkyTex = hdriSky.hdriSky.value;
    }
    //光照贴图切换
    public void AM_Time()
    {
        Debug.Log("AM");
        SetLightMap(lightmapLight, lightmapLightDir);
        hdriSky.hdriSky.value = SkyAM;
    }

    public void PM_Time()
    {
        Debug.Log("PM");
        SetLightMap(lightmapDark, lightmapDarkDir);
        hdriSky.hdriSky.value = SkyPM;
    }
    public void Night_Time()
    {
        Debug.Log("Night");
        SetLightMap(lightmapNight, lightmapNightDir);
        hdriSky.hdriSky.value = SkyNight;
    }
    public void SetLightMap(Texture2D[] lightmapTex, Texture2D[] lightmapDir)
    {
        if (lightmapTex == null)
        {
            return;
        }
        lightmapDatas = new LightmapData[lightmapTex.Length];
        for (int i = 0; i < lightmapTex.Length; i++)
        {
            LightmapData lmd = new LightmapData();
            lmd.lightmapColor = lightmapTex[i];
            lmd.lightmapDir = lightmapDir[i];
            lightmapDatas[i] = lmd;
        }
        LightmapSettings.lightmaps = lightmapDatas;
    }

}

以上是光照贴图部分的切换,但是这样会有个问题,就是光照贴图并不会影响到新加入的模型的漫反射,因为三个时段的漫反射是由冷到暖的颜色上的变化,如果你没有更新LightProbe的信息,那么你加入的模型必定会是很突兀的,如下图所示:

很明显新加入的沙发并没有暖色调影响到它,那是因为缺少LightProbe的更新,那么如果我们想更新三个时段的LightProbe,就需要将三个时段的的LightProbe保存为Asset,然后去动态加载它;

以下是将LightProbe保存为Asset的资源脚本:

using UnityEditor;
using UnityEngine;

public class LightProbeAssetCreator : EditorWindow
{
    [MenuItem("Assets/Create/Light Probe Asset")]
    static void CreateLightProbeAsset()
    {
        // 获取当前场景中的光照探针数据
        LightProbes lightProbes = LightmapSettings.lightProbes;

        // 确保光照探针对象存在
        if (lightProbes != null)
        {
            // 创建一个新的实例并将其保存为资产
            LightProbes lightProbesCopy = Instantiate(lightProbes);

            // 将实例化的光照探针保存为新资产
            AssetDatabase.CreateAsset(lightProbesCopy, "Assets/Arts/Scence/LightProbe/lightProbe.asset");

            // 刷新 AssetDatabase,以确保资产立即出现在项目视图中
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            // 输出成功消息
            Debug.Log("Light Probe Asset created at Assets/lightProbe.asset");
        }
        else
        {
            Debug.LogError("No Light Probes found in LightmapSettings.");
        }
    }
}

动态加载LightProbe资产的脚本:

//using EH;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using System.Collections.Generic;
using UnityEditor;

public class LightingSwitchBtn : MonoBehaviour
{
    LightmapData[] lightmapDatas;   /// 光照信息

    [Header("上午")] /// 亮的时候的贴图
    public Texture2D[] lightmapLightDir;
    public Texture2D[] lightmapLight;

    [Header("下午")]  /// 暗的时候的贴图
    public Texture2D[] lightmapDarkDir;
    public Texture2D[] lightmapDark;

    [Header("晚上")]/// 晚上的贴图
    public Texture2D[] lightmapNightDir;
    public Texture2D[] lightmapNight;

    [Header("天空")]
    public Texture SkyAM;
    public Texture SkyPM;
    public Texture SkyNight;
    [Header("Volume组件")]
    public Volume myVolume;
    public Texture mySkyTex;
    private HDRISky hdriSky;
    [Header("直线光")]
    public Light RealLight;
    public float Temperature_AM = 5800;
    public float Intensity_AM = 10;
    [Space(10)]
    public float Temperature_PM = 5200;
    public float Intensity_PM = 20;
    [Space(10)]
    public float Temperature_Night = 7500;
    public float Intensity_Night = 10;

    [Header("RenderTex")]
    public RenderTexture RTX01;
    public RenderTexture RTX02;
    public Material myMat;

    [Range(0,1)]
    public float TimeSwitch = 0;

    [Header("漫反射(Light Probes Group)")]
    public LightProbes loadedLightProbes;
    public string assetPath_AM = "Assets/Arts/Scence/LightProbe/lightProbe_AM.asset";
    public string assetPath_PM = "Assets/Arts/Scence/LightProbe/lightProbe_PM.asset";
    public string assetPath_Night = "Assets/Arts/Scence/LightProbe/lightProbe_Night.asset";

    //天空切换
    void Awake()
    {
        //FW.Get<EffectMgr>().lightControl = this;
        VolumeProfile volumeProfile = myVolume.profile;
        volumeProfile.TryGet<HDRISky>(out hdriSky);
        mySkyTex = hdriSky.hdriSky.value;
    }
    //光照贴图切换
    public void AM_Time()
    {
        Debug.Log("AM");
        SetLightMap(lightmapLight, lightmapLightDir);
        hdriSky.hdriSky.value = SkyAM;

        LightDirCol(Temperature_AM,Intensity_AM);
        LoadLightProbe( assetPath_AM);
    }

    public void PM_Time()
    {
        Debug.Log("PM");
        SetLightMap(lightmapDark, lightmapDarkDir);
        hdriSky.hdriSky.value = SkyPM;

        LightDirCol(Temperature_PM,Intensity_PM);
        LoadLightProbe( assetPath_PM);
    }
    public void Night_Time()
    {
        Debug.Log("Night");
        SetLightMap(lightmapNight, lightmapNightDir);
        hdriSky.hdriSky.value = SkyNight;

        LightDirCol(Temperature_Night,Intensity_Night);
        LoadLightProbe( assetPath_Night);
    }
    public void SetLightMap(Texture2D[] lightmapTex, Texture2D[] lightmapDir)
    {
        if (lightmapTex == null)
        {
            return;
        }
        lightmapDatas = new LightmapData[lightmapTex.Length];
        for (int i = 0; i < lightmapTex.Length; i++)
        {
            LightmapData lmd = new LightmapData();
            lmd.lightmapColor = lightmapTex[i];
            lmd.lightmapDir = lightmapDir[i];
            lightmapDatas[i] = lmd;
        }
        LightmapSettings.lightmaps = lightmapDatas;
    }

    public void LightDirCol( float TemperatureTime , float IntensityTime)
    {
        RealLight.colorTemperature = TemperatureTime;
        HDAdditionalLightData hdLight = RealLight.GetComponent<HDAdditionalLightData>();
        hdLight.intensity = IntensityTime;
        Debug.Log("光照强度" + RealLight.intensity);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            LightDirCol(Temperature_AM,Intensity_AM);
        }
        else if (Input.GetKeyDown(KeyCode.E))
        {
            LightDirCol(Temperature_PM,Intensity_PM);
        }
        else if(Input.GetKeyDown(KeyCode.R))
        {
            LightDirCol(Temperature_Night,Intensity_Night);
        }
    }
    void LoadLightProbe( string assetPath)
    {
        // 加载光照探针资产
        loadedLightProbes = AssetDatabase.LoadAssetAtPath<LightProbes>(assetPath);
        if (loadedLightProbes != null)
        {
            LightmapSettings.lightProbes = loadedLightProbes;
        }
        else
        {
            Debug.LogError("光照探针毛都没 " + assetPath);
        }
    }
}

其中LightProbes的加载关键代码是:

    void LoadLightProbe( string assetPath)
    {
        // 加载光照探针资产
        loadedLightProbes = AssetDatabase.LoadAssetAtPath<LightProbes>(assetPath);
        if (loadedLightProbes != null)
        {
            LightmapSettings.lightProbes = loadedLightProbes;
        }
        else
        {
            Debug.LogError("光照探针毛都没 " + assetPath);
        }
    }

完整脚本有冗余,请自行删减;


http://www.kler.cn/a/569776.html

相关文章:

  • 服务流程设计和服务或端口重定向及其websocket等应用示例
  • 《Python百练成仙》31-40章(不定时更新)
  • iOS UICollectionViewCell 点击事件自动化埋点
  • react 中,使用antd layout布局中的sider 做sider的展开和收起功能
  • 【Linux】进程地址空间和虚拟地址空间
  • 测试的BUG分析
  • 42 session反序列化漏洞
  • 数据结构(初阶)(七)----树和二叉树(前中后序遍历)
  • vcredist_x64 资源文件分享
  • React(11)路由demo
  • IDEA相关配置
  • LeetCode-154. 寻找旋转排序数组中的最小值 II
  • go类(结构体)和对象
  • 派可数据BI接入DeepSeek,开启智能数据分析新纪元
  • GPT-4.5
  • 力扣785. 判断二分图
  • 黑龙江省地标-DB31/T 862-2021 “一网通办”政务服务中心建设和运行规范
  • js基础二
  • 我通过AI编程完成了第一个实用程序
  • 避免 Git 文件名大小写出错