UnityGame/Library/PackageCache/com.unity.render-pipelines.universal/Runtime/2D/Passes/Utility/Light2DLookupTexture.cs

176 lines
6.7 KiB
C#
Raw Normal View History

2024-10-27 10:53:47 +03:00
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Rendering.Universal
{
internal static class Light2DLookupTexture
{
internal static readonly string k_LightLookupProperty = "_LightLookup";
internal static readonly string k_FalloffLookupProperty = "_FalloffLookup";
internal static readonly int k_LightLookupID = Shader.PropertyToID(k_LightLookupProperty);
internal static readonly int k_FalloffLookupID = Shader.PropertyToID(k_FalloffLookupProperty);
private static Texture2D s_PointLightLookupTexture;
private static Texture2D s_FalloffLookupTexture;
private static RTHandle m_LightLookupRTHandle = null;
private static RTHandle m_FalloffRTHandle = null;
public static RTHandle GetLightLookupTexture_Rendergraph()
{
if (s_PointLightLookupTexture == null || m_LightLookupRTHandle == null)
{
var lightLookupTexture = GetLightLookupTexture();
m_LightLookupRTHandle?.Release();
m_LightLookupRTHandle = RTHandles.Alloc(lightLookupTexture);
}
return m_LightLookupRTHandle;
}
public static RTHandle GetFallOffLookupTexture_Rendergraph()
{
if (s_FalloffLookupTexture == null || m_FalloffRTHandle == null)
{
var fallOffLookupTexture = GetFalloffLookupTexture();
m_FalloffRTHandle?.Release();
m_FalloffRTHandle = RTHandles.Alloc(fallOffLookupTexture);
}
return m_FalloffRTHandle;
}
public static void Release()
{
m_FalloffRTHandle?.Release();
m_LightLookupRTHandle?.Release();
m_FalloffRTHandle = null;
m_LightLookupRTHandle = null;
}
public static Texture GetLightLookupTexture()
{
if (s_PointLightLookupTexture == null)
s_PointLightLookupTexture = CreatePointLightLookupTexture();
return s_PointLightLookupTexture;
}
public static Texture GetFalloffLookupTexture()
{
if (s_FalloffLookupTexture == null)
s_FalloffLookupTexture = CreateFalloffLookupTexture();
return s_FalloffLookupTexture;
}
private static Texture2D CreatePointLightLookupTexture()
{
const int WIDTH = 256;
const int HEIGHT = 256;
var textureFormat = GraphicsFormat.R8G8B8A8_UNorm;
if (SystemInfo.IsFormatSupported(GraphicsFormat.R16G16B16A16_SFloat, GraphicsFormatUsage.SetPixels))
textureFormat = GraphicsFormat.R16G16B16A16_SFloat;
else if (SystemInfo.IsFormatSupported(GraphicsFormat.R32G32B32A32_SFloat, GraphicsFormatUsage.SetPixels))
textureFormat = GraphicsFormat.R32G32B32A32_SFloat;
var texture = new Texture2D(WIDTH, HEIGHT, textureFormat, TextureCreationFlags.None);
texture.name = k_LightLookupProperty;
texture.filterMode = FilterMode.Bilinear;
texture.wrapMode = TextureWrapMode.Clamp;
var center = new Vector2(WIDTH / 2.0f, HEIGHT / 2.0f);
for (var y = 0; y < HEIGHT; y++)
{
for (var x = 0; x < WIDTH; x++)
{
var pos = new Vector2(x, y);
var distance = Vector2.Distance(pos, center);
var relPos = pos - center;
var direction = center - pos;
direction.Normalize();
// red = 1-0 distance
// green = 1-0 angle
// blue = direction.x
// alpha = direction.y
float red;
if (x == WIDTH - 1 || y == HEIGHT - 1)
red = 0;
else
red = Mathf.Clamp(1 - (2.0f * distance / WIDTH), 0.0f, 1.0f);
var cosAngle = Vector2.Dot(Vector2.down, relPos.normalized);
var angle = Mathf.Acos(cosAngle) / Mathf.PI; // 0-1
var green = Mathf.Clamp(1 - angle, 0.0f, 1.0f);
var blue = direction.x;
var alpha = direction.y;
var color = new Color(red, green, blue, alpha);
texture.SetPixel(x, y, color);
}
}
texture.Apply();
return texture;
}
private static Texture2D CreateFalloffLookupTexture()
{
const int WIDTH = 2048;
const int HEIGHT = 192;
const GraphicsFormat textureFormat = GraphicsFormat.R8G8B8A8_SRGB;
var texture = new Texture2D(WIDTH, HEIGHT - 64, textureFormat, TextureCreationFlags.None);
texture.name = k_FalloffLookupProperty;
texture.filterMode = FilterMode.Bilinear;
texture.wrapMode = TextureWrapMode.Clamp;
for (var y = 0; y < HEIGHT; y++)
{
var baseValue = (float)(y + 32) / (HEIGHT + 64);
var lineValue = -baseValue + 1;
var exponent = Mathf.Log(lineValue) / Mathf.Log(baseValue);
for (var x = 0; x < WIDTH; x++)
{
var t = (float)x / WIDTH;
var red = Mathf.Pow(t, exponent);
var color = new Color(red, 0, 0, 1);
if (y >= 32 && y < 160)
texture.SetPixel(x, y - 32, color);
}
}
texture.Apply();
return texture;
}
//#if UNITY_EDITOR
// [MenuItem("Light2D Debugging/Write Light Texture")]
// static public void WriteLightTexture()
// {
// var path = EditorUtility.SaveFilePanel("Save texture as PNG", "", "LightLookupTexture.exr", "png");
// CreatePointLightLookupTexture();
// byte[] imgData = s_PointLightLookupTexture.EncodeToEXR(Texture2D.EXRFlags.CompressRLE);
// if (imgData != null)
// File.WriteAllBytes(path, imgData);
// }
// [MenuItem("Light2D Debugging/Write Falloff Texture")]
// static public void WriteCurveTexture()
// {
// var path = EditorUtility.SaveFilePanel("Save texture as PNG", "", "FalloffLookupTexture.png", "png");
// CreateFalloffLookupTexture();
// byte[] imgData = s_FalloffLookupTexture.EncodeToPNG();
// if (imgData != null)
// File.WriteAllBytes(path, imgData);
// }
//#endif
}
}