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 */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs