315 lines
6.8 KiB
C#
315 lines
6.8 KiB
C#
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera))]
|
|
public class DeluxeTonemapper : MonoBehaviour
|
|
{
|
|
public enum Mode
|
|
{
|
|
Color = 0,
|
|
Luminance = 1,
|
|
ExtendedLuminance = 2,
|
|
ColorHD = 3
|
|
}
|
|
|
|
[SerializeField]
|
|
public FilmicCurve m_MainCurve = new FilmicCurve();
|
|
|
|
[SerializeField]
|
|
public Color m_Tint = new Color(1f, 1f, 1f, 1f);
|
|
|
|
[SerializeField]
|
|
public float m_MoodAmount;
|
|
|
|
[SerializeField]
|
|
public float m_Sharpness;
|
|
|
|
[SerializeField]
|
|
public float m_SharpnessKernel = 0.5f;
|
|
|
|
[SerializeField]
|
|
public Mode m_Mode = Mode.ColorHD;
|
|
|
|
public bool m_EnableLut0;
|
|
|
|
public float m_Saturation = 1f;
|
|
|
|
public bool m_DisableColorGrading;
|
|
|
|
private bool m_LastDisableColorGrading;
|
|
|
|
public float m_Lut0Amount = 1f;
|
|
|
|
public Texture2D m_2DLut0;
|
|
|
|
public Texture3D m_3DLut0;
|
|
|
|
private FTDLut m_LutTool = new FTDLut();
|
|
|
|
public bool m_FilmicCurveOpened = true;
|
|
|
|
public bool m_ColorGradingOpened;
|
|
|
|
public bool m_HDREffectsgOpened;
|
|
|
|
public bool m_BannerIsOpened = true;
|
|
|
|
public bool m_Use2DLut;
|
|
|
|
private bool m_LastUse2DLut;
|
|
|
|
[SerializeField]
|
|
private bool m_IsInitialized;
|
|
|
|
private Mode m_LastMode;
|
|
|
|
private Material m_Material;
|
|
|
|
private Shader m_Shader;
|
|
|
|
public FTDLut LutTool
|
|
{
|
|
get
|
|
{
|
|
return m_LutTool;
|
|
}
|
|
}
|
|
|
|
public Shader TonemappingShader
|
|
{
|
|
get
|
|
{
|
|
return m_Shader;
|
|
}
|
|
}
|
|
|
|
private void DestroyMaterial(Material mat)
|
|
{
|
|
if ((bool)mat)
|
|
{
|
|
Object.DestroyImmediate(mat);
|
|
mat = null;
|
|
}
|
|
}
|
|
|
|
private void CreateMaterials()
|
|
{
|
|
if (m_Shader == null)
|
|
{
|
|
if (m_Mode == Mode.Color)
|
|
{
|
|
m_Shader = Shader.Find("Hidden/Deluxe/TonemapperColor");
|
|
}
|
|
if (m_Mode == Mode.Luminance)
|
|
{
|
|
m_Shader = Shader.Find("Hidden/Deluxe/TonemapperLuminosity");
|
|
}
|
|
if (m_Mode == Mode.ExtendedLuminance)
|
|
{
|
|
m_Shader = Shader.Find("Hidden/Deluxe/TonemapperLuminosityExtended");
|
|
}
|
|
if (m_Mode == Mode.ColorHD)
|
|
{
|
|
m_Shader = Shader.Find("Hidden/Deluxe/TonemapperColorHD");
|
|
}
|
|
}
|
|
if (m_Material == null && m_Shader != null && m_Shader.isSupported)
|
|
{
|
|
m_Material = CreateMaterial(m_Shader);
|
|
}
|
|
}
|
|
|
|
private Material CreateMaterial(Shader shader)
|
|
{
|
|
if (!shader)
|
|
{
|
|
return null;
|
|
}
|
|
Material material = new Material(shader);
|
|
material.hideFlags = HideFlags.HideAndDontSave;
|
|
return material;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
DestroyMaterial(m_Material);
|
|
m_Material = null;
|
|
m_Shader = null;
|
|
}
|
|
|
|
public void ClearLutTextures()
|
|
{
|
|
if (m_3DLut0 != null)
|
|
{
|
|
Object.DestroyImmediate(m_3DLut0);
|
|
m_3DLut0 = null;
|
|
}
|
|
m_2DLut0 = null;
|
|
}
|
|
|
|
public void ConvertAndApply2dLut()
|
|
{
|
|
if (m_2DLut0 != null)
|
|
{
|
|
m_3DLut0 = LutTool.Allocate3DLut(m_2DLut0);
|
|
LutTool.ConvertLUT(m_2DLut0, m_3DLut0);
|
|
}
|
|
}
|
|
|
|
public void SetLut0(Texture2D lut0)
|
|
{
|
|
ClearLutTextures();
|
|
m_2DLut0 = lut0;
|
|
ConvertAndApply2dLut();
|
|
}
|
|
|
|
public void VerifyAndUpdateShaderVariations(bool forceUpdate)
|
|
{
|
|
if (m_Material == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!SystemInfo.supports3DTextures)
|
|
{
|
|
m_Use2DLut = true;
|
|
}
|
|
if (m_DisableColorGrading != m_LastDisableColorGrading || forceUpdate)
|
|
{
|
|
m_Material.DisableKeyword("FTD_DISABLE_CGRADING");
|
|
if (m_DisableColorGrading)
|
|
{
|
|
m_Material.EnableKeyword("FTD_DISABLE_CGRADING");
|
|
}
|
|
}
|
|
if (m_Use2DLut != m_LastUse2DLut || forceUpdate)
|
|
{
|
|
m_Material.DisableKeyword("FTD_2D_LUT");
|
|
if (m_Use2DLut)
|
|
{
|
|
m_Material.EnableKeyword("FTD_2D_LUT");
|
|
}
|
|
}
|
|
m_LastUse2DLut = m_Use2DLut;
|
|
m_LastDisableColorGrading = m_DisableColorGrading;
|
|
}
|
|
|
|
public void UpdateCoefficients()
|
|
{
|
|
if (m_Mode == Mode.ColorHD)
|
|
{
|
|
m_MainCurve.m_UseLegacyCurve = false;
|
|
}
|
|
else
|
|
{
|
|
m_MainCurve.m_UseLegacyCurve = true;
|
|
}
|
|
m_MainCurve.UpdateCoefficients();
|
|
if (!(m_Material == null))
|
|
{
|
|
if (m_2DLut0 == null)
|
|
{
|
|
ClearLutTextures();
|
|
}
|
|
m_Material.SetFloat("_K", m_MainCurve.m_k);
|
|
m_Material.SetFloat("_Crossover", m_MainCurve.m_CrossOverPoint);
|
|
m_Material.SetVector("_Toe", m_MainCurve.m_ToeCoef);
|
|
m_Material.SetVector("_Shoulder", m_MainCurve.m_ShoulderCoef);
|
|
m_Material.SetFloat("_LuminosityWhite", m_MainCurve.m_LuminositySaturationPoint * m_MainCurve.m_LuminositySaturationPoint);
|
|
m_Material.SetFloat("_Sharpness", m_Sharpness);
|
|
m_Material.SetFloat("_Saturation", m_Saturation);
|
|
if (m_2DLut0 != null && m_3DLut0 == null && LutTool.Validate2DLut(m_2DLut0))
|
|
{
|
|
ConvertAndApply2dLut();
|
|
}
|
|
float value = ((QualitySettings.activeColorSpace != ColorSpace.Linear) ? 1f : 0.5f);
|
|
if (m_Use2DLut && m_2DLut0 != null)
|
|
{
|
|
m_2DLut0.filterMode = FilterMode.Bilinear;
|
|
float num = Mathf.Sqrt(m_2DLut0.width);
|
|
m_Material.SetTexture("_2dLut0", m_2DLut0);
|
|
m_Material.SetVector("_Lut0Params", new Vector4(m_Lut0Amount, 1f / (float)m_2DLut0.width, 1f / (float)m_2DLut0.height, num - 1f));
|
|
m_Material.SetFloat("_IsLinear", value);
|
|
}
|
|
else if (m_3DLut0 != null)
|
|
{
|
|
int width = m_3DLut0.width;
|
|
float y = (float)(width - 1) / (1f * (float)width);
|
|
float z = 1f / (2f * (float)width);
|
|
m_3DLut0.filterMode = FilterMode.Trilinear;
|
|
m_Material.SetVector("_Lut0Params", new Vector4(m_Lut0Amount, y, z, 0f));
|
|
m_Material.SetTexture("_Lut0", m_3DLut0);
|
|
m_Material.SetFloat("_IsLinear", value);
|
|
}
|
|
else
|
|
{
|
|
m_Material.SetVector("_Lut0Params", Vector4.zero);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ReloadShaders()
|
|
{
|
|
OnDisable();
|
|
}
|
|
|
|
public void SetCurveParameters(float range, float crossover, float toe, float shoulder)
|
|
{
|
|
SetCurveParameters(0f, range, crossover, toe, shoulder);
|
|
}
|
|
|
|
public void SetCurveParameters(float crossover, float toe, float shoulder)
|
|
{
|
|
SetCurveParameters(0f, 1f, crossover, toe, shoulder);
|
|
}
|
|
|
|
public void SetCurveParameters(float blackPoint, float whitePoint, float crossover, float toe, float shoulder)
|
|
{
|
|
m_MainCurve.m_BlackPoint = blackPoint;
|
|
m_MainCurve.m_WhitePoint = whitePoint;
|
|
m_MainCurve.m_ToeStrength = -1f * toe;
|
|
m_MainCurve.m_ShoulderStrength = shoulder;
|
|
m_MainCurve.m_CrossOverPoint = crossover * (whitePoint - blackPoint) + blackPoint;
|
|
UpdateCoefficients();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (m_MainCurve == null)
|
|
{
|
|
m_MainCurve = new FilmicCurve();
|
|
}
|
|
CreateMaterials();
|
|
UpdateCoefficients();
|
|
VerifyAndUpdateShaderVariations(true);
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
}
|
|
|
|
[ImageEffectTransformsToLDR]
|
|
private void OnRenderImage(RenderTexture source, RenderTexture destination)
|
|
{
|
|
Initialize();
|
|
if (m_Mode != m_LastMode)
|
|
{
|
|
ReloadShaders();
|
|
CreateMaterials();
|
|
VerifyAndUpdateShaderVariations(true);
|
|
}
|
|
m_LastMode = m_Mode;
|
|
UpdateCoefficients();
|
|
VerifyAndUpdateShaderVariations(false);
|
|
m_Material.SetVector("_Tint", m_Tint);
|
|
m_Material.SetVector("_Offsets", new Vector4(m_SharpnessKernel / (float)source.width, m_SharpnessKernel / (float)source.height));
|
|
if (m_EnableLut0)
|
|
{
|
|
Graphics.Blit(source, destination, m_Material, 1);
|
|
}
|
|
else
|
|
{
|
|
Graphics.Blit(source, destination, m_Material, 0);
|
|
}
|
|
}
|
|
}
|