Files
2026-04-16 04:58:10 +09:00

116 lines
3.7 KiB
C#

using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace BadDog.Rendering.AreaLight
{
public class ShadowAtlasResolutionAttribute : PropertyAttribute
{
}
[Serializable]
public class AreaLightSettings
{
[Tooltip("Maximum number of area lights processed per frame")]
[Range(0, 8)]
public int maxAreaLights = 8;
[Tooltip("Pre-integrated FGD shader for GGX and Disney Diffuse")]
public Shader preIntegratedFGD_GGXDisneyDiffuse;
[Tooltip("Pre-integrated FGD shader for Charlie and Fabric Lambert")]
public Shader preIntegratedFGD_CharlieFabricLambert;
[Tooltip("Pre-integrated FGD shader for Marschner")]
public Shader preIntegratedFGD_Marschner;
}
[Serializable]
public class AreaLightShadowSettings
{
public enum BGAreaLightShadowMode
{
Off = 0,
PCF2x2 = 1,
Tent5x5 = 2,
Tent7x7 = 3,
PCSS = 4,
}
[Tooltip("Resolution of the area light shadow atlas (e.g., 512, 1024, 2048, 4096, 8192).)")]
[ShadowAtlasResolution]
public int shadowAtlasResolution = 1024;
[Tooltip("Maximum number of area lights that can cast shadows simultaneously")]
[Range(0, 8)]
public int maxShadowCastingLights = 8;
[Tooltip("Shadow filtering mode")]
public BGAreaLightShadowMode shadowFilter = BGAreaLightShadowMode.Tent5x5;
[Tooltip("Softness radius in world units for PCSS")]
[Range(0.0f, 32.0f)]
public float pcssShadowSoftness = 2f;
[Tooltip("Number of samples used to search blockers in PCSS.")]
[Range(4, 32)]
public int pcssBlockerSampleCount = 16;
[Tooltip("Number of samples used for PCSS filtering.")] [Range(4, 32)]
public int pcssFilterSampleCount = 16;
public string GetShadowKeyword()
{
switch (shadowFilter)
{
case BGAreaLightShadowMode.Off:
return null; // No keyword = off
case BGAreaLightShadowMode.PCF2x2:
return "_BG_AREALIGHT_SHADOWS_PCF2X2";
case BGAreaLightShadowMode.Tent5x5:
return "_BG_AREALIGHT_SHADOWS_TENT5X5";
case BGAreaLightShadowMode.Tent7x7:
return "_BG_AREALIGHT_SHADOWS_TENT7X7";
case BGAreaLightShadowMode.PCSS:
return "_BG_AREALIGHT_SHADOWS_PCSS";
default:
return null;
}
}
}
public class AreaLighting : ScriptableRendererFeature
{
[SerializeField]
private AreaLightSettings m_LightSettings = new AreaLightSettings();
[SerializeField]
private AreaLightShadowSettings m_ShadowSettings = new AreaLightShadowSettings();
private AreaLightingPass m_AreaLightingPass;
public override void Create()
{
if (m_AreaLightingPass == null)
{
m_AreaLightingPass = new AreaLightingPass();
}
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
GraphicsSettings.realtimeDirectRectangularAreaLights = true;
m_AreaLightingPass.Setup(m_LightSettings, m_ShadowSettings, renderingData);
renderer.EnqueuePass(m_AreaLightingPass);
}
protected override void Dispose(bool disposing)
{
m_AreaLightingPass?.Dispose();
m_AreaLightingPass = null;
}
}
}