主页 > 人工智能  > 

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

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

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

标签:

Unity中动态切换光照贴图LightProbe的方法由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Unity中动态切换光照贴图LightProbe的方法