[Bf-blender-cvs] [a2b05accea6] blender2.8: Eevee: Fix vertex color being in srgb space.

Clément Foucault noreply at git.blender.org
Wed May 2 16:45:15 CEST 2018


Commit: a2b05accea6e2879832ae4ac4465ca11d49622c5
Author: Clément Foucault
Date:   Wed May 2 15:36:09 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBa2b05accea6e2879832ae4ac4465ca11d49622c5

Eevee: Fix vertex color being in srgb space.

Now they are properly converted to Linear space before interpolation.

Since the only way to get vertex color in eevee and cycles is via the
attribute node with the CD_AUTO_FROM_NAME flag, we have to know at binding
time which type of buffer will be connected to this auto input.

We store this information inside the batch cache (together with the according
uniform name) and pass it as uniform to the shader which does conversion if
needed. The same shader can then be reused to draw another mesh with
different auto layers configuration.

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

M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/gpu/intern/gpu_codegen.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index de65084f553..036fd041620 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1380,7 +1380,13 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
 		bool use_volume_material = (gpumat_array[0] && GPU_material_use_domain_volume(gpumat_array[0]));
 
 		/* Get per-material split surface */
-		struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
+		char *auto_layer_names;
+		int *auto_layer_is_srgb;
+		int auto_layer_count;
+		struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len,
+		                                                                    &auto_layer_names,
+		                                                                    &auto_layer_is_srgb,
+		                                                                    &auto_layer_count);
 		if (mat_geom) {
 			for (int i = 0; i < materials_len; ++i) {
 				EEVEE_ObjectEngineData *oedata = NULL;
@@ -1412,6 +1418,23 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
 				ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
 				ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
 
+				char *name = auto_layer_names;
+				for (int j = 0; j < auto_layer_count; ++j) {
+					/* TODO don't add these uniform when not needed (default pass shaders). */
+					if (shgrp_array[i]) {
+						DRW_shgroup_uniform_bool(shgrp_array[i], name, &auto_layer_is_srgb[j], 1);
+					}
+					if (shgrp_depth_array[i]) {
+						DRW_shgroup_uniform_bool(shgrp_depth_array[i], name, &auto_layer_is_srgb[j], 1);
+					}
+					if (shgrp_depth_clip_array[i]) {
+						DRW_shgroup_uniform_bool(shgrp_depth_clip_array[i], name, &auto_layer_is_srgb[j], 1);
+					}
+					/* Go to next layer name. */
+					while (*name != '\0') { name++; }
+					name += 1;
+				}
+
 				/* Shadow Pass */
 				if (ma->use_nodes && ma->nodetree && (ma->blend_method != MA_BM_SOLID)) {
 					struct GPUMaterial *gpumat;
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index e84a2378a48..110e986f652 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -523,11 +523,19 @@ Gwn_Batch *DRW_cache_object_surface_get(Object *ob)
 }
 
 Gwn_Batch **DRW_cache_object_surface_material_get(
-        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
+        char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count)
 {
+	if (auto_layer_names != NULL) {
+		*auto_layer_names = NULL;
+		*auto_layer_is_srgb = NULL;
+		*auto_layer_count = 0;
+	}
+
 	switch (ob->type) {
 		case OB_MESH:
-			return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
+			return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len,
+			                                         auto_layer_names, auto_layer_is_srgb, auto_layer_count);
 		case OB_CURVE:
 			return DRW_cache_curve_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
 		case OB_SURF:
@@ -2298,12 +2306,14 @@ Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(Object *ob)
 
 /* Return list of batches */
 Gwn_Batch **DRW_cache_mesh_surface_shaded_get(
-        Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
+        Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
+        char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count)
 {
 	BLI_assert(ob->type == OB_MESH);
 
 	Mesh *me = ob->data;
-	return DRW_mesh_batch_cache_get_surface_shaded(me, gpumat_array, gpumat_array_len);
+	return DRW_mesh_batch_cache_get_surface_shaded(me, gpumat_array, gpumat_array_len,
+	                                               auto_layer_names, auto_layer_is_srgb, auto_layer_count);
 }
 
 /* Return list of batches */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 2ef57884a44..b56f2c0218b 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -49,7 +49,8 @@ struct Gwn_Batch *DRW_cache_screenspace_circle_get(void);
 struct Gwn_Batch *DRW_cache_object_wire_outline_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_object_surface_get(struct Object *ob);
 struct Gwn_Batch **DRW_cache_object_surface_material_get(
-        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
+        char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
 
 /* Empties */
 struct Gwn_Batch *DRW_cache_plain_axes_get(void);
@@ -127,7 +128,8 @@ struct Gwn_Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool
 struct Gwn_Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob);
 struct Gwn_Batch **DRW_cache_mesh_surface_shaded_get(
-        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
+        char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
 struct Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
 
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 83cc87307b5..cfc57dd6e40 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -91,7 +91,8 @@ struct Gwn_Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
 /* Mesh */
 
 struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded(
-        struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
+        struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
+        char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
 struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
 struct Gwn_Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
 struct Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index fb6fe306792..3c75b78976d 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1564,6 +1564,12 @@ typedef struct MeshBatchCache {
 	Gwn_Batch *overlay_weight_verts;
 	Gwn_Batch *overlay_paint_edges;
 
+	/* arrays of bool uniform names (and value) that will be use to
+	 * set srgb conversion for auto attribs.*/
+	char *auto_layer_names;
+	int *auto_layer_is_srgb;
+	int auto_layer_ct;
+
 	/* settings to determine if cache is invalid */
 	bool is_maybe_dirty;
 	bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
@@ -1806,6 +1812,9 @@ static void mesh_batch_cache_clear(Mesh *me)
 	MEM_SAFE_FREE(cache->shaded_triangles_in_order);
 	MEM_SAFE_FREE(cache->shaded_triangles);
 
+	MEM_SAFE_FREE(cache->auto_layer_names);
+	MEM_SAFE_FREE(cache->auto_layer_is_srgb);
+
 	if (cache->texpaint_triangles) {
 		for (int i = 0; i < cache->mat_len; ++i) {
 			GWN_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
@@ -1855,6 +1864,27 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata,
 		if (tangent_len == 0) { tangent_id = NULL; }
 		if (vcol_len == 0) { vcol_id = NULL; }
 
+		/* Count number of auto layer and allocate big enough name buffer. */
+		uint auto_names_len = 0;
+		uint auto_ofs = 0;
+		uint auto_id = 0;
+		cache->auto_layer_ct = 0;
+		for (uint i = 0; i < uv_len; i++) {
+			const char *attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i);
+			auto_names_len += strlen(attrib_name) + 2; /* include null terminator and b prefix. */
+			cache->auto_layer_ct++;
+		}
+		for (uint i = 0; i < vcol_len; i++) {
+			if (rdata->cd.layers.auto_vcol[i]) {
+				const char *attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i);
+				auto_names_len += strlen(attrib_name) + 2; /* include null terminator and b prefix. */
+				cache->auto_layer_ct++;
+			}
+		}
+		auto_names_len += 1; /* add an ultimate '\0' terminator */
+		cache->auto_layer_names = MEM_callocN(auto_names_len * sizeof(char), "Auto layer name buf");
+		cache->auto_layer_is_srgb = MEM_mallocN(cache->auto_layer_ct * sizeof(int), "Auto layer value buf");
+
 		for (uint i = 0; i < uv_len; i++) {
 			/* UV */
 			const char *attrib_name = mesh_render_data_uv_layer_uuid_get(rdata, i);
@@ -1868,6 +1898,10 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata,
 			attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i);
 			GWN_vertformat_alias_add(format, attrib_name);
 
+			/* +1 include null terminator. */
+			auto_ofs += 1 + BLI_snprintf_rlen(cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
+			cache->auto_layer_is_srgb[auto_id++] = 0; /* tag as not srgb */
+
 			if (i == rdata->cd.layers.uv_active) {
 				GWN_vertformat_alias_add(format, "u");
 			}
@@ -1896,7 +1930,12 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata,
 			/* Auto layer */
 			if (rdata->cd.layers.auto_vcol[i]) {
 				attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i);
+
 				GWN_vertformat_alias_add(format, attrib_name);
+
+				/* +1 include null terminator. */
+				auto_ofs += 1 + BLI_snprintf_rlen(cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
+				cache->auto_layer_is_srgb[auto_id++] = 1; /* tag as srgb */
 			}
 
 			if (i == rdata->cd.layers.vcol_active) {
@@ -3809

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list