Texture Baking colorizer shaders [SOLVED]
-
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.
-
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;
-
On 30/12/2016 at 11:17, xxxxxxxx wrote:
I cannot express how much I thank you !!
Have a nice day !