Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented color grading over new UI #1135

Merged
merged 3 commits into from
Dec 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ BreakConstructorInitializersBeforeComma: true
BreakStringLiterals: false

PenaltyBreakAssignment: 20
PenaltyBreakBeforeFirstCallParameter: 10000000
PenaltyBreakBeforeFirstCallParameter: 50
111 changes: 108 additions & 3 deletions apps/yimage/yimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ int run_convert(const convert_params& params) {
return 0;
}

// convert params
// view params
struct view_params {
vector<string> images = {"image.png"};
string output = "out.png";
Expand All @@ -360,14 +360,14 @@ void serialize_value(json_mode mode, json_value& json, view_params& value,

#ifndef YOCTO_OPENGL

// convert images
// view images
int run_view(const view_params& params) {
return print_fatal("Opengl not compiled");
}

#else

// convert images
// view images
int run_view(const view_params& params) {
// open viewer
auto viewer_guard = make_imageview("yimage");
Expand Down Expand Up @@ -410,6 +410,107 @@ int run_view(const view_params& params) {

#endif

// grade params
struct grade_params : colorgrade_params {
string image = "image.png";
string output = "out.png";
bool logo = false;
};

// Json IO
void serialize_value(json_mode mode, json_value& json, colorgrade_params& value,
const string& description) {
serialize_object(mode, json, value, description);
serialize_property(mode, json, value.exposure, "exposure", "Hdr exposure");
serialize_property(
mode, json, (array<float, 3>&)value.tint, "tint", "Hdr tint");
serialize_property(
mode, json, value.lincontrast, "lincontrast", "Hdr lin contrast");
serialize_property(
mode, json, value.logcontrast, "logcontrast", "Hdr log contrast");
serialize_property(
mode, json, value.linsaturation, "linsaturation", "Hdr saturation");
serialize_property(mode, json, value.filmic, "filmic", "Hdr filmic curve");
serialize_property(mode, json, value.srgb, "srgb", "sRGB coversion");
serialize_property(mode, json, value.contrast, "contrast", "Ldr contrast");
serialize_property(
mode, json, value.saturation, "saturation", "Ldr saturation");
serialize_property(mode, json, value.shadows, "shadows", "Ldr shadows");
serialize_property(mode, json, value.midtones, "midtones", "Ldr midtones");
serialize_property(
mode, json, value.highlights, "highlights", "Ldr highlights");
serialize_property(mode, json, (array<float, 3>&)value.shadows_color,
"shadows_color", "Ldr shadows color");
serialize_property(mode, json, (array<float, 3>&)value.midtones_color,
"midtones_color", "Ldr sidtones color");
serialize_property(mode, json, (array<float, 3>&)value.highlights_color,
"highlights_color", "Ldr sighlights color");
}

// Json IO
void serialize_value(json_mode mode, json_value& json, grade_params& value,
const string& description) {
serialize_object(mode, json, value, description);
serialize_property(mode, json, value.image, "image", "Input image.", true);
serialize_property(mode, json, value.output, "output", "Output image.");
serialize_value(mode, json, (colorgrade_params&)value, description);
serialize_clipositionals(mode, json, {"image"});
serialize_clialternates(mode, json, {{"output", "o"}});
}

#ifndef YOCTO_OPENGL

// grade images
int run_grade(const grade_params& params) {
return print_fatal("Opengl not compiled");
}

#else

// grade images
int run_grade(const grade_params& params) {
// open viewer
auto viewer_guard = make_imageview("yimage");
auto viewer = viewer_guard.get();

// load image
auto img = image<vec4f>{};
auto ioerror = string{};
if (is_preset_filename(params.image)) {
if (!make_image_preset(path_basename(params.image), img, ioerror))
return print_fatal(ioerror);
} else {
if (!load_image(params.image, img, ioerror)) return print_fatal(ioerror);
}

// grade image
auto graded = image<vec4b>{img.imsize()};
colorgrade_image_mt(graded, img, true, params);

// set view
set_image(viewer, params.image, graded);
set_params(
viewer, params.image, to_json(params), to_schema(params, "Color grade"));

// set callback
set_callback(viewer, [&params, &graded, &img, viewer](const string& name,
const json_value& uiparams, const gui_input&) {
if (uiparams.is_null()) return;
serialize_value(json_mode::from_json, (json_value&)uiparams,
(colorgrade_params&)params, "");
colorgrade_image_mt(graded, img, true, params);
set_image(viewer, name, graded);
});

// run view
run_view(viewer);

// done
return 0;
}

#endif

// resize params
struct diff_params {
string image1 = "image1.png";
Expand Down Expand Up @@ -569,6 +670,7 @@ struct app_params {
string command = "convert";
convert_params convert = {};
view_params view = {};
grade_params grade = {};
diff_params diff = {};
setalpha_params setalpha = {};
};
Expand All @@ -580,6 +682,7 @@ void serialize_value(json_mode mode, json_value& json, app_params& value,
serialize_command(mode, json, value.command, "command", "Command.");
serialize_property(mode, json, value.convert, "convert", "Convert images.");
serialize_property(mode, json, value.view, "view", "View images.");
serialize_property(mode, json, value.grade, "grade", "Grade images.");
serialize_property(mode, json, value.diff, "diff", "Diff two images.");
serialize_property(
mode, json, value.setalpha, "setalpha", "Set alpha in images.");
Expand All @@ -595,6 +698,8 @@ int main(int argc, const char* argv[]) {
return run_convert(params.convert);
} else if (params.command == "view") {
return run_view(params.view);
} else if (params.command == "grade") {
return run_grade(params.grade);
} else if (params.command == "diff") {
return run_diff(params.diff);
} else if (params.command == "setalpha") {
Expand Down
2 changes: 1 addition & 1 deletion apps/ymeshproc/ymeshproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ bool make_mesh_preset(vector<vec3i>& triangles, vector<vec3f>& positions,
triangles = quads_to_triangles(shape.quadspos);
positions = shape.positions;
normals = (shape.quadspos == shape.quadsnorm) ? shape.normals
: vector<vec3f>{};
: vector<vec3f>{};
texcoords = (shape.quadspos == shape.quadstexcoord) ? shape.texcoords
: vector<vec2f>{};
};
Expand Down
12 changes: 6 additions & 6 deletions libs/yocto/yocto_bvh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,13 @@ void set_shape(bvh_scene* bvh, int shape_id, const vector<int>& points,
shape->lines = as_view ? bvh_span{lines} : bvh_span{shape->lines_data};
shape->triangles_data = as_view ? vector<vec3i>{} : triangles;
shape->triangles = as_view ? bvh_span{triangles}
: bvh_span{shape->triangles_data};
shape->quads_data = as_view ? vector<vec4i>{} : quads;
shape->quads = as_view ? bvh_span{quads} : bvh_span{shape->quads_data};
: bvh_span{shape->triangles_data};
shape->quads_data = as_view ? vector<vec4i>{} : quads;
shape->quads = as_view ? bvh_span{quads} : bvh_span{shape->quads_data};
shape->positions_data = as_view ? vector<vec3f>{} : positions;
shape->positions = as_view ? bvh_span{positions}
: bvh_span{shape->positions_data};
shape->radius_data = as_view ? vector<float>{} : radius;
: bvh_span{shape->positions_data};
shape->radius_data = as_view ? vector<float>{} : radius;
shape->radius = as_view ? bvh_span{radius} : bvh_span{shape->radius_data};
}

Expand Down Expand Up @@ -757,7 +757,7 @@ void build_bvh(bvh_scene* scene, const bvh_params& params) {
auto instance = scene->instance_cb(idx);
auto& shape = scene->shapes[instance.shape];
bboxes[idx] = shape->bvh.nodes.empty() ? invalidb3f
: transform_bbox(instance.frame,
: transform_bbox(instance.frame,
shape->bvh.nodes[0].bbox);
}

Expand Down
4 changes: 2 additions & 2 deletions libs/yocto/yocto_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,8 @@ inline ray3f camera_ray(const frame3f& frame, float lens, float aspect,
float film_, const vec2f& image_uv) {
auto film = aspect >= 1 ? vec2f{film_, film_ / aspect}
: vec2f{film_ * aspect, film_};
auto e = zero3f;
auto q = vec3f{
auto e = zero3f;
auto q = vec3f{
film.x * (0.5f - image_uv.x), film.y * (image_uv.y - 0.5f), lens};
auto q1 = -q;
auto d = normalize(q1 - e);
Expand Down
8 changes: 7 additions & 1 deletion libs/yocto/yocto_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,12 @@ void colorgrade_image_mt(image<vec4f>& corrected, const image<vec4f>& img,
corrected[{i, j}] = colorgrade(img[{i, j}], linear, params);
});
}
void colorgrade_image_mt(image<vec4b>& corrected, const image<vec4f>& img,
bool linear, const colorgrade_params& params) {
parallel_for(img.width(), img.height(), [&](int i, int j) {
corrected[{i, j}] = float_to_byte(colorgrade(img[{i, j}], linear, params));
});
}

// compute white balance
vec3f compute_white_balance(const image<vec4f>& img) {
Expand Down Expand Up @@ -931,7 +937,7 @@ image<vec4f> make_bumps(
};
auto dist = clamp(length(uv - center), 0.0f, thick) / thick;
auto val = uv.x <= 0.5f != uv.y <= 0.5f ? (1 + sqrt(1 - dist)) / 2
: (dist * dist) / 2;
: (dist * dist) / 2;
return lerp(color0, color1, val);
});
}
Expand Down
2 changes: 2 additions & 0 deletions libs/yocto/yocto_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ image<vec4f> colorgrade_image(
// Uses multithreading for speed.
void colorgrade_image_mt(image<vec4f>& corrected, const image<vec4f>& img,
bool linear, const colorgrade_params& params);
void colorgrade_image_mt(image<vec4b>& corrected, const image<vec4f>& img,
bool linear, const colorgrade_params& params);

// determine white balance colors
vec3f compute_white_balance(const image<vec4f>& img);
Expand Down
28 changes: 12 additions & 16 deletions libs/yocto/yocto_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,19 +824,17 @@ inline json_value::operator double() const {
if (_type != json_type::nfloat && _type != json_type::ninteger &&
_type != json_type::nunsigned)
throw json_error{"number expected"};
return _type == json_type::nfloat
? (double)_real
: _type == json_type::ninteger ? (double)_integer
: (double)_unsigned;
return _type == json_type::nfloat ? (double)_real
: _type == json_type::ninteger ? (double)_integer
: (double)_unsigned;
}
inline json_value::operator float() const {
if (_type != json_type::nfloat && _type != json_type::ninteger &&
_type != json_type::nunsigned)
throw json_error{"number expected"};
return _type == json_type::nfloat
? (float)_real
: _type == json_type::ninteger ? (float)_integer
: (float)_unsigned;
return _type == json_type::nfloat ? (float)_real
: _type == json_type::ninteger ? (float)_integer
: (float)_unsigned;
}
inline json_value::operator bool() const {
if (_type != json_type::boolean) throw json_error{"boolean expected"};
Expand Down Expand Up @@ -1816,10 +1814,9 @@ inline bool get_number(json_ctview json, double& value) {
if (jst != json_type::nfloat && jst != json_type::ninteger &&
jst != json_type::nunsigned)
return set_error(json, "number expected");
value = (jst == json_type::nfloat)
? (double)jsv._real
: (jst == json_type::ninteger) ? (double)jsv._integer
: (double)jsv._unsigned;
value = (jst == json_type::nfloat) ? (double)jsv._real
: (jst == json_type::ninteger) ? (double)jsv._integer
: (double)jsv._unsigned;
return true;
}
inline bool get_integer(json_ctview json, int32_t& value) {
Expand Down Expand Up @@ -1849,10 +1846,9 @@ inline bool get_number(json_ctview json, float& value) {
if (jst != json_type::nfloat && jst != json_type::ninteger &&
jst != json_type::nunsigned)
return set_error(json, "number expected");
value = (jst == json_type::nfloat)
? (float)jsv._real
: (jst == json_type::ninteger) ? (float)jsv._integer
: (float)jsv._unsigned;
value = (jst == json_type::nfloat) ? (float)jsv._real
: (jst == json_type::ninteger) ? (float)jsv._integer
: (float)jsv._unsigned;
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions libs/yocto/yocto_matht.h
Original file line number Diff line number Diff line change
Expand Up @@ -4804,8 +4804,8 @@ inline vec<T, 3> sample_microfacet(T roughness, const vec<T, 3>& normal,
// zero)
auto lensq = Vh.x * Vh.x + Vh.y * Vh.y;
auto T1 = lensq > 0 ? vec<T, 3>{-Vh.y, Vh.x, 0} * (1 / sqrt(lensq))
: vec<T, 3>{1, 0, 0};
auto T2 = cross(Vh, T1);
: vec<T, 3>{1, 0, 0};
auto T2 = cross(Vh, T1);
// Section 4.2: parameterization of the projected area
auto r = sqrt(rn.y);
auto phi = 2 * (T)pi * rn.x;
Expand Down
15 changes: 7 additions & 8 deletions libs/yocto/yocto_modelio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1680,10 +1680,9 @@ bool load_obj(const string& filename, obj_scene* obj, string& error,
}
// grab shape and add element
auto shape = obj->shapes.back();
auto& element = (cmd == "f")
? shape->faces.emplace_back()
: (cmd == "l") ? shape->lines.emplace_back()
: shape->points.emplace_back();
auto& element = (cmd == "f") ? shape->faces.emplace_back()
: (cmd == "l") ? shape->lines.emplace_back()
: shape->points.emplace_back();
// get element material or add if needed
if (!geom_only) {
if (mname.empty() && empty_material == nullptr) {
Expand Down Expand Up @@ -2822,8 +2821,8 @@ bool save_stl(
triangle_idx++) {
auto& triangle = shape->triangles[triangle_idx];
auto fnormal = !shape->fnormals.empty()
? shape->fnormals[triangle_idx]
: triangle_normal(shape->positions[triangle.x],
? shape->fnormals[triangle_idx]
: triangle_normal(shape->positions[triangle.x],
shape->positions[triangle.y],
shape->positions[triangle.z]);
if (!write_value(fs, fnormal)) return write_error();
Expand All @@ -2844,8 +2843,8 @@ bool save_stl(
triangle_idx++) {
auto& triangle = shape->triangles[triangle_idx];
auto fnormal = !shape->fnormals.empty()
? shape->fnormals[triangle_idx]
: triangle_normal(shape->positions[triangle.x],
? shape->fnormals[triangle_idx]
: triangle_normal(shape->positions[triangle.x],
shape->positions[triangle.y],
shape->positions[triangle.z]);
if (!format_values(fs, "facet normal {}\n", fnormal))
Expand Down
4 changes: 2 additions & 2 deletions libs/yocto/yocto_sceneio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1399,8 +1399,8 @@ static bool load_json_scene(const string& filename, sceneio_scene* scene,
for (auto [name, element] : iterate_object(group)) {
auto material_it = material_map.find(string{name});
auto material = (material_it == material_map.end())
? add_material(scene, string{name})
: material_it->second.first;
? add_material(scene, string{name})
: material_it->second.first;
for (auto [key, value] : iterate_object(element)) {
if (key == "emission") {
get_value(value, material->emission);
Expand Down
4 changes: 2 additions & 2 deletions libs/yocto/yocto_shading.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ inline vec3f sample_microfacet(float roughness, const vec3f& normal,
// zero)
auto lensq = Vh.x * Vh.x + Vh.y * Vh.y;
auto T1 = lensq > 0 ? vec3f{-Vh.y, Vh.x, 0} * (1 / sqrt(lensq))
: vec3f{1, 0, 0};
auto T2 = cross(Vh, T1);
: vec3f{1, 0, 0};
auto T2 = cross(Vh, T1);
// Section 4.2: parameterization of the projected area
auto r = sqrt(rn.y);
auto phi = 2 * pif * rn.x;
Expand Down
Loading