您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
130 行
3.4 KiB
130 行
3.4 KiB
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
|
|
|
|
[ExecuteInEditMode]
|
|
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (3D Lookup Texture)")]
|
|
public class ColorCorrectionLookup : PostEffectsBase
|
|
{
|
|
public Shader shader;
|
|
private Material material;
|
|
|
|
// serialize this instead of having another 2d texture ref'ed
|
|
public Texture3D converted3DLut = null;
|
|
public string basedOnTempTex = "";
|
|
|
|
|
|
public override bool CheckResources (){
|
|
CheckSupport (false);
|
|
|
|
material = CheckShaderAndCreateMaterial (shader, material);
|
|
|
|
if(!isSupported || !SystemInfo.supports3DTextures)
|
|
ReportAutoDisable ();
|
|
return isSupported;
|
|
}
|
|
|
|
void OnDisable (){
|
|
if (material) {
|
|
DestroyImmediate (material);
|
|
material = null;
|
|
}
|
|
}
|
|
|
|
void OnDestroy (){
|
|
if (converted3DLut)
|
|
DestroyImmediate (converted3DLut);
|
|
converted3DLut = null;
|
|
}
|
|
|
|
public void SetIdentityLut (){
|
|
int dim = 16;
|
|
Color[] newC = new Color[dim*dim*dim];
|
|
float oneOverDim = 1.0f / (1.0f * dim - 1.0f);
|
|
|
|
for(int i = 0; i < dim; i++) {
|
|
for(int j = 0; j < dim; j++) {
|
|
for(int k = 0; k < dim; k++) {
|
|
newC[i + (j*dim) + (k*dim*dim)] = new Color((i*1.0f)*oneOverDim, (j*1.0f)*oneOverDim, (k*1.0f)*oneOverDim, 1.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (converted3DLut)
|
|
DestroyImmediate (converted3DLut);
|
|
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
|
converted3DLut.SetPixels (newC);
|
|
converted3DLut.Apply ();
|
|
basedOnTempTex = "";
|
|
}
|
|
|
|
public bool ValidDimensions ( Texture2D tex2d ){
|
|
if (!tex2d) return false;
|
|
int h = tex2d.height;
|
|
if (h != Mathf.FloorToInt(Mathf.Sqrt(tex2d.width))) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void Convert ( Texture2D temp2DTex , string path ){
|
|
|
|
// conversion fun: the given 2D texture needs to be of the format
|
|
// w * h, wheras h is the 'depth' (or 3d dimension 'dim') and w = dim * dim
|
|
|
|
if (temp2DTex) {
|
|
int dim = temp2DTex.width * temp2DTex.height;
|
|
dim = temp2DTex.height;
|
|
|
|
if (!ValidDimensions(temp2DTex)) {
|
|
Debug.LogWarning ("The given 2D texture " + temp2DTex.name + " cannot be used as a 3D LUT.");
|
|
basedOnTempTex = "";
|
|
return;
|
|
}
|
|
|
|
Color[] c = temp2DTex.GetPixels();
|
|
Color[] newC = new Color[c.Length];
|
|
|
|
for(int i = 0; i < dim; i++) {
|
|
for(int j = 0; j < dim; j++) {
|
|
for(int k = 0; k < dim; k++) {
|
|
int j_ = dim-j-1;
|
|
newC[i + (j*dim) + (k*dim*dim)] = c[k*dim+i+j_*dim*dim];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (converted3DLut)
|
|
DestroyImmediate (converted3DLut);
|
|
converted3DLut = new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
|
|
converted3DLut.SetPixels (newC);
|
|
converted3DLut.Apply ();
|
|
basedOnTempTex = path;
|
|
}
|
|
else {
|
|
// error, something went terribly wrong
|
|
Debug.LogError ("Couldn't color correct with 3D LUT texture. Image Effect will be disabled.");
|
|
}
|
|
}
|
|
|
|
void OnRenderImage ( RenderTexture source , RenderTexture destination ){
|
|
if(CheckResources () == false || !SystemInfo.supports3DTextures) {
|
|
Graphics.Blit (source, destination);
|
|
return;
|
|
}
|
|
|
|
if (converted3DLut == null) {
|
|
SetIdentityLut ();
|
|
}
|
|
|
|
int lutSize = converted3DLut.width;
|
|
converted3DLut.wrapMode = TextureWrapMode.Clamp;
|
|
material.SetFloat("_Scale", (lutSize - 1) / (1.0f*lutSize));
|
|
material.SetFloat("_Offset", 1.0f / (2.0f * lutSize));
|
|
material.SetTexture("_ClutTex", converted3DLut);
|
|
|
|
Graphics.Blit (source, destination, material, QualitySettings.activeColorSpace == ColorSpace.Linear ? 1 : 0);
|
|
}
|
|
}
|
|
|