[Bf-blender-cvs] [bb639ccc47a] blender2.8: GPUMaterial: Geometry Node: Add support for parametric output

Clément Foucault noreply at git.blender.org
Wed Aug 22 13:51:16 CEST 2018


Commit: bb639ccc47a4d66ef451f6b590bd6fad5de2b2f2
Author: Clément Foucault
Date:   Mon Aug 20 17:59:21 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBbb639ccc47a4d66ef451f6b590bd6fad5de2b2f2

GPUMaterial: Geometry Node: Add support for parametric output

This supports meshes and hairs too. Matches cycles output.

This adds barycentric coords to the GPUBuiltin enum which will also be used
for the wireframe node.

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

M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_geometry.c

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

diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index ab55b9c61e7..c8f66e33202 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -112,7 +112,8 @@ typedef enum GPUBuiltin {
 	GPU_OBJECT_INFO =           (1 << 15),
 	GPU_VOLUME_DENSITY =        (1 << 16),
 	GPU_VOLUME_FLAME =          (1 << 17),
-	GPU_VOLUME_TEMPERATURE =    (1 << 18)
+	GPU_VOLUME_TEMPERATURE =    (1 << 18),
+	GPU_BARYCENTRIC_TEXCO =     (1 << 19),
 } GPUBuiltin;
 
 typedef enum GPUMatType {
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 98f9e22cbc1..d4bba0a39c7 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -505,6 +505,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
 		return "sampflame";
 	else if (builtin == GPU_VOLUME_TEMPERATURE)
 		return "unftemperature";
+	else if (builtin == GPU_BARYCENTRIC_TEXCO)
+		return "unfbarycentrictex";
 	else
 		return "";
 }
@@ -724,6 +726,8 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
 					BLI_dynstr_append(ds, "viewmat");
 				else if (input->builtin == GPU_CAMERA_TEXCO_FACTORS)
 					BLI_dynstr_append(ds, "camtexfac");
+				else if (input->builtin == GPU_BARYCENTRIC_TEXCO)
+					BLI_dynstr_append(ds, "barytexco");
 				else if (input->builtin == GPU_OBJECT_MATRIX)
 					BLI_dynstr_append(ds, "objmat");
 				else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX)
@@ -783,13 +787,22 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO
 	codegen_set_unique_ids(nodes);
 	builtins = codegen_process_uniforms_functions(material, ds, nodes);
 
-#if 0
-	if (G.debug & G_DEBUG)
-		BLI_dynstr_appendf(ds, "/* %s */\n", name);
-#endif
+
+	if (builtins & GPU_BARYCENTRIC_TEXCO)
+		BLI_dynstr_append(ds, "\tin vec2 barycentricTexCo;\n");
 
 	BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n");
 
+	if (builtins & GPU_BARYCENTRIC_TEXCO) {
+		BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
+		BLI_dynstr_append(ds, "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n"
+		                      "\t                      ? barycentricTexCo.x\n"
+		                      "\t                      : 1.0 - barycentricTexCo.x,\n"
+		                      "\t                      0.0);\n");
+		BLI_dynstr_append(ds, "#else\n");
+		BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n");
+		BLI_dynstr_append(ds, "#endif\n");
+	}
 	/* TODO(fclem) get rid of that. */
 	if (builtins & GPU_VIEW_MATRIX)
 		BLI_dynstr_append(ds, "\tmat4 viewmat = ViewMatrix;\n");
