Improvements to Blenders color balance (lift/gamma/gain).

Fairly closely match some mac application colin has called 'Looks', to give better results.
- lift is now applied non linear (was being added to the color)
- change the color wheel to preserve the luminance of the gamma and gain values, this stops the color from being set too dark (option for the color wheel template).
- sub-pixel precission for the color wheel since the white area at the center can make a lot of difference with a very small change.

This change will make existing node and sequencer setups lift render slighly differently however discussed this with Ton and he's ok with it.
This commit is contained in:
Campbell Barton 2010-07-04 20:59:10 +00:00
parent 8f825bd460
commit 83a2a4e5b8
10 changed files with 60 additions and 28 deletions

@ -38,7 +38,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
col.operator("ptcache.remove", icon='ZOOMOUT', text="")
row = layout.row()
if cachetype in {'PSYS', 'HAIR', 'SMOKE'}:
if cachetype in ('PSYS', 'HAIR', 'SMOKE'):
row.prop(cache, "external")
if cache.external:

@ -753,11 +753,11 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel):
col.row().prop(strip.color_balance, "lift")
col.prop(strip.color_balance, "inverse_lift", text="Inverse")
col = row.column()
col.template_color_wheel(strip.color_balance, "gamma", value_slider=False)
col.template_color_wheel(strip.color_balance, "gamma", value_slider=False, lock_luminosity=True)
col.row().prop(strip.color_balance, "gamma")
col.prop(strip.color_balance, "inverse_gamma", text="Inverse")
col = row.column()
col.template_color_wheel(strip.color_balance, "gain", value_slider=False)
col.template_color_wheel(strip.color_balance, "gain", value_slider=False, lock_luminosity=True)
col.row().prop(strip.color_balance, "gain")
col.prop(strip.color_balance, "inverse_gain", text="Inverse")

@ -49,6 +49,7 @@
#include "RNA_access.h"
#include "RE_pipeline.h"
#include "BLI_math.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
@ -1528,32 +1529,35 @@ static void make_cb_table_byte(float lift, float gain, float gamma,
unsigned char * table, float mul)
{
int y;
/* matches 'LooksBuilder', generally looks nice too */
if(lift >= 1.0f) lift= 0.0f;
else lift= (1.0f - lift) * (1.0f - lift);
/* end modif's */
for (y = 0; y < 256; y++) {
float v = 1.0 * y / 255;
float v = (float)y * (1.0 / 255.0f);
v *= gain;
v += lift;
v = pow(v, lift);
v = pow(v, gamma);
v *= mul;
if ( v > 1.0) {
v = 1.0;
} else if (v < 0.0) {
v = 0.0;
}
CLAMP(v, 0.0f, 1.0f);
table[y] = v * 255;
}
}
static void make_cb_table_float(float lift, float gain, float gamma,
float * table, float mul)
{
int y;
/* matches 'LooksBuilder', generally looks nice too */
if(lift >= 1.0f) lift= 0.0f;
else lift= (1.0f - lift) * (1.0f - lift);
/* end modif's */
for (y = 0; y < 256; y++) {
float v = (float) y * 1.0 / 255.0;
float v = (float)y * (1.0 / 255.0f);
v *= gain;
v += lift;
v = pow(v, lift);
v = pow(v, gamma);
v *= mul;
table[y] = v;

@ -152,6 +152,8 @@ typedef struct uiLayout uiLayout;
#define UI_BUT_IMMEDIATE (1<<26)
#define UI_BUT_NO_TOOLTIP (1<<27)
#define UI_BUT_VEC_SIZE_LOCK (1<<28) /* used to flag if color hsv-circle should keep luminance */
#define UI_PANEL_WIDTH 340
#define UI_COMPACT_PANEL_WIDTH 160
@ -683,7 +685,7 @@ void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, char *propnam
void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels, int brush);
void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider, int lock);
void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider, int lock, int lock_luminosity);
void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname,
PointerRNA *used_ptr, char *used_propname, int active_layer);

