add abr color dynamics

This commit is contained in:
2019-03-07 00:53:45 +01:00
parent 3296de98cc
commit 5329147d58
14 changed files with 78 additions and 31 deletions

View File

@@ -583,6 +583,9 @@
<node height="20" justify="center">
<text text="Val"/>
</node>
<node height="20" justify="center">
<text text="HSV Jitter"/>
</node>
</node>
<node dir="col" grow="1" width="1">
<node align="center" dir="row">
@@ -626,6 +629,10 @@
<node height="20" pad="1" width="100%">
<slider-h id="jitter-val"/>
</node>
<node height="20" pad="1" width="100%" dir="row" align="center">
<checkbox width="20" height="19" id="jitter-hsv-eachsample"/>
<text text="each sample"/>
</node>
</node>
</node>

View File

@@ -225,6 +225,15 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
}
// Color Dynamics
if (p->value<Boolean>("useColorDynamics"))
{
b->m_jitter_sat = p->value<UnitFloat>("Strt") * 0.01f;
b->m_jitter_hue = p->value<UnitFloat>("H ") * 0.01f;
b->m_jitter_val = p->value<UnitFloat>("Brgh") * 0.01f;
b->m_jitter_hsv_eachsample = p->value<Boolean>("colorDynamicsPerTip");
}
std::vector<std::string> modes = {
"normal", // normal (not in Photoshop)
"Mltp", // multiply

View File

@@ -150,7 +150,9 @@ void App::init_sidebar()
stroke->set_size(value, true, true);
};
quick->on_brush_change = [this](Node*, std::shared_ptr<Brush> b) {
auto c = Canvas::I->m_current_brush->m_tip_color;
*Canvas::I->m_current_brush = *b;
Canvas::I->m_current_brush->m_tip_color = c;
brush_update();
};

View File

@@ -129,12 +129,6 @@ bool BrushMesh::create()
}
StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float dir_angle)
{
auto rnd_nor = [&] { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1]
auto rnd_neg = [&] { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1]
auto rnd_rad = [&] { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi]
auto rnd_vec = [&] { float rad = rnd_rad(); return glm::vec3(cosf(rad), sinf(rad), 0); }; // normalized direction vector
auto rnd_bneg = [&] { return prng() % 2 == 0 ? -1.f : 1.f; }; // -1 or 1
float size_dyn = m_brush->m_tip_size_pressure ? pressure : 1.f;
float flow_dyn = m_brush->m_tip_flow_pressure ? pressure : 1.f;
float opacity_dyn = m_brush->m_tip_opacity_pressure ? pressure : 1.f;
@@ -162,14 +156,24 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa
s.pos = pos + (scatter_scale * rnd_vec() * m_brush->m_jitter_scatter * s.size * 0.5f); // 0.5 because PS scatters by half size
s.flow = m_brush->m_tip_flow * (1.f - rnd_nor() * m_brush->m_jitter_flow) * flow_dyn;
s.opacity = m_brush->m_tip_opacity * (1.f - rnd_nor() * m_brush->m_jitter_opacity) * opacity_dyn;
auto hsv = convert_rgb2hsv(m_brush->m_tip_color);
hsv.x = glm::clamp(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush->m_tip_hue) + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue, 0.f, 1.f);
hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush->m_tip_sat) + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat, 0.f, 1.f);
hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush->m_tip_val) + (rnd_nor() - 0.5f) * m_brush->m_jitter_val, 0.f, 1.f);
auto hsv = m_tip_color;
float eachtip = m_brush->m_jitter_hsv_eachsample ? 1.f : 0.f;
hsv.x = glm::fract(glm::mix(hsv.x, (pressure - 0.5f) * 2.0f, m_brush->m_tip_hue) + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue * eachtip);
hsv.y = glm::clamp(glm::mix(hsv.y, (1.f - pressure - 0.5f) * 2.0f, m_brush->m_tip_sat) + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat * eachtip, 0.f, 1.f);
hsv.z = glm::clamp(glm::mix(hsv.z, (pressure - 0.5f) * 2.0f, m_brush->m_tip_val) + (rnd_nor() - 0.5f) * m_brush->m_jitter_val * eachtip, 0.f, 1.f);
m_hsv_jitter.add(hsv);
s.col = convert_hsv2rgb(m_hsv_jitter.average());
return s;
}
void Stroke::randomize_prng()
{
std::random_device rd;
prng.seed(rd());
}
std::vector<StrokeSample> Stroke::compute_samples()
{
if (m_keypoints.empty()) return {};
@@ -321,6 +325,12 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
float size = aspect_width * glm::min(m_brush->m_tip_scale.x, m_brush->m_tip_scale.y) * raw_size;
m_step = glm::max(0.5f, m_brush->m_tip_spacing * size);
auto hsv = convert_rgb2hsv(m_brush->m_tip_color);
hsv.x = glm::fract(hsv.x + (rnd_nor() - 0.5f) * m_brush->m_jitter_hue);
hsv.y = glm::clamp(hsv.y + (rnd_nor() - 0.5f) * m_brush->m_jitter_sat, 0.f, 1.f);
hsv.z = glm::clamp(hsv.z + (rnd_nor() - 0.5f) * m_brush->m_jitter_val, 0.f, 1.f);
m_tip_color = hsv;
m_direction.resize(std::max<int>(1, m_brush->m_tip_angle_smooth * 200.f / m_step));
prng.seed(0);
}

