2026-04-16 오브젝트 그림자
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace BadDog.Rendering.AreaLight.Editor
|
||||
{
|
||||
public class PreIntegratedFGDWindow : EditorWindow
|
||||
{
|
||||
private PreIntegratedFGD.FGDIndex m_FGDIndex = PreIntegratedFGD.FGDIndex.FGD_GGXAndDisneyDiffuse;
|
||||
private RenderTexture m_PreviewTexture = null;
|
||||
private bool m_IsInitialized = false;
|
||||
private PreIntegratedFGD.FGDIndex m_LastFGDIndex = PreIntegratedFGD.FGDIndex.FGD_GGXAndDisneyDiffuse;
|
||||
|
||||
[MenuItem("BadDog/Rendering/Area Light/Pre-Integrated FGD Preview")]
|
||||
private static void ShowWindow()
|
||||
{
|
||||
var window = GetWindow<PreIntegratedFGDWindow>("Pre-Integrated FGD Preview", true);
|
||||
window.minSize = new Vector2(512, 512);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
InitializePreview();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CleanupPreview();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
DrawOptions();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
DrawPreview();
|
||||
}
|
||||
|
||||
private void DrawOptions()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Options", EditorStyles.boldLabel);
|
||||
|
||||
// Ensure we don't select Count
|
||||
if (m_FGDIndex == PreIntegratedFGD.FGDIndex.Count)
|
||||
{
|
||||
m_FGDIndex = PreIntegratedFGD.FGDIndex.FGD_GGXAndDisneyDiffuse;
|
||||
}
|
||||
|
||||
// Create enum without Count and Marschner (not implemented)
|
||||
var validValues = System.Enum.GetValues(typeof(PreIntegratedFGD.FGDIndex));
|
||||
var displayNames = new System.Collections.Generic.List<string>();
|
||||
var enumValues = new System.Collections.Generic.List<PreIntegratedFGD.FGDIndex>();
|
||||
foreach (PreIntegratedFGD.FGDIndex value in validValues)
|
||||
{
|
||||
if (value != PreIntegratedFGD.FGDIndex.Count && value != PreIntegratedFGD.FGDIndex.FGD_Marschner)
|
||||
{
|
||||
displayNames.Add(value.ToString());
|
||||
enumValues.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = enumValues.IndexOf(m_FGDIndex);
|
||||
if (currentIndex < 0)
|
||||
{
|
||||
// If current index is invalid (e.g., Marschner), reset to first valid option
|
||||
currentIndex = 0;
|
||||
if (enumValues.Count > 0)
|
||||
{
|
||||
m_FGDIndex = enumValues[0];
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int newIndex = EditorGUILayout.Popup("FGD Type", currentIndex, displayNames.ToArray());
|
||||
bool changed = EditorGUI.EndChangeCheck();
|
||||
|
||||
if (changed && newIndex >= 0 && newIndex < enumValues.Count)
|
||||
{
|
||||
m_FGDIndex = enumValues[newIndex];
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Refresh Preview"))
|
||||
{
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawPreview()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
|
||||
|
||||
if (m_PreviewTexture != null && m_PreviewTexture.IsCreated())
|
||||
{
|
||||
int resolution = (int)PreIntegratedFGD.FGDTexture.Resolution;
|
||||
Rect labelRect = GUILayoutUtility.GetLastRect();
|
||||
Rect rect = GUILayoutUtility.GetRect(resolution, resolution, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
|
||||
rect.height = rect.width; // Make it square
|
||||
|
||||
// Center the preview horizontally
|
||||
float availableWidth = EditorGUIUtility.currentViewWidth;
|
||||
rect.x = (availableWidth - rect.width) * 0.5f;
|
||||
|
||||
var sRGBWrite = GL.sRGBWrite;
|
||||
GL.sRGBWrite = false;
|
||||
EditorGUI.DrawPreviewTexture(rect, m_PreviewTexture);
|
||||
GL.sRGBWrite = sRGBWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("Preview texture not available. Click 'Refresh Preview' to generate.", MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void InitializePreview()
|
||||
{
|
||||
if (m_IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int resolution = (int)PreIntegratedFGD.FGDTexture.Resolution;
|
||||
m_PreviewTexture = new RenderTexture(resolution, resolution, 0, GraphicsFormat.A2B10G10R10_UNormPack32)
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave,
|
||||
filterMode = FilterMode.Bilinear,
|
||||
wrapMode = TextureWrapMode.Clamp,
|
||||
name = "PreIntegratedFGD_Preview"
|
||||
};
|
||||
m_PreviewTexture.Create();
|
||||
|
||||
m_IsInitialized = true;
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
private void CleanupPreview()
|
||||
{
|
||||
if (m_IsInitialized)
|
||||
{
|
||||
PreIntegratedFGD.instance.Cleanup(m_LastFGDIndex);
|
||||
m_IsInitialized = false;
|
||||
}
|
||||
|
||||
if (m_PreviewTexture != null)
|
||||
{
|
||||
DestroyImmediate(m_PreviewTexture);
|
||||
m_PreviewTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
if (!m_IsInitialized || m_PreviewTexture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate FGD index
|
||||
if (m_FGDIndex == PreIntegratedFGD.FGDIndex.Count || (int)m_FGDIndex >= (int)PreIntegratedFGD.FGDIndex.Count)
|
||||
{
|
||||
Debug.LogError($"Invalid FGD index: {m_FGDIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Cleanup previous FGD index if it's different and was built
|
||||
if (m_LastFGDIndex != m_FGDIndex)
|
||||
{
|
||||
// Validate last index before accessing array
|
||||
if (m_LastFGDIndex != PreIntegratedFGD.FGDIndex.Count && (int)m_LastFGDIndex < (int)PreIntegratedFGD.FGDIndex.Count)
|
||||
{
|
||||
// Check if the previous index was actually built by checking refCounting
|
||||
var fgdType = typeof(PreIntegratedFGD);
|
||||
var refCountingField = fgdType.GetField("m_refCounting", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (refCountingField != null)
|
||||
{
|
||||
var refCounting = refCountingField.GetValue(PreIntegratedFGD.instance) as int[];
|
||||
if (refCounting != null && (int)m_LastFGDIndex >= 0 && (int)m_LastFGDIndex < refCounting.Length && refCounting[(int)m_LastFGDIndex] > 0)
|
||||
{
|
||||
PreIntegratedFGD.instance.Cleanup(m_LastFGDIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_LastFGDIndex = m_FGDIndex;
|
||||
}
|
||||
|
||||
// Build new (this increments refCounting)
|
||||
PreIntegratedFGD.instance.Build(m_FGDIndex);
|
||||
|
||||
// Render the FGD texture
|
||||
CommandBuffer cmd = CommandBufferPool.Get("PreIntegratedFGD Preview");
|
||||
PreIntegratedFGD.instance.RenderInit(m_FGDIndex, cmd);
|
||||
Graphics.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
|
||||
// Get the internal texture using reflection
|
||||
var fgdType2 = typeof(PreIntegratedFGD);
|
||||
var fieldInfo = fgdType2.GetField("m_PreIntegratedFGD", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
var textures = fieldInfo.GetValue(PreIntegratedFGD.instance) as RenderTexture[];
|
||||
if (textures != null && (int)m_FGDIndex >= 0 && (int)m_FGDIndex < textures.Length && textures[(int)m_FGDIndex] != null && textures[(int)m_FGDIndex].IsCreated())
|
||||
{
|
||||
Graphics.Blit(textures[(int)m_FGDIndex], m_PreviewTexture);
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44fa7453efc94394b87b7e9343c6a80f
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 346790
|
||||
packageName: Realtime Area Light for URP
|
||||
packageVersion: 1.3.0
|
||||
assetPath: Packages/com.baddog.rendering.arealight/Editor/Material/PreIntegratedFGD/PreIntegratedFGDWindow.cs
|
||||
uploadId: 884030
|
||||
Reference in New Issue
Block a user