Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Texture Baking colorizer shaders [SOLVED]

    SDK Help
    0
    3
    502
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 28/12/2016 at 01:37, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   R18 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hello.

      In order to use C4D shaders in my render engine, I have to bake them into images.
      This works for most of shaders (Noise, gradient, fresnel, e.t.c)

      But, when a shader (e.g. colorizer) contains bitmaps as subshaders, BakeTexture call returns BAKE_TEX_ERR_TEXTURE_MISSING.

      For example, I have a colorizer shader with an Xbitmap in its SLA_COLORIZER_TEXTURE parameter. 
      The bitmap uses "my_image.jpg" as BITMAPSHADER_FILENAME. When I bake that colorizer, the BakeTexture returns missing texture.
      If I set the bitmap filename path into absolute, the baking works correctly.
      The image exists in tex/ folder in the same path as the project.

      Is there anything I can do to make BakeTexture find the texture ?

      Thank you very much for your time.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 30/12/2016 at 07:55, xxxxxxxx wrote:

        Hi Peterakos, thanks for writing us.

        With reference to your question, I've investigated the issue and it seems that if you're using a temporary document as shown in this thread to run your baking computations, it's mandatory to set the document path in order to have Cinema looking into that folder or inside the "contained /tex subfolder and load the bitmap specified with a relative path. If not set Cinema will struggle to find the texture and will look in other places like the application startup folder or it application data users's folder.

        Although setting the document path makes baking working out-of-the-box, i suggest you to have a look at GenerateTexturePath(), which provides you with an helper to generate texture path looking inside the following folders (in order of search)
          a)  the suggested path (if passed as argument);
          b)  the current project folder;
          c)  the ex subfolder in the current project folder;
          d)  the application user data folder;
          e)  the application startup folder;
          f)  the Textures paths specified in the Preferences.

        For the sake of completeness find below a short example.

        Best, Riccardo

            // allocate a temp doc  
          AutoAlloc<BaseDocument> tempDoc;  
          if (!tempDoc)  
              return false;  
             
          tempDoc->SetDocumentPath("<Somewhere On Your Drive>");  
             
          // allocate a primitive sphere  
          BaseObject* primSphere = BaseObject::Alloc(Osphere);  
          if (!primSphere)  
              return false;  
             
          // obtain the polygon representation  
          PolygonObject* polygonSphere = ToPoly(primSphere);  
             
          // insert into the temp doc  
          tempDoc->InsertObject(polygonSphere, nullptr, nullptr);  
             
          // allocate a texture tag  
          TextureTag* sphereTextureTag = TextureTag::Alloc();  
          if (!sphereTextureTag)  
              return false;  
             
          // set the texture tag params  
          sphereTextureTag->SetParameter(DescID(TEXTURETAG_PROJECTION), TEXTURETAG_PROJECTION_CUBIC, DESCFLAGS_SET_0);  
             
          // insert into the polygonSphere  
          polygonSphere->InsertTag(sphereTextureTag);  
             
          // allocate a material  
          AutoAlloc<Material> sphereMaterial;  
          if (!sphereMaterial)  
              return false;  
             
          // get the BaseContainer of the material  
          BaseContainer *sphereMaterialBC = sphereMaterial->GetDataInstance();  
          if (!sphereMaterialBC)  
              return false;  
             
          // allocate the colorizer shader  
          AutoAlloc<BaseShader> colorizerShader(Xcolorizer);  
          if (!colorizerShader)  
              return false;  
             
          // retrieve the BaseContainer of the colorizer   
          BaseContainer* colorizerShaderBC = colorizerShader->GetDataInstance();  
          if (!colorizerShaderBC)  
              return false;  
             
          // allocate the bitmap shader  
          AutoAlloc<BaseShader> bitmapShader(Xbitmap);  
          if (!bitmapShader)  
              return false;  
             
          // retrieve the BaseContainer of the bitmap  
          BaseContainer* bitmapShaderBC = bitmapShader->GetDataInstance();  
          if (!bitmapShaderBC)  
              return false;  
             
          Filename bitmapFilename("bitmap.jpg");  
             
          // set the filename of the bitmap shader  
          // NOTE: the file should reside in the application directory if the project files has not been   
          // saved on disk or inside the /tex folder where the project files resides  
          bitmapShaderBC->SetFilename(BITMAPSHADER_FILENAME, bitmapFilename);  
             
          // set the texture link of the colorizer shader to the bitmapShader  
          colorizerShaderBC->SetLink(SLA_COLORIZER_TEXTURE, bitmapShader);  
          colorizerShader->InsertShader(bitmapShader.Release());  
             
          // set the color link of the material to the colorizer shader  
          sphereMaterialBC->SetLink(MATERIAL_COLOR_SHADER, colorizerShader);  
          sphereMaterial->InsertShader(colorizerShader.Release());  
             
          // update   
          sphereMaterial->Message(MSG_UPDATE);  
          sphereMaterial->Update(true, true);  
             
          // insert the material and set the texture tag to use this material  
          sphereTextureTag->SetMaterial(sphereMaterial);  
          tempDoc->InsertMaterial(sphereMaterial.Release());  
              
          // allocate a BaseContainer for the texture baking settings and set a few meaningful values  
          BaseContainer textureBakingBC;  
          textureBakingBC.SetInt32(BAKE_TEX_WIDTH, 512);  
          textureBakingBC.SetInt32(BAKE_TEX_HEIGHT, 512);  
          textureBakingBC.SetBool(BAKE_TEX_COLOR, true);  
             
          // get the UVW tag from the sphere - it's not required to run GenerateUVW() to get the proper  
          // UVW representation because it's done internally by the InitBakeTexture  
          UVWTag* sphereUVWTag = (UVWTag * )polygonSphere->GetTag(Tuvw);  
             
          // proceed to bake the texture assigned in the color slot  
          BAKE_TEX_ERR initBakingRes = BAKE_TEX_ERR_NONE, bakingRes = BAKE_TEX_ERR_NONE;
            //  init the baking process  
          BaseDocument* bakingDoc = InitBakeTexture(tempDoc, sphereTextureTag, sphereUVWTag, NULL, textureBakingBC, &initBakingRes, NULL);  
          if (initBakingRes != BAKE_TEX_ERR_NONE)  
          {  
              GePrint("Failed to init texture baking[" + String::IntToString(initBakingRes) + "]");  
              BaseDocument::Free(bakingDoc);  
              return false;  
          }  
             
          // allocate the bitmap used for storing and saving the baking computations  
          AutoAlloc<BaseBitmap> bakingBmp;  
          if (!bakingBmp)  
          {  
              BaseDocument::Free(bakingDoc);  
              return false;  
          }  
             
          // execute the texture baking  
          bakingRes = BakeTexture(bakingDoc, textureBakingBC, bakingBmp, NULL, NULL, NULL);  
          if (bakingRes != BAKE_TEX_ERR_NONE)  
          {  
              GePrint("Failed to bake the texture[" + String::IntToString(bakingRes) + "]");  
              BaseDocument::Free(bakingDoc);  
              return false;  
          }  
             
          GePrint("Texture baking accomplished");  
             
          // free the baking document because we're still owning it  
          BaseDocument::Free(bakingDoc);  
             
          // save the bitmap on disk  
          Filename bakingBmpFilename("TextureBackingOutput.jpg");  
          Filename bakingBmpFullFilename = tempDoc->GetDocumentPath() + bakingBmpFilename;  
          IMAGERESULT bakingBmpRes = bakingBmp->Save(bakingBmpFullFilename, FILTER_JPG, nullptr, SAVEBIT_0);  
          if (bakingBmpRes != IMAGERESULT_OK)  
          {  
              GePrint("Failed to save baked texture bitmap [" + String::IntToString(bakingBmpRes) + "]");  
              return false;  
          }  
             
          GePrint("Texture baking saved on " + bakingBmpFullFilename.GetString());  
             
          return true;
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 30/12/2016 at 11:17, xxxxxxxx wrote:

          I cannot express how much I thank you !!
          Have a nice day !

          1 Reply Last reply Reply Quote 0
          • First post
            Last post