Jump to content

VRAYProcedural and material


Recommended Posts

Hello

I try to add material (.ifd file) to VRAYProcedural like in Mantra: Delayed Load and I don't know how to do this.

I openGeometryObject(), addGeometry() and how to add material?

Sorry, I thing this is easy but I can't find this in HDK documentation.

Link to comment
Share on other sites

  • 2 weeks later...

Probably using changeSetting()

I've been trying to get this thing working as well, something like this:

UT_String full_material_path = "/obj/shopnet1/basic_surface_01";
openGeometryObject();
    addGeometry(gdp_0, 0);
    changeSetting("shop_materialpath",full_material_path,"object");
closeObject();

But that does not work.

In the VRAY_DemoBox.C example there is a short example of changing the shader:

    // Create a geometry object in mantra
    openGeometryObject();
	// Add the geometry
	addGeometry(gdp, 0);
	// Change the surface shader setting
	changeSetting("surface", "constant Cd ( 1 0 0 )", "object");
    closeObject();

But that is like hardcoding your shader in there and I've got a string that contains the path to the shader I want to assign.

If I try to use:

setSurface(full_material_path);

I get the following error:

mantra: VEX error: Unable to open /obj/shopnet1/basic_surface_01.vex	Path not found
mantra: VEX error: Unable to load /obj/shopnet1/basic_surface_01	Path not found

From the ClusterThis procedural (in the VRAY_ClusterThisRender.C) I found out that:

    void *handle = queryObject ( 0 );
    UT_String myMaterial;
    querySurfaceShader ( handle, myMaterial );
    myMaterial.harden();
    std::cout<<"myMaterial: "<<myMaterial<<endl;

returns something like:

myMaterial: "op:/obj/shopnet1/basic_surface_01/basic baseColor 0.899999976158 0 0 baseColorMap default.pic colorMapWrap repeat colorMapfilter catrom colorMapBorder 0 0 0 1 specType spec specularMap \"\" specMapWrap repeat specMapFilter catrom"

This seems to be a much more detailed string (that contains all the parameters for the shader) that was assigned to the object in object level.

So then I wanted to test if that passes on the information:

    void *handle = queryObject ( 0 );
    UT_String myMaterial;
    querySurfaceShader ( handle, myMaterial );
    myMaterial.harden();
    std::cout<<"myMaterial: "<<myMaterial<<endl;

openGeometryObject();
	addGeometry(gdp_0, 0);
        setSurface(myMaterial);
closeObject();

Which it does - so at this point it seems this is working - but this is still a global assignment.

So now I tried to use my own string with the exact same output as what was returned from the querySurfaceShader():

UT_String full_material_path = "op:/obj/shopnet1/basic_surface_01/basic baseColor 0.899999976158 0 0 baseColorMap default.pic colorMapWrap repeat colorMapfilter catrom colorMapBorder 0 0 0 1 specType spec specularMap \"\" specMapWrap repeat specMapFilter catrom";
openGeometryObject();
    addGeometry(gdp_0, 0);
    setSurface(full_material_path);
closeObject();

Which does not work and brings me back to:

mantra: VEX error: Unable to open op:/obj/shopnet1/basic_surface_01/basic.vex	Path not found
mantra: VEX error: Unable to load op:/obj/shopnet1/basic_surface_01/basic	Path not found

So I'm a bit stuck, does anybody know how to assign your own shader (to which you have got the full path in the scene) to geometry inside a VRAY_Procedural?

You can recreate this problem scenario easily by using the VRAY_DemoBox.C as an example file.

I have a suspicion the querySurfaceShader() returns more than just a string, but I do not know how to convert my own shaderpath into a formatted string of the kind that is required. It seems to be important to get the actual material back, but I do not know how to get to it.

I think it has something to do with :

http://www.sidefx.com/docs/hdk10.0/_o_b_j___node_8h_source.html#l00106

00836     // Get a node specified as a material 
00837     SHOP_Node           *getMaterialNode( fpreal now );

or perhaps:

00818     SHOP_Node           *evalShaderString(UT_String &shader,
00819                                         int shop_type, fpreal now,
00820                                         const UT_Options *options,
00821                                         SHOP_Node *shop = 0);

But I do not know how to use those functions. Any help would be greatly appreciated.

Link to comment
Share on other sites

So I'm a bit stuck, does anybody know how to assign your own shader (to which you have got the full path in the scene) to geometry inside a VRAY_Procedural?

AFAIK that's not possible. When the procedural is run mantra only knows about your scene as it exists in the ifd. How about adding an empty object to the scene with your shader attached, then use queryObject and querySurfaceShader to get the shader in the procedural?

My guess is that for material archives there's a way to include an ifd in another ifd. Maybe setting vm_embedvex on the rop with the method above would also work.

Edited by mrice
Link to comment
Share on other sites

AFAIK that's not possible. When the procedural is run mantra only knows about your scene as it exists in the ifd. How about adding an empty object to the scene with your shader attached, then use queryObject and querySurfaceShader to get the shader in the procedural?

My guess is that for material archives there's a way to include an ifd in another ifd. Maybe setting vm_embedvex on the rop with the method above would also work.

Hmmm, this makes sense. Thanks for the insight. Probably for each material I will have to have an empty object to reference, so rather than referencing the shader. I will reference the objects that have the shaders assigned to them. Hope it still works by passing custom variables to those shaders from within the procedural to overwrite certain parameters.

Otherwise I will probably have to load the vex code from disk.

Why did that work with the VRAY_DemoBox.C example then?

// Change the surface shader setting
        changeSetting("surface", "constant Cd ( 1 0 0 )", "object");

  • Like 1
Link to comment
Share on other sites

Probably for each material I will have to have an empty object to reference, so rather than referencing the shader. I will reference the objects that have the shaders assigned to them. Hope it still works by passing custom variables to those shaders from within the procedural to overwrite certain parameters.

This works, with the overwriting of attributes :).

Feels a bit like a hack, but now I understand it better.

Link to comment
Share on other sites

My guess is that for material archives there's a way to include an ifd in another ifd.

Yes, it seems to be, since this is what Houdini's own Delayed Load Archive SHOP is doing. Now, the question would be what is a code to include ifd in ifd file?

Edited by SYmek
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...