@@ -894,6 +907,13 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
 
 	for (node = nodes->first; node; node = node->next) {
 		for (input = node->inputs.first; input; input = input->next) {
+			if (input->source == GPU_SOURCE_BUILTIN) {
+				if (input->builtin == GPU_BARYCENTRIC_TEXCO) {
+					BLI_dynstr_appendf(
+					        ds, "out vec2 barycentricTexCo%s;\n",
+					        use_geom ? "g" : "");
+				}
+			}
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				/* XXX FIXME : see notes in mesh_render_data_create() */
 				/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
@@ -949,6 +969,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
 	        "vec3 hair_get_customdata_vec3(const samplerBuffer);\n"
 	        "vec4 hair_get_customdata_vec4(const samplerBuffer);\n"
 	        "vec3 hair_get_strand_pos(void);\n"
+	        "int hair_get_base_id(void);\n"
 	        "\n"
 	);
 
@@ -958,6 +979,21 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
 
 	for (node = nodes->first; node; node = node->next) {
 		for (input = node->inputs.first; input; input = input->next) {
+			if (input->source == GPU_SOURCE_BUILTIN) {
+				if (input->builtin == GPU_BARYCENTRIC_TEXCO) {
+					/* To match cycles without breaking into individual segment we encode if we need to invert
+					 * the first component into the second component. We invert if the barycentricTexCo.y
+					 * is NOT 0.0 or 1.0. */
+					BLI_dynstr_appendf(
+					        ds, "\tint _base_id = hair_get_base_id();\n");
+					BLI_dynstr_appendf(
+					        ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n",
+					        use_geom ? "g" : "");
+					BLI_dynstr_appendf(
+					        ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n",
+					        use_geom ? "g" : "");
+				}
+			}
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				if (input->attribtype == CD_TANGENT) {
 					/* Not supported by hairs */
@@ -983,6 +1019,16 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
 
 	for (node = nodes->first; node; node = node->next) {
 		for (input = node->inputs.first; input; input = input->next) {
+			if (input->source == GPU_SOURCE_BUILTIN) {
+				if (input->builtin == GPU_BARYCENTRIC_TEXCO) {
+					BLI_dynstr_appendf(
+					        ds, "\tbarycentricTexCo%s.x = float((gl_VertexID %% 3) == 0);\n",
+					        use_geom ? "g" : "");
+					BLI_dynstr_appendf(
+					        ds, "\tbarycentricTexCo%s.y = float((gl_VertexID %% 3) == 1);\n",
+					        use_geom ? "g" : "");
+				}
+			}
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				if (input->attribtype == CD_TANGENT) { /* silly exception */
 					BLI_dynstr_appendf(
@@ -1049,6 +1095,10 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_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_BUILTIN && input->builtin == GPU_BARYCENTRIC_TEXCO) {
+				BLI_dynstr_appendf(ds, "in vec2 barycentricTexCog[];\n");
+				BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo[];\n");
+			}
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				BLI_dynstr_appendf(
 				        ds, "in %s var%dg[];\n",
@@ -1066,6 +1116,11 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code)
 	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_BUILTIN) {
+				if (input->builtin == GPU_BARYCENTRIC_TEXCO) {
+					BLI_dynstr_appendf(ds, "\tbarycentricTexCo = barycentricTexCog;\n");
+				}
+			}
 			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];\n", input->attribid, input->attribid);
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 40aba1cc004..f3dea3afaf4 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1705,7 +1705,7 @@ void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
 }
 
 void node_geometry(
-        vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld,
+        vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, vec2 barycentric,
         out vec3 position, out vec3 normal, out vec3 tangent,
         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
         out float backfacing, out float pointiness)
@@ -1720,7 +1720,7 @@ void node_geometry(
 	vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
 	incoming = -(toworld * vec4(I_view, 0.0)).xyz;
 
-	parametric = vec3(0.0);
+	parametric = vec3(barycentric, 0.0);
 	backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
 	pointiness = 0.5;
 }
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index dfeebcea305..d004e0e80a1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -46,7 +46,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *node, bNodeExecData
 	return GPU_stack_link(mat, node, "node_geometry", in, out,
 	                      GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
 	                      GPU_attribute(CD_ORCO, ""), GPU_builtin(GPU_OBJECT_MATRIX),
-	                      GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+	                      GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_BARYCENTRIC_TEXCO));
 }
 
 /* node type definition */



More information about the Bf-blender-cvs mailing list