1 Shader "Hidden/Tonemapper" {
2     Properties {
3         _MainTex (
"", 2D) = "black" {}
4         _SmallTex (
"", 2D) = "grey" {}
5         _Curve (
"", 2D) = "black" {}
6     }
7     
8     CGINCLUDE
9     
10     #include
"UnityCG.cginc"
11      
12     
struct v2f {
13         float4 pos : SV_POSITION;
14         float2 uv : TEXCOORD0;
15     };
16     
17     sampler2D _MainTex;
18     sampler2D _SmallTex;
19     sampler2D _Curve;
20     
21     float4 _HdrParams;
22     float2 intensity;
23     float4 _MainTex_TexelSize;
24     
float _AdaptionSpeed;
25     
float _ExposureAdjustment;
26     
float _RangeScale;
27     
28     v2f vert( appdata_img v )
29     {
30         v2f o;
31         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
32         o.uv = v.texcoord.xy;
33         
return o;
34     }
35
36     float4 fragLog(v2f i) : SV_Target
37     {
38         
const float DELTA = 0.0001f;
39  
40         
float fLogLumSum = 0.0f;
41  
42         fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-
1,-1)).rgb) + DELTA);
43         fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(
1,1)).rgb) + DELTA);
44         fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-
1,1)).rgb) + DELTA);
45         fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(
1,-1)).rgb) + DELTA);
46
47         
float avg = fLogLumSum / 4.0;
48         
return float4(avg, avg, avg, avg);
49     }
50
51     float4 fragExp(v2f i) : SV_Target
52     {
53         float2 lum = float2(
0.0f, 0.0f);
54         
55         lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-
1,-1)).xy;
56         lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(
1,1)).xy;
57         lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(
1,-1)).xy;
58         lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-
1,1)).xy;
59
60         lum = exp(lum /
4.0f);
61         
62         
return float4(lum.x, lum.y, lum.x, saturate(0.0125 * _AdaptionSpeed));
63     }
64             
65     float3 ToCIE(float3 FullScreenImage)
66     {
67         
// RGB -> XYZ conversion
68         
// http://www.w3.org/Graphics/Color/sRGB
69         
// The official sRGB to XYZ conversion matrix is (following ITU-R BT.709)
70         
// 0.4125 0.3576 0.1805
71         
// 0.2126 0.7152 0.0722
72         
// 0.0193 0.1192 0.9505
73          
74         float3x3 RGB2XYZ = {
0.5141364, 0.3238786, 0.16036376, 0.265068, 0.67023428, 0.06409157, 0.0241188, 0.1228178, 0.84442666};
75          
76         float3 XYZ = mul(RGB2XYZ, FullScreenImage.rgb);
77          
78         
// XYZ -> Yxy conversion
79          
80         float3 Yxy;
81          
82         Yxy.r = XYZ.g;
83          
84         
// x = X / (X + Y + Z)
85         
// y = X / (X + Y + Z)
86          
87         
float temp = dot(float3(1.0,1.0,1.0), XYZ.rgb);
88          
89         Yxy.gb = XYZ.rg / temp;
90         
91         
return Yxy;
92     }
93     
94     float3 FromCIE(float3 Yxy)
95     {
96         float3 XYZ;
97         
// Yxy -> XYZ conversion
98         XYZ.r = Yxy.r * Yxy.g / Yxy. b;
99          
100         
// X = Y * x / y
101         XYZ.g = Yxy.r;
102          
103         
// copy luminance Y
104         XYZ.b = Yxy.r * (
1 - Yxy.g - Yxy.b) / Yxy.b;
105          
106         
// Z = Y * (1-x-y) / y
107          
108         
// XYZ -> RGB conversion
109         
// The official XYZ to sRGB conversion matrix is (following ITU-R BT.709)
110         
// 3.2410 -1.5374 -0.4986
111         
// -0.9692 1.8760 0.0416
112         
// 0.0556 -0.2040 1.0570
113  
114         float3x3 XYZ2RGB = {
2.5651,-1.1665,-0.3986, -1.0217, 1.9777, 0.0439, 0.0753, -0.2543, 1.1892};
115
116         
return mul(XYZ2RGB, XYZ);
117     }
118             
119     
// NOTE/OPTIMIZATION: we're not going the extra CIE detour anymore, but
120     
// scale with the OUT/IN luminance ratio,this is sooooo much faster
121     
122     float4 fragAdaptive(v2f i) : SV_Target
123     {
124         
float avgLum = tex2D(_SmallTex, i.uv).x;
125         float4 color = tex2D (_MainTex, i.uv);
126         
127         
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
128         
129         
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
130         
131         lumScaled = (lumScaled * (
1.0f + lumScaled / (_HdrParams.w)))/(1.0f + lumScaled);
132         
133         
//cie.r = lumScaled;
134         
135         color.rgb = color.rgb * (lumScaled / cieLum);
136         
137         
//color.rgb = FromCIE(cie);
138         
return color;
139     }
140     
141     float4 fragAdaptiveAutoWhite(v2f i) : SV_Target
142     {
143         float2 avgLum = tex2D(_SmallTex, i.uv).xy;
144         float4 color = tex2D(_MainTex, i.uv);
145         
146         
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
147         
148         
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
149         
150         lumScaled = (lumScaled * (
1.0f + lumScaled / (avgLum.y*avgLum.y)))/(1.0f + lumScaled);
151         
152         
//cie.r = lumScaled;
153         
154         color.rgb = color.rgb * (lumScaled / cieLum);
155         
156         
//color.rgb = FromCIE(cie);
157         
return color;
158     }
159     
160     float4 fragCurve(v2f i) : SV_Target
161     {
162         float4 color = tex2D(_MainTex, i.uv);
163         float3 cie = ToCIE(color.rgb);
164         
165         
// Remap to new lum range
166         
float newLum = tex2D(_Curve, float2(cie.r * _RangeScale, 0.5)).r;
167         cie.r = newLum;
168         color.rgb = FromCIE(cie);
169         
170         
return color;
171     }
172     
173     float4 fragHable(v2f i) : SV_Target
174     {
175         
const float A = 0.15;
176         
const float B = 0.50;
177         
const float C = 0.10;
178         
const float D = 0.20;
179         
const float E = 0.02;
180         
const float F = 0.30;
181         
const float W = 11.2;
182
183         float3 texColor = tex2D(_MainTex, i.uv).rgb;
184         texColor *= _ExposureAdjustment;
185
186         
float ExposureBias = 2.0;
187         float3 x = ExposureBias*texColor;
188         float3 curr = ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
189         
190         x = W;
191         float3 whiteScale =
1.0f/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);
192         float3 color = curr*whiteScale;
193
194         
// float3 retColor = pow(color,1/2.2); // we have SRGB write enabled at this stage
195
196         
return float4(color, 1.0);
197     }
198
199     
// we are doing it on luminance here (better color preservation, but some other problems like very fast saturation)
200     float4 fragSimpleReinhard(v2f i) : SV_Target
201     {
202         float4 texColor = tex2D(_MainTex, i.uv);
203         
float lum = Luminance(texColor.rgb);
204         
float lumTm = lum * _ExposureAdjustment;
205         
float scale = lumTm / (1+lumTm);
206         
return float4(texColor.rgb * scale / lum, texColor.a);
207     }
208     
209     float4 fragOptimizedHejiDawson(v2f i) : SV_Target
210     {
211         float4 texColor = tex2D(_MainTex, i.uv );
212         texColor *= _ExposureAdjustment;
213         float4 X = max(float4(
0.0,0.0,0.0,0.0), texColor-0.004);
214         float4 retColor = (X*(
6.2*X+.5))/(X*(6.2*X+1.7)+0.06);
215         
return retColor*retColor;
216     }
217
218     float4 fragPhotographic(v2f i) : SV_Target
219     {
220         float4 texColor = tex2D(_MainTex, i.uv);
221         
return 1-exp2(-_ExposureAdjustment * texColor);
222     }
223     
224     float4 fragDownsample(v2f i) : SV_Target
225     {
226         float4 tapA = tex2D(_MainTex, i.uv + _MainTex_TexelSize *
0.5);
227         float4 tapB = tex2D(_MainTex, i.uv - _MainTex_TexelSize *
0.5);
228         float4 tapC = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(
0.5,-0.5));
229         float4 tapD = tex2D(_MainTex, i.uv - _MainTex_TexelSize * float2(
0.5,-0.5));
230         
231         float4 average = (tapA+tapB+tapC+tapD)/
4;
232         average.y = max(max(tapA.y,tapB.y), max(tapC.y,tapD.y));
233         
234         
return average;
235     }
236     
237     ENDCG
238     
239 Subshader {
240  
// adaptive reinhhard apply
241  Pass {
242       ZTest Always Cull Off ZWrite Off
243
244       CGPROGRAM
245       #pragma vertex vert
246       #pragma fragment fragAdaptive
247       ENDCG
248   }
249
250   
// 1
251  Pass {
252       ZTest Always Cull Off ZWrite Off
253
254       CGPROGRAM
255       #pragma vertex vert
256       #pragma fragment fragLog
257       ENDCG
258   }
259   
// 2
260  Pass {
261       ZTest Always Cull Off ZWrite Off
262       Blend SrcAlpha OneMinusSrcAlpha
263
264       CGPROGRAM
265       #pragma vertex vert
266       #pragma fragment fragExp
267       ENDCG
268   }
269   
// 3
270  Pass {
271       ZTest Always Cull Off ZWrite Off
272
273       Blend Off
274
275       CGPROGRAM
276       #pragma vertex vert
277       #pragma fragment fragExp
278       ENDCG
279   }
280   
281   
// 4 user controllable tonemap curve
282   Pass {
283       ZTest Always Cull Off ZWrite Off
284
285       CGPROGRAM
286       #pragma vertex vert
287       #pragma fragment fragCurve
288       ENDCG
289   }
290
291   
// 5 tonemapping in uncharted
292   Pass {
293       ZTest Always Cull Off ZWrite Off
294
295       CGPROGRAM
296       #pragma vertex vert
297       #pragma fragment fragHable
298       ENDCG
299   }
300
301   
// 6 simple tonemapping based reinhard
302   Pass {
303       ZTest Always Cull Off ZWrite Off
304
305       CGPROGRAM
306       #pragma vertex vert
307       #pragma fragment fragSimpleReinhard
308       ENDCG
309   }
310
311   
// 7 OptimizedHejiDawson
312   Pass {
313       ZTest Always Cull Off ZWrite Off
314
315       CGPROGRAM
316       #pragma vertex vert
317       #pragma fragment fragOptimizedHejiDawson
318       ENDCG
319   }
320   
321   
// 8 Photographic
322   Pass {
323       ZTest Always Cull Off ZWrite Off
324
325       CGPROGRAM
326       #pragma vertex vert
327       #pragma fragment fragPhotographic
328       ENDCG
329   }
330
331   
// 9 Downsample with auto white detection
332   Pass {
333       ZTest Always Cull Off ZWrite Off
334
335       CGPROGRAM
336       #pragma vertex vert
337       #pragma fragment fragDownsample
338       ENDCG
339   }
340   
341  
// 10 adaptive reinhhard apply with auto white
342  Pass {
343       ZTest Always Cull Off ZWrite Off
344
345       CGPROGRAM
346       #pragma vertex vert
347       #pragma fragment fragAdaptiveAutoWhite
348       ENDCG
349   }
350 }
351
352 Fallback off
353     
354 }
// shader


Gõ tìm kiếm nhanh...