View File

@@ -54,6 +54,7 @@ public:
float m_jitter_hue = 0;
float m_jitter_sat = 0;
float m_jitter_val = 0;
bool m_jitter_hsv_eachsample = false;
float m_jitter_aspect = 0;
bool m_jitter_aspect_bothaxis = false;
int m_blend_mode = 0;
@@ -172,6 +173,7 @@ public:
float m_step = 0;
float m_max_size = FLT_MAX;
bool m_filter_points = true;
glm::vec3 m_tip_color;
Camera m_camera;
std::shared_ptr<Brush> m_brush;
cbuffer<float> m_direction{ 1 };
@@ -182,11 +184,18 @@ public:
std::vector<std::pair<glm::vec3, float>> m_hold_points;
std::vector<StrokeSample> m_samples;
int m_last_kp;
std::minstd_rand prng;
std::mt19937 prng;
void start(const std::shared_ptr<Brush>& brush);
void add_point(glm::vec3 pos, float pressure);
void reset(bool clear_keypoints = false);
bool has_sample();
std::vector<StrokeSample> compute_samples();
StrokeSample randomize_sample(const glm::vec3& pos, float pressure, float curve_angle);
void randomize_prng();
float rnd_nor() { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1]
float rnd_neg() { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1]
float rnd_rad() { return float((double)prng() / (double)prng.max() * M_PI * 2.0); }; // normalized [0, 2pi]
glm::vec3 rnd_vec() { float rad = rnd_rad(); return glm::vec3(cosf(rad), sinf(rad), 0); }; // normalized direction vector
float rnd_bneg() { return prng() % 2 == 0 ? -1.f : 1.f; }; // -1 or 1
};

View File

@@ -900,6 +900,7 @@ void Canvas::stroke_start(glm::vec3 point, float pressure)
m_current_stroke = std::make_unique<Stroke>();
m_current_stroke->m_camera.rot = m_cam_rot;
m_current_stroke->m_camera.fov = m_cam_fov;
m_current_stroke->randomize_prng();
m_current_stroke->start(m_current_brush);
m_current_stroke->add_point(point, pressure);

View File

@@ -239,7 +239,7 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const
tip_color = glm::vec4(s.col, s.flow);
}
}
ShaderManager::u_int(kShaderUniform::DrawOutline, glm::min(tip_scale.x, tip_scale.y) < 20 ? false : m_draw_outline);
ShaderManager::u_int(kShaderUniform::DrawOutline, glm::min(tip_scale.x, tip_scale.y) < 20 || m_resizing ? false : m_draw_outline);
ShaderManager::u_vec4(kShaderUniform::Col, tip_color);
ShaderManager::u_mat4(kShaderUniform::MVP,
glm::scale(glm::vec3(1, -1, 1)) *

View File

@@ -34,7 +34,6 @@ std::thread hmd_renderer;
std::thread renderer;
int running = -1;
std::mutex render_mutex;
std::mutex wnd_mutex;
std::condition_variable render_cv;
int gl_count = 0;
@@ -687,12 +686,11 @@ int main(int argc, char** argv)
static wchar_t title_fps[512];
swprintf_s(title_fps, L"%s - %d fps", window_title, frames);
// lock if
if (wnd_mutex.try_lock())
{
std::lock_guard<std::mutex> lock(main_task_mutex);
main_tasklist.emplace_back([=] {
SetWindowText(hWnd, title_fps);
wnd_mutex.unlock();
}
});
one_sec = 0;
frames = 0;
}
@@ -869,18 +867,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
running = 0;
render_cv.notify_all();
{
// avoid deadlock
// nobody should call windows API on this window at this time
std::lock_guard<std::mutex> lock(wnd_mutex);
if (renderer.joinable())
renderer.join();
if (hmd_renderer.joinable())
hmd_renderer.join();
}
if (renderer.joinable())
renderer.join();
if (hmd_renderer.joinable())
hmd_renderer.join();
App::I.terminate();
}
break;

