[Bf-blender-cvs] [ada6e720f94] blender2.8: GPU_codegen: Add support for passing attributes through the geometry stage.

Clément Foucault noreply at git.blender.org
Wed Jun 28 21:07:11 CEST 2017


Commit: ada6e720f941dbd50e75b04feea6dae16b8ffc55
Author: Clément Foucault
Date:   Wed Jun 28 21:05:43 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBada6e720f941dbd50e75b04feea6dae16b8ffc55

GPU_codegen: Add support for passing attributes through the geometry stage.

Should fix some issues with missing attributes in Eevee.

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

M	source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
M	source/blender/gpu/intern/gpu_codegen.c

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

diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
index e057e91eaef..222d272da72 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
@@ -23,6 +23,9 @@ void main() {
 	for (int v = 0; v < 3; ++v) {
 		gl_Position = vPos[v];
 		worldPosition = x_axis[f] * vPos[v].x + y_axis[f] * vPos[v].y + maj_axes[f];
+#ifdef ATTRIB
+		pass_attrib(v);
+#endif
 		EmitVertex();
 	}
 
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 8586ee67d5d..afdb927fbcc 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -787,7 +787,7 @@ static const char *attrib_prefix_get(CustomDataType type)
 	}
 }
 
-static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
+static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code, bool use_geom)
 {
 	DynStr *ds = BLI_dynstr_new();
 	GPUNode *node;
@@ -814,8 +814,8 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
 					BLI_dynstr_appendf(ds, "#define att%d %s%u\n",
 						input->attribid, attrib_prefix_get(input->attribtype), hash);
 				}
-				BLI_dynstr_appendf(ds, "out %s var%d;\n",
-					GPU_DATATYPE_STR[input->type], input->attribid);
+				BLI_dynstr_appendf(ds, "out %s var%d%s;\n",
+					GPU_DATATYPE_STR[input->type], input->attribid, use_geom ? "g" : "");
 			}
 		}
 	}
@@ -831,19 +831,19 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				if (input->attribtype == CD_TANGENT) { /* silly exception */
 					BLI_dynstr_appendf(
-					        ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
-					        input->attribid, input->attribid);
+					        ds, "\tvar%d%s.xyz = normalize(NormalMatrix * att%d.xyz);\n",
+					        input->attribid, use_geom ? "g" : "", input->attribid);
 					BLI_dynstr_appendf(
-					        ds, "\tvar%d.w = att%d.w;\n",
-					        input->attribid, input->attribid);
+					        ds, "\tvar%d%s.w = att%d.w;\n",
+					        input->attribid, use_geom ? "g" : "", input->attribid);
 				}
 				else if (input->attribtype == CD_ORCO) {
-					BLI_dynstr_appendf(ds, "\tvar%d = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
-					                   input->attribid);
+					BLI_dynstr_appendf(ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
+					                   input->attribid, use_geom ? "g" : "");
 				}
 				else {
-					BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n",
-					                   input->attribid, input->attribid);
+					BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n",
+					                   input->attribid, use_geom ? "g" : "", input->attribid);
 				}
 			}
 		}
@@ -972,6 +972,49 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
 	return code;
 }
 
+static char *code_generate_geometry_new(ListBase *nodes, const char *geom_code)
+{
+	DynStr *ds = BLI_dynstr_new();
+	GPUNode *node;
+	GPUInput *input;
+	char *code;
+
+	/* Generate varying declarations. */
+	for (node = nodes->first; node; node = node->next) {
+		for (input = node->inputs.first; input; input = input->next) {
+			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+				if (input->attribtype == CD_MTFACE) {
+					BLI_dynstr_appendf(ds, "in %s var%dg[];\n",
+					                   GPU_DATATYPE_STR[input->type],
+					                   input->attribid);
+					BLI_dynstr_appendf(ds, "out %s var%d;\n",
+					                   GPU_DATATYPE_STR[input->type],
+					                   input->attribid);
+				}
+			}
+		}
+	}
+	/* Generate varying assignments. */
+	BLI_dynstr_append(ds, "#define ATTRIB\n");
+	BLI_dynstr_appendf(ds, "void pass_attrib(in int vert) {\n");
+	for (node = nodes->first; node; node = node->next) {
+		for (input = node->inputs.first; input; input = input->next) {
+			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+				/* TODO let shader choose what to do depending on what the attrib is. */
+				BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];", input->attribid, input->attribid);
+			}
+		}
+	}
+	BLI_dynstr_append(ds, "}\n");
+
+	BLI_dynstr_append(ds, geom_code);
+
+	code = BLI_dynstr_get_cstring(ds);
+	BLI_dynstr_free(ds);
+
+	return code;
+}
+
 static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv)
 {
 #ifdef WITH_OPENSUBDIV
@@ -1854,7 +1897,7 @@ GPUPass *GPU_generate_pass_new(
 {
 	GPUShader *shader;
 	GPUPass *pass;
-	char *vertexgen, *geometrygen, *fragmentgen, *tmp;
+	char *vertexgen, *fragmentgen, *tmp;
 	char *vertexcode, *geometrycode, *fragmentcode;
 
 	/* prune unused nodes */
@@ -1864,14 +1907,18 @@ GPUPass *GPU_generate_pass_new(
 
 	/* generate code and compile with opengl */
 	fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true);
-	vertexgen = code_generate_vertex_new(nodes, vert_code);
-	// geometrygen = code_generate_geometry(nodes, false);
-	UNUSED_VARS(geometrygen);
+	vertexgen = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL));
 
 	tmp = BLI_strdupcat(frag_lib, glsl_material_library);
 	fragmentcode = BLI_strdupcat(tmp, fragmentgen);
 	vertexcode = BLI_strdup(vertexgen);
-	geometrycode = (geom_code) ? BLI_strdup(geom_code) : NULL;
+
+	if (geom_code) {
+		geometrycode = code_generate_geometry_new(nodes, geom_code);
+	}
+	else {
+		geometrycode = NULL;
+	}
 
 	shader = GPU_shader_create(vertexcode,
 	                           fragmentcode,




More information about the Bf-blender-cvs mailing list