diff options
Diffstat (limited to 'source/blender/nodes/shader/nodes')
18 files changed, 291 insertions, 47 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c index 76291df41bc..e57f5e0d6cf 100644 --- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c +++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c @@ -40,12 +40,15 @@ static bNodeSocketTemplate sh_node_blackbody_out[] = { static int node_shader_gpu_blackbody(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - const int size = 256; + const int size = CM_TABLE + 1; float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"); blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f); - return GPU_stack_link(mat, node, "node_blackbody", in, out, GPU_texture(size, data)); + float layer; + GPUNodeLink *ramp_texture = GPU_texture_ramp(mat, size, data, &layer); + + return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_uniform(&layer)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index c1423867d96..6551b20a375 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -54,6 +54,8 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *node, bNode if (!in[4].link) GPU_link(mat, "world_normals_get", &in[4].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index 58a37b0e81d..c1b8c748657 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *node, bNodeExec if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 7b060bc68aa..ada6e21356f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index c3fb43c0ce8..f56837de261 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -51,6 +51,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c new file mode 100644 index 00000000000..83e4bf1731b --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c @@ -0,0 +1,132 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Stockner, L. E. Segovia + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +/* Color, melanin and absorption coefficient default to approximately same brownish hair. */ +static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = { + { SOCK_RGBA, 1, N_("Color"), 0.017513f, 0.005763f, 0.002059f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Melanin"), 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Melanin Redness"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, N_("Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Absorption Coefficient"), 0.245531f, 0.52f, 1.365f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 1, N_("Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 1, N_("Offset"), 2.0f * ((float)M_PI) / 180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, + { SOCK_FLOAT, 1, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" }, +}; + +static bNodeSocketTemplate sh_node_bsdf_hair_principled_out[] = { + { SOCK_SHADER, 0, N_("BSDF")}, + { -1, 0, "" } +}; + +/* Initialize the custom Parametrization property to Color. */ +static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE; +} + +/* Triggers (in)visibility of some sockets when changing Parametrization. */ +static void node_shader_update_hair_principled(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sock; + int parametrization = node->custom1; + + for (sock = node->inputs.first; sock; sock = sock->next) { + if (STREQ(sock->name, "Color")) { + if (parametrization == SHD_PRINCIPLED_HAIR_REFLECTANCE) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Melanin")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Melanin Redness")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Tint")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Absorption Coefficient")) { + if (parametrization == SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Random Color")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + } +} + +/* node type definition */ +void register_node_type_sh_bsdf_hair_principled(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER, 0); + node_type_socket_templates(&ntype, sh_node_bsdf_hair_principled_in, sh_node_bsdf_hair_principled_out); + node_type_size_preset(&ntype, NODE_SIZE_LARGE); + node_type_init(&ntype, node_shader_init_hair_principled); + node_type_storage(&ntype, "", NULL, NULL); + node_type_update(&ntype, node_shader_update_hair_principled, NULL); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 7f02295d45f..370dcdcc2ea 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -64,22 +64,12 @@ static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node) node->custom2 = SHD_SUBSURFACE_BURLEY; } +#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f)) +#define socket_not_one(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f)) + static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { GPUNodeLink *sss_scale; -#if 0 /* Old 2.7 glsl viewport */ - // normal - if (!in[17].link) - in[17].link = GPU_builtin(GPU_VIEW_NORMAL); - else - GPU_link(mat, "direction_transform_m4v3", in[17].link, GPU_builtin(GPU_VIEW_MATRIX), &in[17].link); - - // clearcoat normal - if (!in[18].link) - in[18].link = GPU_builtin(GPU_VIEW_NORMAL); - else - GPU_link(mat, "direction_transform_m4v3", in[18].link, GPU_builtin(GPU_VIEW_MATRIX), &in[18].link); -#endif /* Normals */ if (!in[17].link) { @@ -117,7 +107,48 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE GPU_link(mat, "set_rgb", GPU_uniform((float *)one), &sss_scale); } - return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION), + bool use_diffuse = socket_not_one(4) && socket_not_one(15); + bool use_subsurf = socket_not_zero(1) && use_diffuse; + bool use_refract = socket_not_one(4) && socket_not_zero(15); + bool use_clear = socket_not_zero(12); + + /* Due to the manual effort done per config, we only optimize the most common permutations. */ + char *node_name; + uint flag = 0; + if (!use_subsurf && use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_dielectric"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_metallic"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && !use_refract && use_clear) { + static char name[] = "node_bsdf_principled_clearcoat"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY; + } + else if (use_subsurf && use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_subsurface"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS | GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && use_refract && !use_clear && !socket_not_zero(4)) { + static char name[] = "node_bsdf_principled_glass"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT; + } + else { + static char name[] = "node_bsdf_principled"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_SSS | GPU_MATFLAG_REFRACT; + } + + GPU_material_flag_set(mat, flag); + + return GPU_stack_link(mat, node, node_name, in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id), GPU_uniform(&node->sss_id), sss_scale); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c index 41dd3f8af3c..b59f1c80342 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *node, bNodeE if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index 2c0949f275c..349db30af14 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -45,6 +45,8 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *node, bNode if (!in[1].link) GPU_link(mat, "world_normals_get", &in[1].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index ce331f03d4e..59b831c0dab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index d5932ff233a..21bdc3cd0d8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -62,11 +62,13 @@ static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + float *array, layer; int size; curvemapping_table_RGBA(node->storage, &array, &size); - return GPU_stack_link(mat, node, "curves_vec", in, out, GPU_texture(size, array)); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + + return GPU_stack_link(mat, node, "curves_vec", in, out, tex, GPU_uniform(&layer)); } void register_node_type_sh_curve_vec(void) @@ -119,12 +121,14 @@ static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + float *array, layer; int size; curvemapping_initialize(node->storage); curvemapping_table_RGBA(node->storage, &array, &size); - return GPU_stack_link(mat, node, "curves_rgb", in, out, GPU_texture(size, array)); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + + return GPU_stack_link(mat, node, "curves_rgb", in, out, tex, GPU_uniform(&layer)); } void register_node_type_sh_curve_rgb(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c index e05b0be1e62..6583dd0cec3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c +++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c @@ -67,6 +67,8 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat, bNode *node, bNodeEx GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link); } + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index a84e88e9551..98dcd58b983 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -88,13 +88,18 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS TexMapping *texmap = node->storage; float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0; float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0; - GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat); - GPUNodeLink *tmin = GPU_uniform(texmap->min); - GPUNodeLink *tmax = GPU_uniform(texmap->max); - GPUNodeLink *tdomin = GPU_uniform(&domin); - GPUNodeLink *tdomax = GPU_uniform(&domax); - - GPU_stack_link(mat, node, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax); + static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; + static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3; + + tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3); + tmax = GPU_uniform_buffer((domax) ? texmap->max : max, GPU_VEC3); + tmat0 = GPU_uniform_buffer((float *)texmap->mat[0], GPU_VEC4); + tmat1 = GPU_uniform_buffer((float *)texmap->mat[1], GPU_VEC4); + tmat2 = GPU_uniform_buffer((float *)texmap->mat[2], GPU_VEC4); + tmat3 = GPU_uniform_buffer((float *)texmap->mat[3], GPU_VEC4); + + GPU_stack_link(mat, node, "mapping", in, out, tmat0, tmat1, tmat2, tmat3, tmin, tmax); if (texmap->type == TEXMAP_TYPE_NORMAL) GPU_link(mat, "texco_norm", out[0].link, &out[0].link); diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 3c0fb145987..e4b5aaef72d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -63,11 +63,21 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U if (in[0].link) strength = in[0].link; + else if (node->original) { + bNodeSocket *socket = BLI_findlink(&node->original->inputs, 0); + bNodeSocketValueFloat *socket_data = socket->default_value; + strength = GPU_uniform_buffer(&socket_data->value, GPU_FLOAT); + } else strength = GPU_uniform(in[0].vec); if (in[1].link) realnorm = in[1].link; + else if (node->original) { + bNodeSocket *socket = BLI_findlink(&node->original->inputs, 1); + bNodeSocketValueRGBA *socket_data = socket->default_value; + realnorm = GPU_uniform_buffer(socket_data->value, GPU_VEC3); + } else realnorm = GPU_uniform(in[1].vec); diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c index 57fb9026595..f8af125eb9e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c +++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c @@ -54,6 +54,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node, if (!in[5].link) GPU_link(mat, "world_normals_get", &in[5].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS); + if (node->sss_id == 1) { bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2); bNodeSocketValueRGBA *socket_data = socket->default_value; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 2bbe3617bee..9782df2638f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -55,11 +55,28 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node) static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { + static const char *names[] = { + "node_tex_image_linear", + "node_tex_image_nearest", + "node_tex_image_cubic", + "node_tex_image_smart" + }; + static const char *names_box[] = { + "tex_box_sample_linear", + "tex_box_sample_nearest", + "tex_box_sample_cubic", + "tex_box_sample_smart" + }; + Image *ima = (Image *)node->id; ImageUser *iuser = NULL; NodeTexImage *tex = node->storage; + const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) + ? names_box[tex->interpolation] + : names[tex->interpolation]; + bool do_color_correction = false; - GPUNodeLink *norm; + GPUNodeLink *norm, *col1, *col2, *col3; int isdata = tex->color_space == SHD_COLORSPACE_NONE; float blend = tex->projection_blend; @@ -67,6 +84,15 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat if (!ima) return GPU_stack_link(mat, node, "node_tex_image_empty", in, out); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); + if ((tex->color_space == SHD_COLORSPACE_COLOR) && + ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && + GPU_material_do_color_management(mat)) + { + do_color_correction = true; + } + BKE_image_release_ibuf(ima, ibuf, NULL); + if (!in[0].link) in[0].link = GPU_attribute(CD_MTFACE, ""); @@ -74,7 +100,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat switch (tex->projection) { case SHD_PROJ_FLAT: - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_BOX: GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), @@ -83,8 +109,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat GPU_link(mat, "direction_transform_m4v3", norm, GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), &norm); + GPU_link(mat, gpu_node_name, in[0].link, + norm, + GPU_image(ima, iuser, isdata), + &col1, + &col2, + &col3); + if (do_color_correction) { + GPU_link(mat, "srgb_to_linearrgb", col1, &col1); + GPU_link(mat, "srgb_to_linearrgb", col2, &col2); + GPU_link(mat, "srgb_to_linearrgb", col3, &col3); + } GPU_link(mat, "node_tex_image_box", in[0].link, norm, + col1, col2, col3, GPU_image(ima, iuser, isdata), GPU_uniform(&blend), &out[0].link, @@ -93,23 +131,18 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat case SHD_PROJ_SPHERE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_sphere", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_TUBE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_tube", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; } - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); - if ((tex->color_space == SHD_COLORSPACE_COLOR) && - ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && - GPU_material_do_color_management(mat)) - { + if (do_color_correction && (tex->projection != SHD_PROJ_BOX)) { GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link); } - BKE_image_release_ibuf(ima, ibuf, NULL); return true; } diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c index b6581cb18cb..5f583e1e29b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c @@ -65,11 +65,19 @@ static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + struct ColorBand *coba = node->storage; + float *array, layer; int size; - BKE_colorband_evaluate_table_rgba(node->storage, &array, &size); - return GPU_stack_link(mat, node, "valtorgb", in, out, GPU_texture(size, array)); + BKE_colorband_evaluate_table_rgba(coba, &array, &size); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + + if (coba->ipotype == COLBAND_INTERP_CONSTANT) { + return GPU_stack_link(mat, node, "valtorgb_nearest", in, out, tex, GPU_uniform(&layer)); + } + else { + return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer)); + } } void register_node_type_sh_valtorgb(void) 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 a88a7ebb21a..c946c42f9af 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c @@ -132,19 +132,19 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNod } /* Create blackbody spectrum. */ - GPUNodeLink *spectrummap; + const int size = CM_TABLE + 1; + float *data, layer; if (use_blackbody) { - const int size = 256; - float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"); + 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); + data = MEM_callocN(sizeof(float) * size * 4, "blackbody black"); } + GPUNodeLink *spectrummap = GPU_texture_ramp(mat, size, data, &layer); - return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap); + return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap, + GPU_uniform(&layer)); } /* node type definition */ |