Page MenuHome

Vertex color painting. Syringe is screen-color dependent.
Open, Confirmed, LowPublic

Description

System Information
Operating system: Windows-7-6.1.7601-SP1 64 Bits
Graphics card: GeForce GTX 660 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 430.86

Blender Version
Broken: version: 2.80 (sub 74), branch: sculpt-mode-features, commit date: 2019-07-08 14:21, hash: rB3539cd38a454

Short description of error
As I am picking color from viewport pixels, not from VCOL data, it is almost impossible to match color (even with flat shading) and syringe become useless.

Exact steps for others to reproduce the error
Toggle vertex color mode, try to paint any color, then pick it with S and paint again

Details

Type
Bug

Event Timeline

texture painting checked, all is okay, it takes color right from bitmap.

Philipp Oeser (lichtwerk) triaged this task as Confirmed, Medium priority.

Even though this is not my area, I'm enrapt to confirm this.

@Jeroen Bakker (jbakker), @Clément Foucault (fclem): mind sharing your wisdom how we are displaying VCOLs?
Solid, Flat, Color set to Vertex doesnt end up displaying the same values we painted it seems? (at least glReadPixels in paint_sample_color doesnt read the same back)
Colormanagement should not take affect here, right?

The color is differnet. For example the overlay is multiplied on top of the shaded model. In the example file the transparency is set to 0.8 what will do the next mix

linear_to_srgb(0.8 * srgb_to_linear(color) + 0.2 * white) * shaded color from render engine.

When setting setting the opacity of the vertex paint overlay to 0.0 it should give the right colors. We know that this part is still lacking some final tweaks.

OK, get it, thx for clarifying, it is a bit confusing though.

Would it be good to force

  • Viewport Shading Color to Vertex + Viewport Overlay Vertex Paint Opacity = 0.0 or
  • Viewport Shading Color to Single white + Viewport Overlay Vertex Paint Opacity = 1.0 then?

Sorry if this has been discussed before, is there a task for it? (this somehow slipped under my radar...)

In any case, I think this report can be closed then? (would still be good to know the "other task" where above mentioned final tweaks are discussed...)

Germano Cavalcante (mano-wii) lowered the priority of this task from Confirmed, Medium to Confirmed, Low.

I made an experimental code that proposes to fix this.
It still needs to be optimized and deduplicated:

1diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
2index c8ad1b5781d..16b36b934ab 100644
3--- a/source/blender/editors/sculpt_paint/paint_utils.c
4+++ b/source/blender/editors/sculpt_paint/paint_utils.c
5@@ -484,7 +484,7 @@ void paint_sample_color(
6 palette->active_color = BLI_listbase_count(&palette->colors) - 1;
7 }
8
9- if (CTX_wm_view3d(C) && texpaint_proj) {
10+ if (CTX_wm_view3d(C)) {
11 /* first try getting a color directly from the mesh faces if possible */
12 ViewLayer *view_layer = CTX_data_view_layer(C);
13 Object *ob = OBACT(view_layer);
14@@ -504,12 +504,68 @@ void paint_sample_color(
15 unsigned int faceindex;
16 unsigned int totpoly = me->totpoly;
17
18- if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) {
19- ED_view3d_viewcontext_init(C, &vc);
20-
21- view3d_operator_needs_opengl(C);
22-
23- if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) {
24+ ED_view3d_viewcontext_init(C, &vc);
25+ view3d_operator_needs_opengl(C);
26+
27+ if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) {
28+ if (!texpaint_proj && CustomData_has_layer(&me_eval->ldata, CD_MLOOPCOL)) {
29+ float matrix[4][4], proj[4][4];
30+ GLint view[4];
31+
32+ const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(me_eval);
33+ const int tottri = me_eval->runtime.looptris.len;
34+
35+ const MVert *mvert = me_eval->mvert;
36+ const MPoly *mpoly = me_eval->mpoly;
37+ const MLoop *mloop = me_eval->mloop;
38+ struct MLoopCol *mloopcol = me_eval->mloopcol;
39+
40+ /* get the needed opengl matrices */
41+ GPU_viewport_size_get_i(view);
42+ GPU_matrix_model_view_get(matrix);
43+ GPU_matrix_projection_get(proj);
44+ view[0] = view[1] = 0;
45+ mul_m4_m4m4(matrix, matrix, ob_eval->obmat);
46+ mul_m4_m4m4(matrix, proj, matrix);
47+
48+ /* loop over all looptri's for a given polygon: i */
49+ MPoly *mp = &mpoly[faceindex];
50+ MLoopTri *lt = &looptri[poly_to_tri_count(faceindex, mp->loopstart)];
51+ int j, lt_tot = ME_POLY_TRI_TOT(mp);
52+
53+ float p[2], w[3], absw, minabsw = 1e10;
54+ for (j = 0; j < lt_tot; j++, lt++) {
55+ unsigned int vtri[3] = {
56+ mloop[lt->tri[0]].v,
57+ mloop[lt->tri[1]].v,
58+ mloop[lt->tri[2]].v,
59+ };
60+ float tri_co[3][3];
61+ copy_v3_v3(tri_co[0], mvert[vtri[0]].co);
62+ copy_v3_v3(tri_co[1], mvert[vtri[1]].co);
63+ copy_v3_v3(tri_co[2], mvert[vtri[2]].co);
64+
65+ p[0] = mval[0];
66+ p[1] = mval[1];
67+ imapaint_tri_weights(matrix, view, UNPACK3(tri_co), p, w);
68+ absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
69+ if (absw < minabsw) {
70+ float col1[4], col2[4], col3[4];
71+ rgba_uchar_to_float(col1, (char *)&mloopcol[lt->tri[0]]);
72+ rgba_uchar_to_float(col2, (char *)&mloopcol[lt->tri[1]]);
73+ rgba_uchar_to_float(col3, (char *)&mloopcol[lt->tri[2]]);
74+ mul_v4_fl(col1, w[0]);
75+ mul_v4_fl(col2, w[1]);
76+ mul_v4_fl(col3, w[2]);
77+ add_v4_v4(col1, col2);
78+ add_v4_v4(col1, col3);
79+ rgba_float_to_uchar((char *)&col, col1);
80+
81+ minabsw = absw;
82+ }
83+ };
84+ }
85+ else if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) {
86 Image *image;
87
88 if (use_material) {

@Germano Cavalcante (mano-wii): that's pretty cool and nice code to have, however I am unsure if there are situations where you actually want to sample not just the raw VCOLs (but actually want to sample whatever is drawn on the screen? -- same is true for texpaint as well imho)
Maybe we could trigger sampling in two modes: one for "screen truth" and one for "data truth" (defaulting to "data truth" -- as it is for texpaint atm....)?

@Philipp Oeser (lichtwerk)
Data-true will give you the same predictable result on the screen.
Screen-true will give you (right after drawing) unpredictable result.

I see the only one way to use screen color: adding it to 2d pallete, when I want exactly this one color, that I suddenly got on the screen, not for now but just as good sample (from matcaps or procedure mixes i.e.) So the default should be data-true, as for texture painting.