[Bf-blender-cvs] [3ed49a8] master: Make matcaps suck less

Antony Riakiotakis noreply at git.blender.org
Tue Apr 1 19:14:27 CEST 2014


Commit: 3ed49a810d469174d2c0233dcb03d249adc60056
Author: Antony Riakiotakis
Date:   Sat Mar 29 11:40:26 2014 +0200
https://developer.blender.org/rB3ed49a810d469174d2c0233dcb03d249adc60056

Make matcaps suck less

This commit does various changes for matcaps:

One is taking advantage of drawing with pbvh (which would only happen
with dyntopo previously) and drawing with partial redraw during
sculpting.

The second one is support for masks. To make this work in the special
case of multires, which uses flat shading, I use the only available flat
shaded builtins in OpenGL 2.0 which are color and secondary color.

Abusing colors in that way is also essential for flat shading to work if
we are to use pbvh draw in multires, since it is the color that is being
interpolated flatly, not the normal (which can only interpolated
smoothly). The pbvh drawing code for multires used last triangle
element's normal to compute the shading which would only produce smooth
results. This could change if we did the shading in the vertex shader
for flat shaded primitives, but this is more complex and makes it harder
to have one shader to rule the mole.

Also increased the brightness of the default diffuse color for
sculpting. This should be useful since artists like to tweak the
lighting settings and it will give them the full dynamic range of the
lights, but also it helps with correct brightness of sculpted matcaps.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D435

===================================================================

M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_material.c
M	source/blender/gpu/shaders/gpu_shader_material.glsl

===================================================================

diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 64b3cf5..cd624cf 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -612,7 +612,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
 		if (!GPU_buffer_legacy(dm)) {
 			glShadeModel(GL_SMOOTH);
 			for (a = 0; a < dm->drawObject->totmaterial; a++) {
-				if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
+				if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
 					glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
 					             dm->drawObject->materials[a].totpoint);
 				}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 946f92f..87de748 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1763,12 +1763,15 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 			new_shademodel = GL_SMOOTH;
 			new_matnr = 0;
 		}
-		
+
 		if (shademodel != new_shademodel || matnr != new_matnr) {
 			matnr = new_matnr;
 			shademodel = new_shademodel;
 
-			drawcurrent = setMaterial(matnr + 1, NULL);
+			if (setMaterial)
+				drawcurrent = setMaterial(matnr + 1, NULL);
+			else
+				drawcurrent = 1;
 
 			glShadeModel(shademodel);
 		}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index a8abd08..84b3935 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -3454,6 +3454,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 	else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
 	         check_object_draw_texture(scene, v3d, dt))
 	{
+		bool draw_loose = true;
+
 		if ((v3d->flag & V3D_SELECT_OUTLINE) &&
 		    ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
 		    (base->flag & SELECT) &&
@@ -3464,9 +3466,33 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 		}
 
 		if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+			Paint *p;
+
 			glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+			/* this will get ignored mostly, will only be relevant for matcaps */
+			glColor3f(1.0, 1.0, 1.0);
+
+			if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
+				GPUVertexAttribs gattribs;
+				float planes[4][4];
+				float (*fpl)[4] = NULL;
+				int fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+				if (ob->sculpt->partial_redraw) {
+					if (ar->do_draw & RGN_DRAW_PARTIAL) {
+						sculpt_get_redraw_planes(planes, ar, rv3d, ob);
+						fpl = planes;
+						ob->sculpt->partial_redraw = 0;
+					}
+				}
+
+				GPU_enable_material(1, &gattribs);
+				dm->drawFacesSolid(dm, fpl, fast, NULL);
+				draw_loose = false;
+			}
+			else
+				dm->drawFacesGLSL(dm, GPU_enable_material);
 
-			dm->drawFacesGLSL(dm, GPU_enable_material);
 //			if (BKE_bproperty_object_get(ob, "Text"))
 // XXX				draw_mesh_text(ob, 1);
 			GPU_disable_material();
@@ -3480,7 +3506,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 			draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
 		}
 
