1 using System;
2 using
UnityEngine;
3
4 namespace
UnityStandardAssets.ImageEffects
5 {
6     
[ExecuteInEditMode]
7     
[AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (3D Lookup Texture)")]
8     
public class ColorCorrectionLookup : PostEffectsBase
9     {
10         
public Shader shader;
11         
private Material material;
12
13         
// serialize this instead of having another 2d texture ref'ed
14         
public Texture3D converted3DLut = null;
15         
public string basedOnTempTex = "";
16
17
18         
public override bool CheckResources () {
19             CheckSupport (
false);
20
21             material = CheckShaderAndCreateMaterial (shader, material);
22
23             
if (!isSupported || !SystemInfo.supports3DTextures)
24                 ReportAutoDisable ();
25             
return isSupported;
26         }
27
28         
void OnDisable () {
29             
if (material) {
30                 DestroyImmediate (material);
31                 material =
null;
32             }
33         }
34
35         
void OnDestroy () {
36             
if (converted3DLut)
37                 DestroyImmediate (converted3DLut);
38             converted3DLut =
null;
39         }
40
41         
public void SetIdentityLut () {
42             
int dim = 16;
43             
var newC = new Color[dim*dim*dim];
44             
float oneOverDim = 1.0f / (1.0f * dim - 1.0f);
45
46             
for(int i = 0; i < dim; i++) {
47                 
for(int j = 0; j < dim; j++) {
48                     
for(int k = 0; k < dim; k++) {
49                         newC[i + (j*dim) + (k*dim*dim)] =
new Color((i*1.0f)*oneOverDim, (j*1.0f)*oneOverDim, (k*1.0f)*oneOverDim, 1.0f);
50                     }
51                 }
52             }
53
54             
if (converted3DLut)
55                 DestroyImmediate (converted3DLut);
56             converted3DLut =
new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
57             converted3DLut.SetPixels (newC);
58             converted3DLut.Apply ();
59             basedOnTempTex =
"";
60         }
61
62         
public bool ValidDimensions ( Texture2D tex2d) {
63             
if (!tex2d) return false;
64             
int h = tex2d.height;
65             
if (h != Mathf.FloorToInt(Mathf.Sqrt(tex2d.width))) {
66                 
return false;
67             }
68             
return true;
69         }
70
71         
public void Convert ( Texture2D temp2DTex, string path) {
72
73             
// conversion fun: the given 2D texture needs to be of the format
74             
// w * h, wheras h is the 'depth' (or 3d dimension 'dim') and w = dim * dim
75
76             
if (temp2DTex) {
77                 
int dim = temp2DTex.width * temp2DTex.height;
78                 dim = temp2DTex.height;
79
80                 
if (!ValidDimensions(temp2DTex)) {
81                     Debug.LogWarning (
"The given 2D texture " + temp2DTex.name + " cannot be used as a 3D LUT.");
82                     basedOnTempTex =
"";
83                     
return;
84                 }
85
86                 
var c = temp2DTex.GetPixels();
87                 
var newC = new Color[c.Length];
88
89                 
for(int i = 0; i < dim; i++) {
90                     
for(int j = 0; j < dim; j++) {
91                         
for(int k = 0; k < dim; k++) {
92                             
int j_ = dim-j-1;
93                             newC[i + (j*dim) + (k*dim*dim)] = c[k*dim+i+j_*dim*dim];
94                         }
95                     }
96                 }
97
98                 
if (converted3DLut)
99                     DestroyImmediate (converted3DLut);
100                 converted3DLut =
new Texture3D (dim, dim, dim, TextureFormat.ARGB32, false);
101                 converted3DLut.SetPixels (newC);
102                 converted3DLut.Apply ();
103                 basedOnTempTex = path;
104             }
105             
else {
106                 
// error, something went terribly wrong
107                 Debug.LogError (
"Couldn't color correct with 3D LUT texture. Image Effect will be disabled.");
108             }
109         }
110
111         
void OnRenderImage (RenderTexture source, RenderTexture destination) {
112             
if (CheckResources () == false || !SystemInfo.supports3DTextures) {
113                 Graphics.Blit (source, destination);
114                 
return;
115             }
116
117             
if (converted3DLut == null) {
118                 SetIdentityLut ();
119             }
120
121             
int lutSize = converted3DLut.width;
122             converted3DLut.wrapMode = TextureWrapMode.Clamp;
123             material.SetFloat(
"_Scale", (lutSize - 1) / (1.0f*lutSize));
124             material.SetFloat(
"_Offset", 1.0f / (2.0f * lutSize));
125             material.SetTexture(
"_ClutTex", converted3DLut);
126
127             Graphics.Blit (source, destination, material, QualitySettings.activeColorSpace == ColorSpace.Linear ?
1 : 0);
128         }
129     }
130 }