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

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

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

相关文章:

  • C++实现3D(EasyX)详细教程
  • DeepSeek蒸馏TinyLSTM实操指南
  • deepseek使用记录18——文化基因之文化融合
  • 数据结构(初阶)(六)----队列
  • Linux NAT和代理服务器
  • 【开源免费】基于SpringBoot+Vue.JS周边游平台系统(JAVA毕业设计)
  • 0x05 部门功能开发日志技术
  • 图漾PercipioIPTool软件使用
  • python基于后门的神经网络模型水印通用方法
  • AndroidStudio下载旧版本方法
  • miqiu的分布式锁(四):MySQL悲观锁解析
  • 线程控制(创建、终止、等待、分离)
  • 定位需要优化的SQL ,及如何优化SQL
  • 深入xtquant:掌握市场基础信息的获取技巧
  • React 第二十七节 <StrictMode> 的使用方法及注意事项
  • Unity XR-XR Interaction Toolkit开发使用方法(十三)组件介绍(XR Grab Interactable)
  • 开源项目Wren AI 文本到SQL解决方案详解
  • 电池管理系统(BMS)架构详细解析:原理与器件选型指南
  • 力扣785. 判断二分图
  • 在AIStudio飞桨星河社区一键部署DeepSeek-r1:70b模型
  • 61岁云浮市律师协会副会长谭炳光因突发疾病逝世
  • 尹锡悦宣布退出国民力量党
  • 媒体评欧阳娜娜遭民进党当局威胁:艺人表达国家认同是民族大义
  • 宜昌谱写新叙事:长江大保护与高质量发展如何相互成就
  • 秦洪看盘|指标股发力,A股渐有突破态势
  • 中华人民共和国和巴西联邦共和国关于强化携手构建更公正世界和更可持续星球的中巴命运共同体,共同维护多边主义的联合声明