Announcement

Collapse
No announcement yet.

Assign per face shaders

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Assign per face shaders

    Hi,
    In a Maya/VRay plugin, I have a custom-built geometry created with a GeomStaticMesh (e.g., simple cube with 6 faces), and would like to assign different shaders per face.
    I extracted the list of shaders in a MObjectArray (lambert,blinn,VRayMtl...) which are already available in the Maya's hypershade and assigned to other meshes. How can I assign randomly these shaders to different faces of the geometry ?
    Geometry built like this:

    Code:
        baseGeomPlugin->setParameter(&param_vertices);
        baseGeomPlugin->setParameter(&param_faces);
        baseGeomPlugin->setParameter(&param_normals);
        baseGeomPlugin->setParameter(&param_faceNormals);
        baseGeomPlugin->setParameter(&param_dynamic_geometry);
        baseGeomPlugin->setParameter(&param_dynamicGeom);
    I think I should use the "face_mtlIDs" parameter, but not sure how to convert my array of Object shaders to an Mtl array exploitable by VRay.

    Thanks.
    Last edited by lcrivell; 14-12-2015, 01:00 AM.

  • #2
    You'll have to export proper face_mtlIDs (every face has a proper material index) parameter and then you'll have to use a MtlMulti material.

    The easiest way to see how this works is to export a vrscene with simple scehe, where you have a mesh that has more than one material assigned to the faces.
    V-Ray developer

    Comment


    • #3
      Thanks. Am I supposed to create each material in my code (like the one below extracted from a vrscene), or is there a function that translates MObject Maya materials in VRayPlugin Material (I have the shader MObject available) ?
      Ie, if there is already a Blinn1 assigned to another object in Maya, can I simply reuse this Blinn1 or do I have to create a material in Vray sdk and copy all the Blinn1 attributes ?
      In the first case, is there an sample to show me how to create these different materials to be linked in the Mtldulti ?

      Thank !

      Code:
      BRDFBlinn blinn1@blinn_brdf {
        color=Color(1, 1, 1);
        transparency=Color(0.65, 0.65, 0.65);
        back_side=1;
        trace_depth=1;
        hilightGlossiness=0.7;
        reflectionGlossiness=0.7;
        subdivs=8;
      }
      
      BRDFDiffuse blinn1@diffuse_brdf {
        color=Color(0, 0, 0);
        color_tex=blinn1@diffuse_brdf_color_tex@tex_with_amount;
        transparency=Color(0, 0, 0);
      }
      
      TexAColorOp blinn1@diffuse_brdf_color_tex@tex_with_amount {
        color_a=AColor(1, 0, 0, 1);
        mult_a=0.8;
      }
      
      BRDFLayered blinn1@brdflayered {
        brdfs=List(
          blinn1@blinn_brdf,
          blinn1@diffuse_brdf
        );
        channels=List(
        );
      }
      
      MtlSingleBRDF blinn1@material {
        brdf=blinn1@brdflayered;
        allow_negative_colors=1;
      }
      Last edited by lcrivell; 14-12-2015, 09:48 AM.

      Comment


      • #4
        Originally posted by lcrivell View Post
        Thanks. Am I supposed to create each material in my code (like the one below extracted from a vrscene), or is there a function that translates MObject Maya materials in VRayPlugin Material (I have the shader MObject available)?
        It depends on where this happens and what state the translator is in, so if you can provide a bit more info it would be helpful.

        Best regards,
        Vlado
        I only act like I know everything, Rogers.

        Comment


        • #5
          I don't think we have any way for a plugin to export a material in the current versions.
          But, I think it won't be too difficult to add this functionality in a future version.

          Can you give us an overview or a bit more detailed description what you are trying to achieve with your plugin?
          If we know more about your problem we could probably give better suggestions how to solve it.
          V-Ray developer

          Comment


          • #6
            Basically I have animated meshes in Maya (polygon mesh animated via a joint), and I am writing a Maya plugin to duplicate / rotate / translate / scale many times these meshes. Can be up to 50.000, so I prefer to remain in C++ rather than integrating Python code.
            The duplication is "virtual", i.e. only visible at render time. I therefore need to copy the existing mesh's shaders to the duplicated ones.

            Based on the samples, I created an mtlMulti:
            Code:
                int NUM_RANDOM=2;
                VRayPlugin *randomMtls[NUM_RANDOM];
                for (int i=0; i<NUM_RANDOM; i++)
                    randomMtls[i]=createRandomMtl(); // Random color material
            
                mtlPlugin=newPlugin("MtlMulti");
            
                DefPluginListParam *mtlListParam=factory.saveInFactory(new DefPluginListParam("mtls_list"));
                mtlListParam->setCount(NUM_RANDOM+1);
                for (int i=0; i<NUM_RANDOM; i++)
                    mtlListParam->setPlugin(i, randomMtls[i]);
                mtlPlugin->setParameter(mtlListParam);
                
                DefIntListParam *idListParam=factory.saveInFactory(new DefIntListParam("ids_list"));
                idListParam->setCount(NUM_RANDOM+1);
                IntList list = idListParam->getIntList(0);
                for (int i=0; i<NUM_RANDOM+1; i++)
                    list[i]=i;
                mtlPlugin->setParameter(idListParam);
            
                param_shaders.setCount(12); // Cube -> 6 faces x 2
                setFace(param_shaders, 0, 0, 1, 0); // Color #0 for some triangles ad #1 for others
                setFace(param_shaders, 1, 0, 1, 0);
                setFace(param_shaders, 2, 0, 1, 0);
                setFace(param_shaders, 3, 0, 1, 0);
                mtlPlugin->setParameter(&param_shaders);
            and assign it to my instances:
            Code:
            		MaterialInterface *mtl=mtlPlugin? static_cast<MaterialInterface*>(GET_INTERFACE(mtlPlugin, EXT_MATERIAL)) : _mtl;
            		BSDFInterface *bsdf=mtlPlugin? static_cast<BSDFInterface*>(GET_INTERFACE(mtlPlugin, EXT_BSDF)) : _bsdf;
             
                            myInstance->addMesh(geomSource->newInstance(mtl, bsdf, renderID, volume, lightList, bTM, objectID, infoUserAttr.ptr(), primaryVisibility));
            But all my instances are grey. Should I do something else ?

            Thank you !
            Last edited by lcrivell; 14-12-2015, 11:59 AM.

            Comment


            • #7
              Hm, so do you want to preserve the original materials applied to the mesh object you're duplicating, or do you want to attach some random materials to the instances?

              On a side note: Have you looked at the vray_scenemodifiertest?
              It might be easier for you to work on the vray scene level and create the instances after the scene is loaded during the actual rendering.
              V-Ray developer

              Comment


              • #8
                Indeed, I would like to preserve the original materials applied to the mesh I am duplicating.
                I will have a look at the scene modifier but as VRay will not be the only renderer, I need to instance the meshes in Maya.
                Thanks for any idea to preserving materials. The example I have was a start, the randomization will come at a later stage but in a first step I would like to reuse material.

                In the code I gave below, the MtlMulti is not even present in the vrscene. But the vertices/indices... are not in the vrscene neither, but as my geometry is properly displayed, any clue on how to get all of these in the vrscene ?
                Last edited by lcrivell; 14-12-2015, 01:50 PM.

                Comment


                • #9
                  So, if I understand correctly you have a single Maya node in the Maya scene that has some other Maya node (geometry) as input.
                  Then your node is supposed to created objects only during rendering right?
                  V-Ray developer

                  Comment


                  • #10
                    Hi,
                    I have indeed a Maya node, but it's a MPxNode, not a SurfaceShader.

                    ** but **

                    I was able to properly do what I needed thanks to your comments and questions !

                    Basically I looked too complicated and VRay's architecture is helping to keep it simple.
                    I simply needed to connect the face_mtlIDs to the GeomStaticMesh plugin (I connected it initially to the MtlMulti plugin), and to reuse the provided MaterialInterface and BSDFInterface.
                    In addition to that, I assigned the different needed shaders to simple meshes linked to the MPxNode.

                    Code:
                    VRayStaticGeometry* GeomMeshLoader::newInstance(MaterialInterface [COLOR="#FF0000"]*_mtl[/COLOR], BSDFInterface [COLOR="#FF0000"]*_bsdf[/COLOR], int renderID, VolumetricInterface *volume, LightList *lightList, const TraceTransform &baseTM, int objectID, const tchar *userAttr, int primaryVisibility)
                    {
                        <...>
                        myInstance->addMesh(geomSource->newInstance([COLOR="#FF0000"]_mtl[/COLOR], [COLOR="#FF0000"]_bsdf[/COLOR], renderID, volume, lightList, baseTM, objectID, infoUserAttr.ptr(), primaryVisibility));
                    }
                    Now I have all the instances with right material.
                    Thanks again !
                    Last edited by lcrivell; 15-12-2015, 07:01 AM.

                    Comment


                    • #11
                      Good to know you've made it work.
                      V-Ray developer

                      Comment


                      • #12
                        Thanks. Still struggling a bit with uvw channels. What we call uvw channels in VRay terms, is simply the uv coordinates for each mesh vertex and face, right ?
                        Last edited by lcrivell; 16-12-2015, 01:06 AM.

                        Comment


                        • #13
                          You have to provide the list of UVW values (uv coordinates, but as vector3) and a list of faces that specify which uvw value should be used for a particular face vertex.
                          V-Ray developer

                          Comment


                          • #14
                            Thanks. Is the map_channel list type a DefListParamBase ?
                            Would you have a sample showing how to create a list of lists ?
                            Thanks !

                            Comment


                            • #15
                              You can use the class DefMapChannelsParam, it implements the whole list of lists logic and allows you to set up the mapping channels easily - f.e. you could use getMapChannels() method to get the channels list and fill it as needed.

                              Best regards,
                              Vlado
                              I only act like I know everything, Rogers.

                              Comment

                              Working...
                              X