13 : mContext(C), material(ma), effect(nullptr), key_image_map(&key_image_map)
15 bNodeTree *new_ntree = prepare_material_nodetree();
18 shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300,
"");
20 add_link(shader_node, 0, output_node, 0);
25 COLLADAFW::EffectCommon *ef,
28 : mContext(C), material(ma), effect(ef), uid_image_map(&uid_image_map)
30 prepare_material_nodetree();
33 std::map<std::string, bNode *> nmap;
35 nmap[
"main"] = add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, -300, 300);
36 nmap[
"emission"] = add_node(C, ntree, SH_NODE_EMISSION, -300, 500,
"emission");
37 nmap[
"add"] = add_node(C, ntree, SH_NODE_ADD_SHADER, 100, 400);
38 nmap[
"transparent"] = add_node(C, ntree, SH_NODE_BSDF_TRANSPARENT, 100, 200);
39 nmap[
"mix"] = add_node(C, ntree, SH_NODE_MIX_SHADER, 400, 300,
"transparency");
41 nmap[
"out"]->flag &= ~NODE_SELECT;
43 add_link(ntree, nmap[
"emission"], 0, nmap[
"add"], 0);
44 add_link(ntree, nmap[
"main"], 0, nmap[
"add"], 1);
45 add_link(ntree, nmap[
"add"], 0, nmap[
"mix"], 1);
46 add_link(ntree, nmap[
"transparent"], 0, nmap[
"mix"], 2);
48 add_link(ntree, nmap[
"mix"], 0, nmap[
"out"], 0);
50 make_group(C, ntree, nmap);
52 shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300,
"");
54 add_link(shader_node, 0, output_node, 0);
58void MaterialNode::setShaderType()
61 COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
66 if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
67 ma->spec_shader = MA_SPEC_BLINN;
68 ma->spec = ef->getShininess().getFloatValue();
71 else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
72 ma->spec_shader = MA_SPEC_PHONG;
73 ma->har = ef->getShininess().getFloatValue();
76 else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
77 ma->diff_shader = MA_DIFF_LAMBERT;
81 ma->diff_shader = MA_DIFF_LAMBERT;
82 fprintf(stderr,
"Current shader type is not supported, default to lambert.\n");
87bNodeTree *MaterialNode::prepare_material_nodetree()
89 if (material->nodetree) {
90 ntree = material->nodetree;
95 nullptr, &material->id,
"Shader Nodetree",
"ShaderNodeTree");
96 material->use_nodes =
true;
97 ntree = material->nodetree;
106bNode *MaterialNode::add_node(
int node_type,
int locx,
int locy, std::string
label)
110 if (
label.length() > 0) {
121void MaterialNode::add_link(
bNode *from_node,
int from_index,
bNode *to_node,
int to_index)
129void MaterialNode::add_link(
bNode *from_node,
130 const char *from_label,
132 const char *to_label)
137 if (from_socket && to_socket) {
144 float reflectivity = val.getFloatValue();
145 if (reflectivity >= 0) {
148 material->metallic = reflectivity;
156 float roughness = val.getFloatValue();
157 if (roughness >= 0) {
166 float ior = val.getFloatValue();
169 "IOR of negative value is not allowed for materials (using Blender default value "
179 COLLADAFW::ColorOrTexture &cot,
180 COLLADAFW::FloatOrParam &val)
185 if (effect ==
nullptr) {
189 if (cot.isColor() || !cot.isValid()) {
192 float transparent_alpha;
194 COLLADAFW::Color
col = cot.getColor();
195 transparent_alpha =
col.getAlpha();
199 transparent_alpha = 1;
202 float transparency_alpha = val.getFloatValue();
203 if (transparency_alpha < 0) {
205 transparency_alpha = 1;
208 float alpha = transparent_alpha * transparency_alpha;
209 if (mode == COLLADAFW::EffectCommon::RGB_ZERO) {
217 else if (cot.isTexture()) {
218 int locy = -300 * (node_map.size() - 2);
219 add_texture_node(cot, -300, locy,
"Alpha");
225 int locy = -300 * (node_map.size() - 2);
227 if (cot.isTexture()) {
228 bNode *texture_node = add_texture_node(cot, -300, locy,
"Base Color");
229 if (texture_node !=
nullptr) {
230 add_link(texture_node, 0, shader_node, 0);
238 COLLADAFW::Color
col = cot.getColor();
239 fcol[0] = material->r =
col.getRed();
240 fcol[1] = material->g =
col.getGreen();
241 fcol[2] = material->b =
col.getBlue();
242 fcol[3] = material->a =
col.getAlpha();
246 fcol[0] = material->r = 0.0f;
247 fcol[1] = material->g = 0.0f;
248 fcol[2] = material->b = 0.0f;
249 fcol[3] = material->a = 1.0f;
256 ntree->ensure_topology_cache();
258 if (nodes.is_empty()) {
261 const bNode *shader = nodes.first();
264 if (in_socket ==
nullptr) {
269 if (link ==
nullptr) {
274 if (texture ==
nullptr) {
290 fcol[0] =
col.getRed();
291 fcol[1] =
col.getGreen();
292 fcol[2] =
col.getBlue();
299 int locy = -300 * (node_map.size() - 2);
301 COLLADAFW::Color
col = cot.getColor();
307 else if (cot.isTexture()) {
308 add_texture_node(cot, -300, locy,
"Ambient");
315 int locy = -300 * (node_map.size() - 2);
317 COLLADAFW::Color
col = cot.getColor();
323 else if (cot.isTexture()) {
324 add_texture_node(cot, -300, locy,
"Reflective");
331 int locy = -300 * (node_map.size() - 2);
333 COLLADAFW::Color
col = cot.getColor();
337 fcol[0] =
col.getRed();
338 fcol[1] =
col.getGreen();
339 fcol[2] =
col.getBlue();
340 fcol[3] =
col.getAlpha();
343 else if (cot.isTexture()) {
344 bNode *texture_node = add_texture_node(cot, -300, locy,
"Emission Color");
345 if (texture_node !=
nullptr) {
346 add_link(texture_node,
"Color", shader_node,
"Emission Color");
358 if (effect ==
nullptr) {
362 int locy = -300 * (node_map.size() - 2);
364 COLLADAFW::Color
col = effect->getTransparent().getColor();
365 float alpha = effect->getTransparency().getFloatValue();
368 alpha *=
col.getAlpha();
375 else if (cot.isTexture()) {
376 add_texture_node(cot, -300, locy,
"Alpha");
383 bool has_specularity =
true;
384 int locy = -300 * (node_map.size() - 2);
386 COLLADAFW::Color
col = cot.getColor();
388 if (
col.getRed() == 0 &&
col.getGreen() == 0 &&
col.getBlue() == 0) {
389 has_specularity =
false;
397 else if (cot.isTexture()) {
398 add_texture_node(cot, -300, locy,
"Specular IOR Level");
403 has_specularity =
false;
406 if (!has_specularity) {
412 shader_node,
SOCK_IN,
"Specular IOR Level");
417bNode *MaterialNode::add_texture_node(COLLADAFW::ColorOrTexture &cot,
422 if (effect ==
nullptr) {
428 COLLADAFW::Texture ctex = cot.getTexture();
430 COLLADAFW::SamplerPointerArray &samp_array = effect->getSamplerPointerArray();
431 COLLADAFW::Sampler *
sampler = samp_array[ctex.getSamplerId()];
433 const COLLADAFW::UniqueId &ima_uid =
sampler->getSourceImage();
435 if (image_map.find(ima_uid) == image_map.end()) {
436 fprintf(stderr,
"Couldn't find an image by UID.\n");
440 Image *ima = image_map[ima_uid];
442 texture_node->
id = &ima->
id;
Main * CTX_data_main(const bContext *C)
#define SH_NODE_TEX_IMAGE
#define SH_NODE_OUTPUT_MATERIAL
void BKE_ntree_update_main_tree(Main *bmain, bNodeTree *ntree, NodeTreeUpdateExtraParams *params)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STRNCPY(dst, src)
static bNodeSocket * set_color(bNode *node, COLLADAFW::Color col)
void set_reflectivity(COLLADAFW::FloatOrParam &val)
void set_shininess(COLLADAFW::FloatOrParam &val)
void set_specular(COLLADAFW::ColorOrTexture &cot)
void update_material_nodetree()
void set_ior(COLLADAFW::FloatOrParam &val)
void set_reflective(COLLADAFW::ColorOrTexture &cot)
void set_emission(COLLADAFW::ColorOrTexture &cot)
Image * get_diffuse_image()
MaterialNode(bContext *C, COLLADAFW::EffectCommon *ef, Material *ma, UidImageMap &uid_image_map)
void set_opacity(COLLADAFW::ColorOrTexture &cot)
void set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode, COLLADAFW::ColorOrTexture &cot, COLLADAFW::FloatOrParam &val)
void set_diffuse(COLLADAFW::ColorOrTexture &cot)
void set_ambient(COLLADAFW::ColorOrTexture &cot)
std::map< std::string, Image * > KeyImageMap
std::map< COLLADAFW::UniqueId, Image * > UidImageMap
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
local_group_size(16, 16) .push_constant(Type local_group_size(16, 16) .push_constant(Type input_tx sampler(1, ImageType::FLOAT_2D, "matte_tx") .image(0
bNode * node_add_static_node(const bContext *C, bNodeTree *ntree, int type)
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, const char *name, const char *idname)
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)