228 lines
6.1 KiB
C#
228 lines
6.1 KiB
C#
using UnityEngine;
|
|
|
|
namespace UnityStandardAssets.ImageEffects
|
|
{
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera))]
|
|
[AddComponentMenu("Image Effects/Color Adjustments/Tonemapping")]
|
|
public class Tonemapping : PostEffectsBase
|
|
{
|
|
public enum TonemapperType
|
|
{
|
|
SimpleReinhard = 0,
|
|
UserCurve = 1,
|
|
Hable = 2,
|
|
Photographic = 3,
|
|
OptimizedHejiDawson = 4,
|
|
AdaptiveReinhard = 5,
|
|
AdaptiveReinhardAutoWhite = 6
|
|
}
|
|
|
|
public enum AdaptiveTexSize
|
|
{
|
|
Square16 = 0x10,
|
|
Square32 = 0x20,
|
|
Square64 = 0x40,
|
|
Square128 = 0x80,
|
|
Square256 = 0x100,
|
|
Square512 = 0x200,
|
|
Square1024 = 0x400
|
|
}
|
|
|
|
public TonemapperType type = TonemapperType.Photographic;
|
|
|
|
public AdaptiveTexSize adaptiveTextureSize = AdaptiveTexSize.Square256;
|
|
|
|
public AnimationCurve remapCurve;
|
|
|
|
private Texture2D curveTex;
|
|
|
|
public float exposureAdjustment = 1.5f;
|
|
|
|
public float middleGrey = 0.4f;
|
|
|
|
public float white = 2f;
|
|
|
|
public float adaptionSpeed = 1.5f;
|
|
|
|
public Shader tonemapper;
|
|
|
|
public bool validRenderTextureFormat = true;
|
|
|
|
private Material tonemapMaterial;
|
|
|
|
private RenderTexture rt;
|
|
|
|
private RenderTextureFormat rtFormat = RenderTextureFormat.ARGBHalf;
|
|
|
|
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 float UpdateCurve()
|
|
{
|
|
float num = 1f;
|
|
if (remapCurve.keys.Length < 1)
|
|
{
|
|
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;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if ((bool)rt)
|
|
{
|
|
Object.DestroyImmediate(rt);
|
|
rt = null;
|
|
}
|
|
if ((bool)tonemapMaterial)
|
|
{
|
|
Object.DestroyImmediate(tonemapMaterial);
|
|
tonemapMaterial = null;
|
|
}
|
|
if ((bool)curveTex)
|
|
{
|
|
Object.DestroyImmediate(curveTex);
|
|
curveTex = null;
|
|
}
|
|
}
|
|
|
|
private bool CreateInternalRenderTexture()
|
|
{
|
|
if ((bool)rt)
|
|
{
|
|
return false;
|
|
}
|
|
rtFormat = ((!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf)) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.RGHalf);
|
|
rt = new RenderTexture(1, 1, 0, rtFormat);
|
|
rt.hideFlags = HideFlags.DontSave;
|
|
return true;
|
|
}
|
|
|
|
[ImageEffectTransformsToLDR]
|
|
private 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, rtFormat);
|
|
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, rtFormat);
|
|
num2 *= 2;
|
|
}
|
|
RenderTexture source2 = array[num - 1];
|
|
Graphics.Blit(temporary, array[0], tonemapMaterial, 1);
|
|
if (type == TonemapperType.AdaptiveReinhardAutoWhite)
|
|
{
|
|
for (int j = 0; j < num - 1; j++)
|
|
{
|
|
Graphics.Blit(array[j], array[j + 1], tonemapMaterial, 9);
|
|
source2 = array[j + 1];
|
|
}
|
|
}
|
|
else if (type == TonemapperType.AdaptiveReinhard)
|
|
{
|
|
for (int k = 0; k < num - 1; k++)
|
|
{
|
|
Graphics.Blit(array[k], array[k + 1]);
|
|
source2 = array[k + 1];
|
|
}
|
|
}
|
|
adaptionSpeed = ((!(adaptionSpeed < 0.001f)) ? adaptionSpeed : 0.001f);
|
|
tonemapMaterial.SetFloat("_AdaptionSpeed", adaptionSpeed);
|
|
rt.MarkRestoreExpected();
|
|
Graphics.Blit(source2, rt, tonemapMaterial, (!flag) ? 2 : 3);
|
|
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 l = 0; l < num; l++)
|
|
{
|
|
RenderTexture.ReleaseTemporary(array[l]);
|
|
}
|
|
RenderTexture.ReleaseTemporary(temporary);
|
|
}
|
|
}
|
|
}
|