View File

@@ -94,7 +94,9 @@ kEventResult Node::on_event(Event* e)
if (current_mouse_capture)
{
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus != current_mouse_capture)
if (e->m_cat == kEventCategory::MouseEvent &&
child_mouse_focus != current_mouse_capture &&
is_child(current_mouse_capture))
{
MouseEvent* me = static_cast<MouseEvent*>(e);
if (child_mouse_focus)
@@ -432,6 +434,16 @@ bool Node::is_child_recursive(Node* o) const
return false;
}
bool Node::is_child(Node* o) const
{
for (const auto& c : m_children)
{
if (c.get() == o)
return true;
}
return false;
}
void Node::mouse_capture()
{
auto& c = root()->current_mouse_capture;

View File

@@ -259,6 +259,7 @@ public:
// returns {origin, size} form
glm::vec4 get_children_rect() const;
bool is_child_recursive(Node* o) const;
bool is_child(Node* o) const;
void mouse_capture();
void mouse_release();
void key_capture();

View File

@@ -517,6 +517,7 @@ bool NodePanelBrushPreset::save()
i.m_jitter_hue = b->m_jitter_hue;
i.m_jitter_sat = b->m_jitter_sat;
i.m_jitter_val = b->m_jitter_val;
i.m_jitter_hsv_eachsample = b->m_jitter_hsv_eachsample;
i.m_jitter_aspect = b->m_jitter_aspect;
i.m_jitter_aspect_bothaxis = b->m_jitter_aspect_bothaxis;
i.m_blend_mode = b->m_blend_mode;
@@ -624,6 +625,7 @@ bool NodePanelBrushPreset::restore()
b->m_jitter_hue = i.m_jitter_hue;
b->m_jitter_sat = i.m_jitter_sat;
b->m_jitter_val = i.m_jitter_val;
b->m_jitter_hsv_eachsample = i.m_jitter_hsv_eachsample;
b->m_jitter_aspect = i.m_jitter_aspect;
b->m_jitter_aspect_bothaxis = i.m_jitter_aspect_bothaxis;
b->m_blend_mode = i.m_blend_mode;

View File

@@ -137,6 +137,7 @@ class NodePanelBrushPreset : public Node
float m_jitter_hue = 0;
float m_jitter_sat = 0;
float m_jitter_val = 0;
bool m_jitter_hsv_eachsample = false;
float m_jitter_aspect = 0;
bool m_jitter_aspect_bothaxis = false;
int m_blend_mode = 0;

View File

@@ -163,6 +163,7 @@ void NodePanelStroke::update_controls()
m_jitter_hue->m_value = b->m_jitter_hue;
m_jitter_sat->m_value = b->m_jitter_sat;
m_jitter_val->m_value = b->m_jitter_val;
m_jitter_hsv_eachsample->checked = b->m_jitter_hsv_eachsample;
m_jitter_aspect->m_value = b->m_jitter_aspect;
m_tip_angle_follow->checked = b->m_tip_angle_follow;
m_tip_angle_init->checked = b->m_tip_angle_init;
@@ -484,6 +485,7 @@ void NodePanelStroke::init_controls()
init_checkbox(m_tip_size_pressure, "tip-size-pressure", &Brush::m_tip_size_pressure);
init_checkbox(m_jitter_scatter_bothaxis, "jitter-scatter-bothaxis", &Brush::m_jitter_scatter_bothaxis);
init_checkbox(m_jitter_aspect_bothaxis, "jitter-aspect-bothaxis", &Brush::m_jitter_aspect_bothaxis);
init_checkbox(m_jitter_hsv_eachsample, "jitter-hsv-eachsample", &Brush::m_jitter_hsv_eachsample);
init_checkbox(m_tip_invert, "tip-invert", &Brush::m_tip_invert);
init_checkbox(m_tip_flipx, "tip-flipx", &Brush::m_tip_flipx);

View File

@@ -34,6 +34,7 @@ public:
NodeSliderH* m_jitter_hue;
NodeSliderH* m_jitter_sat;
NodeSliderH* m_jitter_val;
NodeCheckBox* m_jitter_hsv_eachsample;
NodeSliderH* m_jitter_aspect;
NodeCheckBox* m_tip_angle_init;
NodeCheckBox* m_tip_angle_follow;