mirror of
https://github.com/ApfelTeeSaft/Slender.git
synced 2026-08-27 11:53:34 +00:00
239 lines
6.0 KiB
C#
239 lines
6.0 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
[AddComponentMenu("Image Effects/Tonemapping")]
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera))]
|
|
public class Tonemapping : PostEffectsBase
|
|
{
|
|
[Serializable]
|
|
public enum TonemapperType
|
|
{
|
|
SimpleReinhard = 0,
|
|
UserCurve = 1,
|
|
Hable = 2,
|
|
Photographic = 3,
|
|
OptimizedHejiDawson = 4,
|
|
AdaptiveReinhard = 5,
|
|
AdaptiveReinhardAutoWhite = 6
|
|
}
|
|
|
|
[Serializable]
|
|
public enum AdaptiveTexSize
|
|
{
|
|
Square16 = 0x10,
|
|
Square32 = 0x20,
|
|
Square64 = 0x40,
|
|
Square128 = 0x80,
|
|
Square256 = 0x100,
|
|
Square512 = 0x200,
|
|
Square1024 = 0x400
|
|
}
|
|
|
|
public TonemapperType type;
|
|
|
|
public AdaptiveTexSize adaptiveTextureSize;
|
|
|
|
public AnimationCurve remapCurve;
|
|
|
|
private Texture2D curveTex;
|
|
|
|
public float exposureAdjustment;
|
|
|
|
public float middleGrey;
|
|
|
|
public float white;
|
|
|
|
public float adaptionSpeed;
|
|
|
|
public Shader tonemapper;
|
|
|
|
public bool validRenderTextureFormat;
|
|
|
|
private Material tonemapMaterial;
|
|
|
|
private RenderTexture rt;
|
|
|
|
public Tonemapping()
|
|
{
|
|
type = TonemapperType.SimpleReinhard;
|
|
adaptiveTextureSize = AdaptiveTexSize.Square256;
|
|
exposureAdjustment = 1.5f;
|
|
middleGrey = 0.4f;
|
|
white = 2f;
|
|
adaptionSpeed = 1.5f;
|
|
validRenderTextureFormat = true;
|
|
}
|
|
|
|
public virtual void OnDisable()
|
|
{
|
|
if ((bool)tonemapMaterial)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(tonemapMaterial);
|
|
}
|
|
}
|
|
|
|
public override bool CheckResources()
|
|
{
|
|
CheckSupport(false, true);
|
|
tonemapMaterial = CheckShaderAndCreateMaterial(tonemapper, tonemapMaterial);
|
|
if (!curveTex && type == TonemapperType.UserCurve)
|
|
{
|
|
curveTex = new Texture2D(256, 1, TextureFormat.ARGB32, false, true);
|
|
curveTex.filterMode = FilterMode.Bilinear;
|
|
curveTex.wrapMode = TextureWrapMode.Clamp;
|
|
curveTex.hideFlags = HideFlags.DontSave;
|
|
}
|
|
if (!isSupported)
|
|
{
|
|
ReportAutoDisable();
|
|
}
|
|
return isSupported;
|
|
}
|
|
|
|
public virtual float UpdateCurve()
|
|
{
|
|
float num = 1f;
|
|
if (remapCurve == null)
|
|
{
|
|
remapCurve = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(2f, 1f));
|
|
}
|
|
if (remapCurve != null)
|
|
{
|
|
if (remapCurve.length != 0)
|
|
{
|
|
num = remapCurve[remapCurve.length - 1].time;
|
|
}
|
|
for (float num2 = 0f; num2 <= 1f; num2 += 0.003921569f)
|
|
{
|
|
float num3 = remapCurve.Evaluate(num2 * 1f * num);
|
|
curveTex.SetPixel((int)Mathf.Floor(num2 * 255f), 0, new Color(num3, num3, num3));
|
|
}
|
|
curveTex.Apply();
|
|
}
|
|
return 1f / num;
|
|
}
|
|
|
|
public virtual bool CreateInternalRenderTexture()
|
|
{
|
|
int result;
|
|
if ((bool)rt)
|
|
{
|
|
result = 0;
|
|
}
|
|
else
|
|
{
|
|
rt = new RenderTexture(1, 1, 0, RenderTextureFormat.ARGBHalf);
|
|
RenderTexture renderTexture = RenderTexture.active;
|
|
RenderTexture.active = rt;
|
|
GL.Clear(false, true, Color.white);
|
|
rt.hideFlags = HideFlags.DontSave;
|
|
RenderTexture.active = renderTexture;
|
|
result = 1;
|
|
}
|
|
return (byte)result != 0;
|
|
}
|
|
|
|
[ImageEffectTransformsToLDR]
|
|
public virtual void OnRenderImage(RenderTexture source, RenderTexture destination)
|
|
{
|
|
if (!CheckResources())
|
|
{
|
|
Graphics.Blit(source, destination);
|
|
return;
|
|
}
|
|
exposureAdjustment = ((exposureAdjustment >= 0.001f) ? exposureAdjustment : 0.001f);
|
|
if (type == TonemapperType.UserCurve)
|
|
{
|
|
float value = UpdateCurve();
|
|
tonemapMaterial.SetFloat("_RangeScale", value);
|
|
tonemapMaterial.SetTexture("_Curve", curveTex);
|
|
Graphics.Blit(source, destination, tonemapMaterial, 4);
|
|
return;
|
|
}
|
|
if (type == TonemapperType.SimpleReinhard)
|
|
{
|
|
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
|
Graphics.Blit(source, destination, tonemapMaterial, 6);
|
|
return;
|
|
}
|
|
if (type == TonemapperType.Hable)
|
|
{
|
|
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
|
Graphics.Blit(source, destination, tonemapMaterial, 5);
|
|
return;
|
|
}
|
|
if (type == TonemapperType.Photographic)
|
|
{
|
|
tonemapMaterial.SetFloat("_ExposureAdjustment", exposureAdjustment);
|
|
Graphics.Blit(source, destination, tonemapMaterial, 8);
|
|
return;
|
|
}
|
|
if (type == TonemapperType.OptimizedHejiDawson)
|
|
{
|
|
tonemapMaterial.SetFloat("_ExposureAdjustment", 0.5f * exposureAdjustment);
|
|
Graphics.Blit(source, destination, tonemapMaterial, 7);
|
|
return;
|
|
}
|
|
bool flag = CreateInternalRenderTexture();
|
|
RenderTexture temporary = RenderTexture.GetTemporary((int)adaptiveTextureSize, (int)adaptiveTextureSize, 0, RenderTextureFormat.ARGBHalf);
|
|
Graphics.Blit(source, temporary);
|
|
int num = (int)Mathf.Log((float)temporary.width * 1f, 2f);
|
|
int num2 = 2;
|
|
RenderTexture[] array = new RenderTexture[num];
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
array[i] = RenderTexture.GetTemporary(temporary.width / num2, temporary.width / num2, 0, RenderTextureFormat.ARGBHalf);
|
|
num2 *= 2;
|
|
}
|
|
float num3 = (float)source.width * 1f / ((float)source.height * 1f);
|
|
RenderTexture source2 = array[num - 1];
|
|
Graphics.Blit(temporary, array[0], tonemapMaterial, 1);
|
|
if (type == TonemapperType.AdaptiveReinhardAutoWhite)
|
|
{
|
|
for (int i = 0; i < num - 1; i++)
|
|
{
|
|
Graphics.Blit(array[i], array[i + 1], tonemapMaterial, 9);
|
|
source2 = array[i + 1];
|
|
}
|
|
}
|
|
else if (type == TonemapperType.AdaptiveReinhard)
|
|
{
|
|
for (int i = 0; i < num - 1; i++)
|
|
{
|
|
Graphics.Blit(array[i], array[i + 1]);
|
|
source2 = array[i + 1];
|
|
}
|
|
}
|
|
adaptionSpeed = ((adaptionSpeed >= 0.001f) ? adaptionSpeed : 0.001f);
|
|
tonemapMaterial.SetFloat("_AdaptionSpeed", adaptionSpeed);
|
|
Graphics.Blit(source2, rt, tonemapMaterial, 2);
|
|
middleGrey = ((middleGrey >= 0.001f) ? middleGrey : 0.001f);
|
|
tonemapMaterial.SetVector("_HdrParams", new Vector4(middleGrey, middleGrey, middleGrey, white * white));
|
|
tonemapMaterial.SetTexture("_SmallTex", rt);
|
|
if (type == TonemapperType.AdaptiveReinhard)
|
|
{
|
|
Graphics.Blit(source, destination, tonemapMaterial, 0);
|
|
}
|
|
else if (type == TonemapperType.AdaptiveReinhardAutoWhite)
|
|
{
|
|
Graphics.Blit(source, destination, tonemapMaterial, 10);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("No valid adaptive tonemapper type found!");
|
|
Graphics.Blit(source, destination);
|
|
}
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
RenderTexture.ReleaseTemporary(array[i]);
|
|
}
|
|
RenderTexture.ReleaseTemporary(temporary);
|
|
}
|
|
|
|
public override void Main()
|
|
{
|
|
}
|
|
}
|