[Bf-blender-cvs] [2eef097831c] blender2.8: GPU Codegen: Add new closure socket type.

Clément Foucault noreply at git.blender.org
Mon Jul 3 22:10:27 CEST 2017


Commit: 2eef097831caf14634cc0fc6749b857096baf3da
Author: Clément Foucault
Date:   Mon Jul 3 21:39:52 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB2eef097831caf14634cc0fc6749b857096baf3da

GPU Codegen: Add new closure socket type.

This allow specialized shaders to redefine the closure interface to fit their needs.

For instance, Volumetric closure needs to pass more than one vec4 (absorption vec3, scattering vec3, anisotropy float).

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

M	source/blender/gpu/GPU_material.h
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
M	source/blender/nodes/shader/node_shader_util.c

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

diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index b12a59f607d..ec50bd9d9f5 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -76,6 +76,8 @@ typedef enum GPUType {
 	GPU_MAT3 = 9,
 	GPU_MAT4 = 16,
 
+	GPU_CLOSURE = 17,
+
 	GPU_TEX2D = 1002,
 	GPU_SHADOW2D = 1003,
 	GPU_TEXCUBE = 1004,
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 87fbccc0c87..cd367c821ba 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -86,9 +86,10 @@ typedef struct GPUFunction {
 } GPUFunction;
 
 /* Indices match the GPUType enum */
-static const char *GPU_DATATYPE_STR[17] = {
+static const char *GPU_DATATYPE_STR[18] = {
 	"", "float", "vec2", "vec3", "vec4",
 	NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4",
+	"Closure"
 };
 
 /* GLSL code parsing for finding function definitions.
@@ -172,7 +173,7 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
 
 			/* test for type */
 			type = GPU_NONE;
-			for (i = 1; i <= 16; i++) {
+			for (i = 1; i <= 17; i++) {
 				if (GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
 					type = i;
 					break;
@@ -350,6 +351,8 @@ static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *t
 			BLI_dynstr_appendf(ds, "vec4(%s.r, %s.r, %s.r, %s.g)", name, name, name, name);
 		else if (from == GPU_FLOAT)
 			BLI_dynstr_appendf(ds, "vec4(%s, %s, %s, 1.0)", name, name, name);
+		else /* can happen with closure */
+			BLI_dynstr_append(ds, name);
 	}
 }
 
@@ -357,6 +360,11 @@ static void codegen_print_datatype(DynStr *ds, const GPUType type, float *data)
 {
 	int i;
 
+	if (type == GPU_CLOSURE) {
+		BLI_dynstr_append(ds, "CLOSURE_DEFAULT");
+		return;
+	}
+
 	BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]);
 
 	for (i = 0; i < type; i++) {
@@ -543,9 +551,16 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
 						GPU_DATATYPE_STR[input->type], input->id);
 				}
 				else {
-					/* for others use const so the compiler can do folding */
-					BLI_dynstr_appendf(ds, "const %s cons%d = ",
-						GPU_DATATYPE_STR[input->type], input->id);
+					if (input->type != GPU_CLOSURE) {
+						/* for others use const so the compiler can do folding */
+						BLI_dynstr_appendf(ds, "const %s cons%d = ",
+							GPU_DATATYPE_STR[input->type], input->id);
+					}
+					else {
+						/* const keyword does not work with struct */
+						BLI_dynstr_appendf(ds, "%s cons%d = ",
+							GPU_DATATYPE_STR[input->type], input->id);
+					}
 					codegen_print_datatype(ds, input->type, input->vec);
 					BLI_dynstr_append(ds, ";\n");
 				}
@@ -667,8 +682,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
 		BLI_dynstr_append(ds, ");\n");
 	}
 
-	BLI_dynstr_append(ds, "\n\tfragColor = ");
-	codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
+	BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id);
 	BLI_dynstr_append(ds, ";\n");
 }
 
@@ -696,7 +710,7 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use
 		BLI_dynstr_appendf(ds, "/* %s */\n", name);
 #endif
 