-		if (!(draw_flags & DRAW_FACE_SELECT)) {
+		if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
 			if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
 				if ((dflag & DRAW_CONSTCOLOR) == 0) {
 					glColor3ubv(ob_wire_col);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index ce974e1..3571b3e 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -84,7 +84,9 @@ typedef enum GPUBuiltin {
 	GPU_VIEW_POSITION = 16,
 	GPU_VIEW_NORMAL = 32,
 	GPU_OBCOLOR = 64,
-	GPU_AUTO_BUMPSCALE = 128
+	GPU_AUTO_BUMPSCALE = 128,
+	GPU_MATCAP_NORMAL = 256,
+	GPU_COLOR = 512,
 } GPUBuiltin;
 
 typedef enum GPUBlendMode {
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 0518d25..3b4f08c 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1446,7 +1446,7 @@ void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
 
 	if (buffers->vert_buf) {
 		int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
-		float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+		float diffuse_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
 
 		if (buffers->show_diffuse_color) {
 			MFace *f = buffers->mface + buffers->face_indices[0];
@@ -1664,7 +1664,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
 		int totvert = key->grid_area * totgrid;
 		int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
 		const int has_mask = key->has_mask;
-		float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+		float diffuse_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
 
 		if (buffers->show_diffuse_color) {
 			const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
@@ -1960,7 +1960,7 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
 		VertexBufferFormat *vd = &vert_data[*v_index];
 
 		/* TODO: should use material color */
-		float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+		float diffuse_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
 
 		/* Set coord, normal, and mask */
 		copy_v3_v3(vd->co, v->co);
@@ -2200,7 +2200,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_PBVH_Buffers *buffers)
 	int i, j;
 	const int has_mask = (buffers->vmask != NULL);
 	const MFace *face = &buffers->mface[buffers->face_indices[0]];
-	float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+	float diffuse_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
 
 	if (buffers->show_diffuse_color)
 		GPU_material_diffuse_get(face->mat_nr + 1, diffuse_color);
@@ -2272,7 +2272,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_PBVH_Buffers *buffers)
 	int i, j, x, y, gridsize = buffers->gridkey.grid_size;
 	const int has_mask = key->has_mask;
 	const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
-	float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+	float diffuse_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
 
 	if (buffers->show_diffuse_color)
 		GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 20e6502..18b5123 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -365,6 +365,10 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
 		return "unfobcolor";
 	else if (builtin == GPU_AUTO_BUMPSCALE)
 		return "unfobautobumpscale";
+	else if (builtin == GPU_MATCAP_NORMAL)
+		return "gl_SecondaryColor";
+	else if (builtin == GPU_COLOR)
+		return "gl_Color";
 	else
 		return "";
 }
@@ -665,6 +669,18 @@ static char *code_generate_vertex(ListBase *nodes)
 				else
 					BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid);
 			}
+			/* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */
+			else if (input->source == GPU_SOURCE_BUILTIN) {
+				if (input->builtin == GPU_MATCAP_NORMAL) {
+					/* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
+					 * between shader stages and we want the full range of the normal */
+					BLI_dynstr_appendf(ds, "\tvec3 matcapcol = vec3(0.5, 0.5, 0.5) * varnormal + vec3(0.5, 0.5, 0.5);\n");
+					BLI_dynstr_appendf(ds, "\tgl_FrontSecondaryColor = vec4(matcapcol, 1.0);\n");
+				}
+				else if (input->builtin == GPU_COLOR) {
+					BLI_dynstr_appendf(ds, "\tgl_FrontColor = gl_Color;\n");
+				}
+			}
 
 	BLI_dynstr_append(ds, "}\n\n");
 
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index f73c98f..f512212 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1531,7 +1531,11 @@ static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
 {
 	GPUNodeLink *outlink;
 	
-	GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
+	/* some explanations here:
+	 * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse
+	 * the built in secondary color of opengl. Color is just the regular color, which should include mask value too.
+	 * This also needs flat shading so we use the primary opengl color built-in */
+	GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_builtin(GPU_MATCAP_NORMAL), GPU_builtin(GPU_COLOR), &outlink);
 	
 	return outlink;
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 19ef6d0..cfe9962 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2409,16 +2409,20 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
 
 /* ********************** matcap style render ******************** */
 
-void material_preview_matcap(vec4 color, sampler2D ima, vec3 N, out vec4 result)
+void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
 {
+	vec3 normal;
 	vec2 tex;
-
-	if (N.z < 0.0) {
-		N.z = 0.0;
-		N = normalize(N);
+	
+	/* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors 
+	 * between shader stages and we want the full range of the normal */
+	normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0);
+	if (normal.z < 0.0) {
+		normal.z = 0.0;
 	}
+	normal = normalize(normal);
 
-	tex.x = 0.5 + 0.49 * N.x;
-	tex.y = 0.5 + 0.49 * N.y;
-	result = texture2D(ima, tex);
+	tex.x = 0.5 + 0.49 * normal.x;
+	tex.y = 0.5 + 0.49 * normal.y;
+	result = texture2D(ima, tex) * mask;
 }




More information about the Bf-blender-cvs mailing list