[Bf-blender-cvs] [38ccd1fe33e] blender2.8: Eevee: add Principled Volume shader.

Brecht Van Lommel noreply at git.blender.org
Fri Feb 23 19:12:21 CET 2018


Commit: 38ccd1fe33e61a6d609273dd87d3a4c69d62f368
Author: Brecht Van Lommel
Date:   Thu Feb 22 20:04:20 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB38ccd1fe33e61a6d609273dd87d3a4c69d62f368

Eevee: add Principled Volume shader.

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

M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_volume_principled.c

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

diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 8d120ae8984..1269f81180c 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -3089,6 +3089,71 @@ void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color)
 	}
 }
 
+void node_volume_principled(
+	vec4 color,
+	float density,
+	float anisotropy,
+	vec4 absorption_color,
+	float emission_strength,
+	vec4 emission_color,
+	float blackbody_intensity,
+	vec4 blackbody_tint,
+	float temperature,
+	float density_attribute,
+	vec4 color_attribute,
+	float temperature_attribute,
+	sampler2D spectrummap,
+	out Closure result)
+{
+#ifdef VOLUMETRICS
+	vec3 absorption_coeff = vec3(0.0);
+	vec3 scatter_coeff = vec3(0.0);
+	vec3 emission_coeff = vec3(0.0);
+
+	/* Compute density. */
+	density = max(density, 0.0);
+
+	if(density > 1e-5) {
+		density = max(density * density_attribute, 0.0);
+	}
+
+	if(density > 1e-5) {
+		/* Compute scattering and absorption coefficients. */
+		vec3 scatter_color = color.rgb * color_attribute.rgb;
+
+		scatter_coeff = scatter_color * density;
+		absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color.rgb, 0.0) * density;
+	}
+
+	/* Compute emission. */
+	emission_strength = max(emission_strength, 0.0);
+
+	if(emission_strength > 1e-5) {
+		emission_coeff += emission_strength * emission_color.rgb;
+	}
+
+	if(blackbody_intensity > 1e-3) {
+		/* Add temperature from attribute. */
+		float T = max(temperature * max(temperature_attribute, 0.0), 0.0);
+
+		/* Stefan-Boltzman law. */
+		float T4 = (T * T) * (T * T);
+		float sigma = 5.670373e-8 * 1e-6 / M_PI;
+		float intensity = sigma * mix(1.0, T4, blackbody_intensity);
+
+		if(intensity > 1e-5) {
+			vec4 bb;
+			node_blackbody(T, spectrummap, bb);
+			emission_coeff += bb.rgb * blackbody_tint.rgb * intensity;
+		}
+	}
+
+	result = Closure(absorption_coeff, scatter_coeff, emission_coeff, anisotropy);
+#else
+	result = CLOSURE_DEFAULT;
+#endif
+}
+
 /* closures */
 
 void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
index f9a481e6c7e..e51833e4474 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
@@ -62,9 +62,89 @@ static void node_shader_init_volume_principled(bNodeTree *UNUSED(ntree), bNode *
 	}
 }
 
-static int node_shader_gpu_volume_principled(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out))
+static void node_shader_gpu_volume_attribute(GPUMaterial *mat, const char *name, GPUNodeLink **outcol, GPUNodeLink **outvec, GPUNodeLink **outf)
 {
-	return false;
+	if (strcmp(name, "density") == 0) {
+		GPU_link(mat, "node_attribute_volume_density",
+		         GPU_builtin(GPU_VOLUME_DENSITY),
+		         outcol, outvec, outf);
+	}
+	else if (strcmp(name, "color") == 0) {
+		GPU_link(mat, "node_attribute_volume_color",
+		         GPU_builtin(GPU_VOLUME_DENSITY),
+		         outcol, outvec, outf);
+	}
+	else if (strcmp(name, "flame") == 0) {
+		GPU_link(mat, "node_attribute_volume_flame",
+		         GPU_builtin(GPU_VOLUME_FLAME),
+		         outcol, outvec, outf);
+	}
+	else if (strcmp(name, "temperature") == 0) {
+		GPU_link(mat, "node_attribute_volume_temperature",
+		         GPU_builtin(GPU_VOLUME_FLAME),
+		         GPU_builtin(GPU_VOLUME_TEMPERATURE),
+		         outcol, outvec, outf);
+	}
+	else {
+		*outcol = *outvec = *outf = NULL;
+	}
+}
+
+static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+	/* Test if blackbody intensity is enabled. */
+	bool use_blackbody = (in[8].link || in[8].vec[0] != 0.0f);
+
+	/* Get volume attributes. */
+	GPUNodeLink *density = NULL, *color = NULL, *temperature = NULL;
+
+	for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
+		if (sock->typeinfo->type != SOCK_STRING) {
+			continue;
+		}
+
+		bNodeSocketValueString *value = sock->default_value;
+		GPUNodeLink *outcol, *outvec, *outf;
+
+		if (STREQ(sock->name, "Density Attribute")) {
+			node_shader_gpu_volume_attribute(mat, value->value, &outcol, &outvec, &density);
+		}
+		else if (STREQ(sock->name, "Color Attribute")) {
+			node_shader_gpu_volume_attribute(mat, value->value, &color, &outvec, &outf);
+		}
+		else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) {
+			node_shader_gpu_volume_attribute(mat, value->value, &outcol, &outvec, &temperature);
+		}
+	}
+
+	/* Default values if attributes not found. */
+	if (!density) {
+		static float one = 1.0f;
+		density = GPU_uniform(&one);
+	}
+	if (!color) {
+		static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+		color = GPU_uniform(white);
+	}
+	if (!temperature) {
+		static float one = 1.0f;
+		temperature = GPU_uniform(&one);
+	}
+
+	/* Create blackbody spectrum. */
+	GPUNodeLink *spectrummap;
+	if (use_blackbody) {
+		const int size = 256;
+		float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
+		blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
+		spectrummap = GPU_texture(size, data);
+	}
+	else {
+		float *data = MEM_callocN(sizeof(float) * 4, "blackbody black");
+		spectrummap = GPU_texture(1, data);
+	}
+
+	return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap);
 }
 
 /* node type definition */



More information about the Bf-blender-cvs mailing list