-	BLI_dynstr_append(ds, "void main()\n{\n");
+	BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n");
 
 	if (use_new_shading) {
 		if (builtins & GPU_VIEW_MATRIX)
@@ -764,6 +778,17 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use
 
 	BLI_dynstr_append(ds, "}\n");
 
+	/* XXX This cannot go into gpu_shader_material.glsl because main() would be parsed and generate error */
+	/* Old glsl mode compat. */
+	BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n");
+	BLI_dynstr_append(ds, "out vec4 fragColor;\n");
+	BLI_dynstr_append(ds, "void main()\n");
+	BLI_dynstr_append(ds, "{\n");
+	BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n");
+	BLI_dynstr_append(ds, "\tfragColor = vec4(cl.radiance, cl.opacity);\n");
+	BLI_dynstr_append(ds, "}\n");
+	BLI_dynstr_append(ds, "#endif\n\n");
+
 	/* create shader */
 	code = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index dafd305e8ba..40d1acfabd1 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -2366,6 +2366,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
 					case GPU_VEC4:
 					case GPU_MAT3:
 					case GPU_MAT4:
+					case GPU_CLOSURE:
 					case GPU_ATTRIB:
 						break;
 				}
@@ -2394,6 +2395,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
 						break;
 
 					case GPU_NONE:
+					case GPU_CLOSURE:
 					case GPU_TEX2D:
 					case GPU_TEXCUBE:
 					case GPU_SHADOW2D:
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 1f9ab45e556..afe862bb70f 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -12,7 +12,37 @@ uniform mat4 ProjectionMatrixInverse;
 uniform mat3 NormalMatrix;
 uniform vec4 CameraTexCoFactors;
 
-out vec4 fragColor;
+/* Old glsl mode compat. */
+
+#ifndef NODETREE_EXEC
+
+struct Closure {
+	vec3 radiance;
+	float opacity;
+};
+
+#define CLOSURE_DEFAULT Closure(vec3(0.0), 0.0);
+
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+	Closure cl;
+	cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
+	cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
+	return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+	Closure cl;
+	cl.radiance = cl1.radiance + cl2.radiance;
+	cl.opacity = cl1.opacity + cl2.opacity;
+	return cl;
+}
+
+Closure nodetree_exec(void); /* Prototype */
+
+#endif /* NODETREE_EXEC */
+
 
 /* Converters */
 
@@ -2625,7 +2655,7 @@ layout(std140) uniform lightSource {
 
 /* bsdfs */
 
-void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
 {
 	/* ambient light */
 	vec3 L = vec3(0.2);
@@ -2639,10 +2669,10 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
 		L += light_diffuse * bsdf;
 	}
 
-	result = vec4(L * color.rgb, 1.0);
+	result = Closure(L * color.rgb, 1.0);
 }
 
-void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out Closure result)
 {
 	/* ambient light */
 	vec3 L = vec3(0.2);
@@ -2660,29 +2690,29 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
 		L += light_specular * bsdf;
 	}
 
-	result = vec4(L * color.rgb, 1.0);
+	result = Closure(L * color.rgb, 1.0);
 }
 
 void node_bsdf_anisotropic(
         vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
-        out vec4 result)
+        out Closure result)
 {
 	node_bsdf_diffuse(color, 0.0, N, result);
 }
 
-void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
+void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out Closure result)
 {
 	node_bsdf_diffuse(color, 0.0, N, result);
 }
 
-void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result)
+void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
 {
 	node_bsdf_diffuse(color, 0.0, N, result);
 }
 
 void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
 	float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
-	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
 {
 	vec3 X, Y;
 	float ax, ay;
@@ -2775,18 +2805,18 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
 		L += diffuse_and_specular_bsdf + clearcoat_bsdf;
 	}
 
-	result = vec4(L, 1.0);
+	result = Closure(L, 1.0);
 }
 
 void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
 	float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
-	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
 {
 #ifdef EEVEE_ENGINE
 	vec3 diffuse, f0;
 	convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
 
-	result = vec4(eevee_surface_lit(N, diffuse, f0, roughness, 1.0), 1.0);
+	result = Closure(eevee_surface_lit(N, diffuse, f0, roughness, 1.0), 1.0);
 #else
 	node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
 		specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
@@ -2796,7 +2826,7 @@ void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurf
 
 void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
 	float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
-	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+	float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
 {
 #ifdef EEVEE_ENGINE
 	vec3 diffuse, f0;
@@ -2825,9 +2855,9 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
 		

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list