-
Notifications
You must be signed in to change notification settings - Fork 1
/
C_Color_Balance.dctl
81 lines (70 loc) · 3.21 KB
/
C_Color_Balance.dctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
Color Balance
Version 004
- Use perceptual luminance.
- Optimize performance.
****************************************************************************************/
__CONSTANT__ int ZOOM = 1; // Increase to ZOOM into the shadows.
__CONSTANT__ int SAMPLE = 16; // Lower for more accuracy, raise for better performance.
__CONSTANT__ int PANEL_COUNT = 26; // Defines the number of horizontal panels (25 max or increase arrays)
__CONSTANT__ int PANEL_SPACING = 20; // The larger the number the smaller the height of the panels.
__DEVICE__ float perceptual(float3 x)
{
x.x = x.x <= 0.081f ? x.x / 4.5f : _powf((x.x + 0.099f)/1.099f, 1.0f/0.45f);
x.y = x.y <= 0.081f ? x.y / 4.5f : _powf((x.y + 0.099f)/1.099f, 1.0f/0.45f);
x.z = x.z <= 0.081f ? x.z / 4.5f : _powf((x.z + 0.099f)/1.099f, 1.0f/0.45f);
return x.x * 0.2126f + x.y * 0.7152f + x.z * 0.0722f;
}
__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, __TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB)
{
const int panel_width = (int) p_Width / PANEL_COUNT;
const int panel_height = (int) p_Height / PANEL_SPACING;
const int panel_zoom = PANEL_COUNT * ZOOM;
if (p_Y < panel_height * ((float) PANEL_SPACING - 1.5f))
return make_float3(_tex2D(p_TexR, p_X, p_Y),
_tex2D(p_TexG, p_X, p_Y),
_tex2D(p_TexB, p_X, p_Y));
else
{
float R[26] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
float G[26] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
float B[26] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
int SUM[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for (int i = SAMPLE-1; i < p_Width; i+=SAMPLE)
for (int j = (SAMPLE/2)-1; j < p_Height; j+=SAMPLE/2)
{
float3 x = make_float3(_tex2D(p_TexR, i, j),
_tex2D(p_TexG, i, j),
_tex2D(p_TexB, i, j));
const int idx = (int) (perceptual(x) * panel_zoom);
if (idx >= 0 && idx < PANEL_COUNT)
{
R[idx] += x.x;
G[idx] += x.y;
B[idx] += x.z;
SUM[idx]++;
}
}
int idx = (int) p_X / panel_width;
if (p_Y < panel_height*(PANEL_SPACING - 1))
{
float level = (float) (2*idx+1) / (2*panel_zoom);
float p = level <= 0.018f ? level * 4.5f : 1.099f *_powf(level,0.45f) - 0.099f;
return make_float3(p,p,p);
}
else
if (SUM[idx] >= 1)
return make_float3(R[idx]/SUM[idx],G[idx]/SUM[idx],B[idx]/SUM[idx]);
else
if (p_Y % 2)
return make_float3(0.3f,0.2f,0.1f);
else
return make_float3(0.1f,0.2f,0.3f);
}
}