Files
Main/Assets/Editor/SplitTerrain/Uitls/LightMapUtil.cs
2025-01-25 04:38:09 +08:00

231 lines
8.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace Thousandto.Editor.Test
{
public static class LightMapUtil
{
public static void CalcLightmapInfo(Renderer render)
{
}
//如果不存在uv2则使用uv代替
public static Vector2[] GetMeshUV2(Mesh m)
{
var uv2 = m.uv2;
if (uv2 == null || uv2.Length == 0)
uv2 = m.uv;
return uv2;
}
/// <summary>
/// 计算该renderer在lightmap贴图中的包围范围
/// </summary>
/// <param name="uv">uv2光照uv</param>
/// <param name="r"></param>
/// <returns>(minx, miny, maxX, maxY)</returns>
public static Vector4 GetBounds(Vector2[] uv, Renderer r)
{
if (uv != null)
{
var __uv = new Vector2[uv.Length];
Array.Copy(uv, __uv, uv.Length);
uv = __uv;
var minx = float.MaxValue;
var miny = float.MaxValue;
var maxx = float.MinValue;
var maxy = float.MinValue;
for (var _j = 0; _j < uv.Length; ++_j)
{
var _uv = uv[_j];
if (_uv.x < minx)
{
minx = _uv.x;
}
if (_uv.y < miny)
{
miny = _uv.y;
}
if (_uv.x > maxx)
{
maxx = _uv.x;
}
if (_uv.y > maxy)
{
maxy = _uv.y;
}
}
var bounds = new Vector4(minx, miny, maxx, maxy);
return bounds;
}
return Vector4.zero;
}
public static float GetScaleInLightmap(Renderer rd)
{
UnityEditor.SerializedObject so = new UnityEditor.SerializedObject(rd);
var sp = so.FindProperty("m_ScaleInLightmap");
return sp.floatValue;
}
//烘焙场景时可以指定GameObject的bake tag相同tag的物件的光照信息会生成到同以一张贴图中
public static void SetRenderLightmapParameters(Renderer renderer, string giparamsFile = "Assets/GameAssets/Resources/Scene/AAA.giparams")
{
SerializedObject so = new SerializedObject(renderer);
var sp = so.FindProperty("m_LightmapParameters");
sp.objectReferenceValue = AssetDatabase.LoadAssetAtPath(giparamsFile, typeof(LightmapParameters));
so.ApplyModifiedProperties();
}
//创建LightmapParameters资源文件
public static void CreateLightmapParameterFile(string path, int bakeTag)
{
LightmapParameters lp = new LightmapParameters();
lp.bakedLightmapTag = bakeTag;
AssetDatabase.CreateAsset(lp, path);
AssetDatabase.ImportAsset(path);
}
//从整lightmap贴图中扣指定物件的光照贴图
public static Texture2D PickLightmap(GameObject go, out Vector4 sourceBounds, out Vector4 scaleBounds, out Rect pickRect)
{
pickRect = new Rect();
sourceBounds = Vector4.zero;
scaleBounds = Vector4.zero;
if (go == null)
return null;
var meshFilter = go.GetComponent<MeshFilter>();
var renderer = go.GetComponent<Renderer>();
if (meshFilter == null || renderer == null)
return null;
var tex = GetFullLightmap(renderer);
if (tex == null)
return null;
var uv2s = GetMeshUV2(meshFilter.sharedMesh);
//var bounds = GetBounds(uv2s, renderer);
sourceBounds = LightMapUtil.GetBounds(uv2s, renderer);
scaleBounds = CalcBoundWithLightmapScaleOffset(sourceBounds, renderer.lightmapScaleOffset);
return PickTexture(tex, scaleBounds, out pickRect);
}
public static Vector4 CalcBoundWithLightmapScaleOffset(Vector4 sourceBounds, Vector4 lightmapScaleOffset)
{
var scaleBounds = new Vector4(sourceBounds.x * lightmapScaleOffset.x + lightmapScaleOffset.z,
sourceBounds.y * lightmapScaleOffset.y + lightmapScaleOffset.w,
sourceBounds.z * lightmapScaleOffset.x + lightmapScaleOffset.z,
sourceBounds.w * lightmapScaleOffset.y + lightmapScaleOffset.w);
return scaleBounds;
}
public static Texture2D PickTexture(Texture2D sourceTex, Vector4 bounds, out Rect pickRect)
{
pickRect = new Rect();
var blockW = ((bounds.z - bounds.x) * sourceTex.width);
var blockH = ((bounds.w - bounds.y) * sourceTex.height);
var startX = Mathf.RoundToInt(bounds.x * sourceTex.width);
var startY = Mathf.RoundToInt(bounds.y * sourceTex.height);
if(blockW - (int)blockW > 0.11f)
{
blockW += 1;
}
if(blockH - (int)blockH > 0.11f)
{
blockH += 1;
}
int w = (int)blockW;
int h = (int)blockH;
//startY = (tex.height - startY - blockH);
if (blockH == 0 || blockW == 0)
return null;
if (startX + w > sourceTex.width)
w--;
if (startY + h > sourceTex.height)
h--;
pickRect.x = startX;
pickRect.y = startY;
pickRect.width = w;
pickRect.height = h;
var colors = sourceTex.GetPixels(startX, startY, w, h);
Texture2D tex2d = new Texture2D(w, h);
tex2d.SetPixels(colors);
tex2d.Apply();
return tex2d;
}
//从整lightmap贴图中扣指定物件的光照贴图
public static Texture2D PickLightmap(Renderer renderer, out Vector4 bound, out Vector4 scaleBound, out Rect pickRect)
{
GameObject go = renderer.gameObject;
return PickLightmap(go, out bound, out scaleBound, out pickRect);
}
public static Texture2D GetFullLightmap(Renderer rd)
{
int lightmapIndex = rd.lightmapIndex;
var lightmaps = LightmapSettings.lightmaps;
if(lightmaps.Length == 0)
{
UnityEngine.Debug.LogError("No lightmap in current scene: " + EditorSceneManager.GetActiveScene().name);
return null;
}
if(lightmapIndex == -1)
{
UnityEngine.Debug.LogError("lightmapIndex is -1 : " + rd.name);
return null;
}
if(lightmapIndex >= lightmaps.Length)
{
UnityEngine.Debug.LogError("Renderer index out of range: " + lightmapIndex + " name: " + rd.name);
return null;
}
var tex = lightmaps[lightmapIndex].lightmapColor;
var path = AssetDatabase.GetAssetPath(tex);
if(File.Exists(path))
{
TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter;
if (!ti.isReadable)
{
ti.isReadable = true;
ti.SaveAndReimport();
}
}
return tex;
}
public static Texture2D CreateEmptyTexture(int width, int height, TextureFormat format)
{
Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
Color[] color = new Color[width * height];
for (int i = 0; i < color.Length; ++i)
{
color[i] = new Color(0, 0, 0, 0);
}
tex.SetPixels(color);
return tex;
}
[MenuItem("Test/Create/LightmapParameters")]
static void TestCreate()
{
CreateLightmapParameterFile("Assets/GameAssets/Resources/Scene/1.giparams", 1);
}
}
}