Forum

Inherit from Node-Material

24 August 2015 19:11
Hi,
I am trying to bring a material from one object in scene on to another object in scene, using the m_mat.inherit_material(..) function, following the material_api code_snippet example ( https://www.blend4web.com/apps/code_snippets/code_snippets.html?scene=material_api ).

The material I want to copy or reuse has a node-tree. The target object has a simple/other material as default. I observed that the inherit_material() function only copies the standard material params to the new object. The 'node_tree' property (I can see in the javascript-console ~: sourceObject.data.materials[0].node_tree) does not get copied/assigned and remains null on the target object (as well as the 'use_nodes' property stays false).

How do I get the node-tree-material properly copied or reused/applied, via an API call, on another object that has not that material/node-tree in first place?
Thanks for your help!

Daniel
@ Emotional3D
25 August 2015 13:34
.
15 September 2015 10:57
Thank you, Roman.

It seems that Blend4Web can only inherit stack-materials, is that right?

In the following example I tried in the second row to inherit a material from a stack-material (working), and in the last row, to inherit from a node-material (not working).



All objects are marked as dynamic (via 'Force Dynamic Object' option).

The console is however logging: 'B4W ERROR: Wrong objects for inheriting material!' (for the third row)

Is there any way to transfer/copy/inherit a node-material to another object in runtime via JavaScript?

material_api_texture_test.zip
@ Emotional3D
15 September 2015 14:13
Hi!

It seems that Blend4Web can only inherit stack-materials, is that right?
You're close to the truth. Material inheritance is partially supported at the moment because it's a rather complicated thing to do. You can inherit some simple material properties, for example, diffuse intensity or specular color. Generally, they are those properties that you can change through the API of the material.js module. So, a node material that takes into account some of them will be affected too but not so much.

Also some of the material textures (colormap, normalmap, …) can be inherited but only for a stack material.

The console is however logging: 'B4W ERROR: Wrong objects for inheriting material!' (for the third row)
This error means that the inheritance wasn't being done.

Apparently, you are passing wrong object in your script:
m_mat.inherit_material(sphere_1, "NodeMaterialA", sphere_2, "NodeMaterialB");

It should be:
m_mat.inherit_material(objectA, "NodeMaterialA", objectB, "NodeMaterialB");
.

Is there any way to transfer/copy/inherit a node-material to another object in runtime via JavaScript?
It's impossible to do it directly by now. However you can use set_nodemat_value and set_nodemat_rgb API methods for a node material. It was discussed here:
link

Also you can try roundabout ways such as instancing, shape keys or overriding geometry if it's suitable in your case.
26 November 2015 11:35
I'm creating a node material and with set_nodemat_value and set_nodemat_rgb we have almost the 80 % of the runtime material creation but the main issue on this task is if I can change the texture of the material dinamically.

Is there any way to change the texture / normalmap or the path to another .png/.jpg in runtime?

Thanks!
26 November 2015 12:07

I'm creating a node material and with set_nodemat_value and set_nodemat_rgb we have almost the 80 % of the runtime material creation but the main issue on this task is if I can change the texture of the material dinamically.

Is there any way to change the texture / normalmap or the path to another .png/.jpg in runtime?

Thanks!
You can load all you textures into one material, then using node Color Mix and Value switch between them like in this example. I used animation to switch betwen two textures, but you also can use API to change value of the Value node.
texture_switch.blend
Blend4web and that kind of thing.
26 November 2015 13:20
Thanks for your reply, The example works perfectly but we need to set the texture in runtime because we don't know how many texture may will have.

For example, we have a sofa and we want to change the fabric with a 3d configurator and we have 3 kind of leathers and we want to add a textil texture, with your example we need to open this material and we need to add in the node the new texture.

For us the best solution could be to set the values of the node material (rgb, tile, etc..) and the name of the textures in runtime through the api and with one material node we will have all the fabrics of our database.

Kind regards,
26 November 2015 13:53
Also you can use a canvas texture. Take a look at this.
07 November 2016 14:08
You can load all you textures into one material, then using node Color Mix and Value switch between them like in this example. I used animation to switch betwen two textures, but you also can use API to change value of the Value node.
texture_switch.blend

Can you describe how the color mix is set with API? That would make my live a lot easier..
08 November 2016 11:48
Can you describe how the color mix is set with API? That would make my live a lot easier..
The set_nodemat_value method is what you need.
In regard to Mikhail's blend-file you should use it like this:
var m_mat = require("material");
var m_scenes = require("scenes");
...

var cube = m_scenes.get_object_by_name("Cube");
var your_value = 0.5;
m_mat.set_nodemat_value(cube, ["Material", "Value"], your_value);

To make it work you should also disable the "Apply Default Animation" option at the Object tab under the Animation section for the Cube object - otherwise the animation for this node will override all attempts to change the value.
 
Please register or log in to leave a reply.