@ -236,7 +236,7 @@ static uiBut *ui_but_last(uiBlock *block)
static int ui_is_a_warp_but(uiBut *but)
{
if(U.uiflag & USER_CONTINUOUS_MOUSE)
if(ELEM(but->type, NUM, NUMABS))
if(ELEM3(but->type, NUM, NUMABS, HSVCIRCLE))
return TRUE;
return FALSE;
@ -3064,10 +3064,22 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
if (but->a2 == 1) { // lock
if (hsv[2] == 0.f) hsv[2] = 0.0001f;
}
if(U.uiflag & USER_CONTINUOUS_MOUSE) {
/* slow down the mouse, this is fairly picky */
mx = (data->dragstartx*0.9 + mx*0.1);
my = (data->dragstarty*0.9 + my*0.1);
}
ui_hsvcircle_vals_from_pos(hsv, hsv+1, &rect, (float)mx, (float)my);
hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
if(but->flag & UI_BUT_VEC_SIZE_LOCK) {
normalize_v3(rgb);
mul_v3_fl(rgb, but->color_lum);
}
ui_set_but_vectorf(but, rgb);
data->draglastx= mx;

@ -173,6 +173,7 @@ struct uiBut {
float hardmin, hardmax, softmin, softmax;
float a1, a2, hsv[3]; // hsv is temp memory for hsv buttons
float aspect;
float color_lum; /* used only for color buttons so far */
uiButHandleFunc func;
void *func_arg1;
@ -184,8 +185,11 @@ struct uiBut {
struct bContextStore *context;
/* not ysed yet, was used in 2.4x for ui_draw_pulldown_round & friends */
/*
void (*embossfunc)(int , int , float, float, float, float, float, int);
void (*sliderfunc)(int , float, float, float, float, float, float, int);
*/
uiButCompleteFunc autocomplete_func;
void *autofunc_arg;
@ -228,12 +232,12 @@ struct uiBut {
/* Operator data */
struct wmOperatorType *optype;
int opcontext;
struct IDProperty *opproperties;
struct PointerRNA *opptr;
short opcontext;
/* Draggable data, type is WM_DRAG_... */
int dragtype;
short dragtype;
void *dragpoin;
struct ImBuf *imb;
float imb_scale;

@ -1949,11 +1949,12 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, i
#define WHEEL_SIZE 100
void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider, int lock)
void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider, int lock, int lock_luminosity)
{
PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
uiBlock *block= uiLayoutGetBlock(layout);
uiLayout *col, *row;
uiBut *but;
float softmin, softmax, step, precision;
if (!prop) {
@ -1966,8 +1967,15 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int
col = uiLayoutColumn(layout, 0);
row= uiLayoutRow(col, 1);
uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, lock, "");
but= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, lock, "");
if(lock_luminosity) {
float color[4]; /* incase of alpha */
but->flag |= UI_BUT_VEC_SIZE_LOCK;
RNA_property_float_get_array(ptr, prop, color);
but->color_lum= len_v3(color); /* abuse the soft-max though this is a kind of soft-max */
}
uiItemS(row);
if (value_slider)

@ -1674,6 +1674,7 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect)
float co= cos(ang);
ui_hsvcircle_vals_from_pos(hsv, hsv+1, rect, centx + co*radius, centy + si*radius);
CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
glColor3fv(col);
glVertex2f( centx + co*radius, centy + si*radius);
@ -1688,7 +1689,7 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect)
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH );
glColor3ubv((unsigned char*)wcol->outline);
glutil_draw_lined_arc(0.0f, M_PI*2.0, radius, tot);
glutil_draw_lined_arc(0.0f, M_PI*2.0, radius, tot + 1);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH );
glPopMatrix();

@ -107,7 +107,7 @@ static void node_buts_rgb(uiLayout *layout, bContext *C, PointerRNA *ptr)
RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
col = uiLayoutColumn(layout, 0);
uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0);
uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0, 0);
uiItemR(col, &sockptr, "default_value", 0, "", 0);
}
@ -947,17 +947,17 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *C, Point
split = uiLayoutSplit(layout, 0, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "lift", 1, 1);
uiTemplateColorWheel(col, ptr, "lift", 1, 1, 0);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "lift", 0, NULL, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "gamma", 1, 1);
uiTemplateColorWheel(col, ptr, "gamma", 1, 1, 1);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "gamma", 0, NULL, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "gain", 1, 1);
uiTemplateColorWheel(col, ptr, "gain", 1, 1, 1);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "gain", 0, NULL, 0);
@ -965,17 +965,17 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *C, Point
split = uiLayoutSplit(layout, 0, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "offset", 1, 1);
uiTemplateColorWheel(col, ptr, "offset", 1, 1, 0);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "offset", 0, NULL, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "power", 1, 1);
uiTemplateColorWheel(col, ptr, "power", 1, 1, 0);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "power", 0, NULL, 0);
col = uiLayoutColumn(split, 0);
uiTemplateColorWheel(col, ptr, "slope", 1, 1);
uiTemplateColorWheel(col, ptr, "slope", 1, 1, 0);
row = uiLayoutRow(col, 0);
uiItemR(row, ptr, "slope", 0, NULL, 0);
}

@ -360,6 +360,7 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
RNA_def_boolean(func, "value_slider", 0, "", "Display the value slider to the right of the color wheel");
RNA_def_boolean(func, "lock", 0, "", "Lock the color wheel display to value 1.0 regardless of actual color");
RNA_def_boolean(func, "lock_luminosity", 0, "", "Keep the color at its original vector length");
func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet");
api_ui_item_rna_common(func);