[Bf-blender-cvs] [9177bb33f68] master: Workbench: Support node texture "closest" interpolation option

Clément Foucault noreply at git.blender.org
Fri Jan 11 16:00:45 CET 2019


Commit: 9177bb33f68f66609b29e1e53a90552cae8026b3
Author: Clément Foucault
Date:   Sun Dec 23 15:20:06 2018 +0100
Branches: master
https://developer.blender.org/rB9177bb33f68f66609b29e1e53a90552cae8026b3

Workbench: Support node texture "closest" interpolation option

This makes it possible to paint pixel art using the workbench.

Cubic interpolation is not supported but could be added if needed.

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

M	source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/engines/workbench/workbench_materials.c
M	source/blender/draw/engines/workbench/workbench_private.h

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

diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index 25942b162ee..ce8988de4a5 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -159,3 +159,13 @@ vec4 srgb_to_linearrgb(vec4 col_from)
 	col_to.a = col_from.a;
 	return col_to;
 }
+
+vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool srgb, bool nearest_sampling)
+{
+	vec2 tex_size = vec2(textureSize(image, 0).xy);
+	/* TODO(fclem) We could do the same with sampler objects.
+	 * But this is a quick workaround instead of messing with the GPUTexture itself. */
+	vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord;
+	vec4 color = texture(image, uv);
+	return (srgb) ? srgb_to_linearrgb(color) : color;
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index aed86937e0d..93da32dd765 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -2,6 +2,7 @@
 uniform float ImageTransparencyCutoff = 0.1;
 uniform sampler2D image;
 uniform bool imageSrgb;
+uniform bool imageNearest;
 
 uniform mat4 ProjectionMatrix;
 uniform mat4 ViewMatrixInverse;
@@ -35,13 +36,10 @@ void main()
 	vec4 diffuse_color;
 
 #ifdef V3D_SHADING_TEXTURE_COLOR
-	diffuse_color = texture(image, uv_interp);
+	diffuse_color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
 	if (diffuse_color.a < ImageTransparencyCutoff) {
 		discard;
 	}
-	if (imageSrgb) {
-		diffuse_color = srgb_to_linearrgb(diffuse_color);
-	}
 #else
 	diffuse_color = vec4(materialDiffuseColor, 1.0);
 #endif /* V3D_SHADING_TEXTURE_COLOR */
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
index 2ce816c6484..db51d3da15f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
@@ -7,6 +7,7 @@ uniform float materialRoughness;
 uniform sampler2D image;
 uniform float ImageTransparencyCutoff = 0.1;
 uniform bool imageSrgb;
+uniform bool imageNearest;
 
 #ifdef NORMAL_VIEWPORT_PASS_ENABLED
 in vec3 normal_viewport;
@@ -37,13 +38,10 @@ void main()
 	vec4 color;
 
 #  ifdef V3D_SHADING_TEXTURE_COLOR
-	color = texture(image, uv_interp);
+	color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
 	if (color.a < ImageTransparencyCutoff) {
 		discard;
 	}
-	if (imageSrgb) {
-		color = srgb_to_linearrgb(color);
-	}
 #  else
 	color.rgb = materialDiffuseColor;
 #  endif
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 2aa588802e7..cc8254d0f3d 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -709,7 +709,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
 }
 
 static WORKBENCH_MaterialData *get_or_create_material_data(
-        WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int color_type)
+        WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int color_type, int interp)
 {
 	WORKBENCH_StorageList *stl = vedata->stl;
 	WORKBENCH_PassList *psl = vedata->psl;
@@ -725,6 +725,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
 	material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
 	material_template.color_type = color_type;
 	material_template.ima = ima;
+	material_template.interp = interp;
 	uint hash = workbench_material_get_hash(&material_template, is_ghost);
 
 	material = BLI_ghash_lookup(wpd->material_hash, POINTER_FROM_UINT(hash));
@@ -736,7 +737,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
 		workbench_material_copy(material, &material_template);
 		DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
 		DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
-		workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true);
+		workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp);
 
 		BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
 	}
@@ -764,11 +765,12 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
 		const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
 
 		if (draw_as == PART_DRAW_PATH) {
-			Image *image = NULL;
-			Material *mat = give_current_material(ob, part->omat);
-			ED_object_get_active_image(ob, part->omat, &image, NULL, NULL, NULL);
+			Material *mat;
+			Image *image;
+			int interp;
+			workbench_material_get_image_and_mat(ob, part->omat, &image, &interp, &mat);
 			int color_type = workbench_material_determine_color_type(wpd, image, ob);
-			WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, color_type);
+			WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, color_type, interp);
 
 			struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
 			        wpd->prepass_solid_hair_sh :
@@ -779,7 +781,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
 			        shader);
 			DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
 			DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
-			workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true);
+			workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp);
 		}
 	}
 }
@@ -829,11 +831,12 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 			struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
 			for (int i = 0; i < materials_len; i++) {
 				if (geom_array != NULL && geom_array[i] != NULL) {
-					Material *mat = give_current_material(ob, i + 1);
+					Material *mat;
 					Image *image;
-					ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
+					int interp;
+					workbench_material_get_image_and_mat(ob, i + 1, &image, &interp, &mat);
 					int color_type = workbench_material_determine_color_type(wpd, image, ob);
-					material = get_or_create_material_data(vedata, ob, mat, image, color_type);
+					material = get_or_create_material_data(vedata, ob, mat, image, color_type, interp);
 					DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
 				}
 			}
@@ -842,7 +845,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 		              V3D_SHADING_SINGLE_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR))
 		{
 			/* Draw solid color */
-			material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type);
+			material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type, 0);
 			if (is_sculpt_mode) {
 				DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
 			}
@@ -858,7 +861,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 			if (is_sculpt_mode) {
 				/* Multiple materials are not supported in sculpt mode yet. */
 				Material *mat = give_current_material(ob, 1);
-				material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR);
+				material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
 				DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
 			}
 			else {
@@ -870,7 +873,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 				for (int i = 0; i < materials_len; ++i) {
 					if (geoms != NULL && geoms[i] != NULL) {
 						Material *mat = give_current_material(ob, i + 1);
-						material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR);
+						material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
 						DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
 					}
 				}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 6c955ac1fcb..d303f2ea88e 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -139,7 +139,7 @@ static void workbench_init_object_data(DrawData *dd)
 }
 
 static WORKBENCH_MaterialData *get_or_create_material_data(
-        WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int color_type)
+        WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int color_type, int interp)
 {
 	WORKBENCH_StorageList *stl = vedata->stl;
 	WORKBENCH_PassList *psl = vedata->psl;
@@ -155,6 +155,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
 	material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
 	material_template.color_type = color_type;
 	material_template.ima = ima;
+	material_template.interp = interp;
 	uint hash = workbench_material_get_hash(&material_template, false);
 
 	material = BLI_ghash_lookup(wpd->material_hash, POINTER_FROM_UINT(hash));
@@ -177,7 +178,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
 			DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
 		}
 
-		workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false);
+		workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp);
 		material->shgrp = grp;
 
 		/* Depth */
@@ -430,11 +431,12 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
 		const int draw_as = (part-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list