THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 06:05, xxxxxxxx wrote:
Okay, I looked up how exactly I do my baking, and I suppose it won't help you much, because your main concern seem to be the UV coordinates, which I currently don't care for at all.
My TextureBaker results in a new bitmap file for every unique shader, a single quad with the shader applied gets rendered and saved. I do that by creating a temporary plane object, converting that to a polygon object and using the resulting UVW-tag to bake the texture.
I chose that way because I want to reuse those textures for every object that uses the material without relying on the UV-mapping (the BakeTexture process somehow only writes pixels for actually used areas on the texture, therefore relying on the UV-coordinates of the object).
Furthermore, because I had problems with some of the material channels not getting baked properly (read: the way I wanted them, being just the clean result of the shader, not something with lighting or other "obscure" effects), I copy the requested material channel to a dummy material into the color channel. Pretty much a workaround, but it does the job.
Once I get proper export of UV-coordinates running I should be fine.
Here's the code I thought could be interesting for you, which is basically the complete main method of my TextureBaker thread:
> _
> BaseDocument* bakeDoc = NULL;
> BaseContainer bakeSettings;
> TextureTag* tTagToBake;
> Material* matToBake;
>
> // create plane
> BaseContainer planeData;
> planeData.InsData(PRIM_PLANE_SUBW, GeData(1));
> planeData.InsData(PRIM_PLANE_SUBH, GeData(1));
> BaseObject* plane = GeneratePrimitive(g_pDocument, Oplane, planeData,1.0, false, this->Get());
>
> // make plane editable
> ModelingCommandData mcData = ModelingCommandData();
> mcData.doc = g_pDocument;
> mcData.op = plane;
> if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcData))
> {
> GeConsoleOut("ERROR: TextureBaker failed creating dummy plane!");
> BaseObject::Free(plane);
> return;
> }
> BaseObject::Free(plane);
> //get editable plane to get UVW set
> BaseObject* vPlane = static_cast<BaseObject*>(mcData.result->GetIndex(0));
> UVWTag* quadUV = (UVWTag* )vPlane->GetTag(Tuvw,0);
> //set texture tag for editable plane
> tTagToBake = TextureTag::Alloc();
> tTagToBake->SetParameter(DescID(TEXTURETAG_PROJECTION), TEXTURETAG_PROJECTION_UVW, 0);
> vPlane->InsertTag(tTagToBake);
>
> g_pDocument->InsertObject(vPlane, 0,0,0);
>
> //iterate through assigned jobs
> for(std::vector<BakerInstruction>::iterator i = this->m_vWorkList.begin(); i != this->m_vWorkList.end(); i++)
> {
> bakeDoc = NULL;
> //creates default settings in bakeSettings
> MakeDefaultBakeSettings(bakeSettings, *i);
>
> if(i->ChannelToBake != CHANNEL_BUMP)
> {
> //create copy of source material with desired channel copied to color channel of result material 'matToBake'
> Material* sourceMat = (Material* )i->TexTag->GetMaterial();
> //clone original material
> matToBake = (Material* )sourceMat->GetClone(0,0);
> //disable all channels
> for(LONG j = CHANNEL_COLOR; j < CHANNEL_NORMAL; j++)
> {
> matToBake->SetChannelState(j, FALSE);
> }
> //enable color channel
> matToBake->SetChannelState(CHANNEL_COLOR, TRUE);
> //set temp material name and copy source channel from source material to color channel of temp material
> matToBake->SetName(i->TexTag->GetMaterial()->GetName()+String("_Copy"));
> CopyChannel(sourceMat, i->ChannelToBake, matToBake, CHANNEL_COLOR);
>
> //add material to document
> g_pDocument->InsertMaterial(matToBake);
> //enable color channel baking
> bakeSettings.SetData(BAKE_TEX_COLOR, GeData(TRUE));
> //set temp material in temp TextureTag
> tTagToBake->SetMaterial(matToBake);
> }
> else
> {
> // enable bumpmap baking
> bakeSettings.SetData(BAKE_TEX_NORMAL, GeData(TRUE));
> // set original material in temp TextureTag
> tTagToBake->SetMaterial(i->TexTag->GetMaterial());
> }
>
>
> bakeDoc = InitBakeTexture(g_pDocument, tTagToBake, quadUV, i->ResultUVs, bakeSettings, &i-;>ResultError, this->Get());
> if(i->ResultError || !bakeDoc)
> {
> GeConsoleOut(i->ToString());
> continue;
> }
>
> //create multipass bitmap (needed for bumpmap baking)
> MultipassBitmap* resultBitmap = MultipassBitmap::Alloc(i->TargetResX, i->TargetResY, MODE_RGB);
>
> i->ResultError = BakeTexture(bakeDoc, bakeSettings, resultBitmap, this->Get(), NULL, NULL);
> if(i->ResultError)
> {
> GeConsoleOut(i->ToString());
> continue;
> }
> //get valid version of materialname
> String matName = NameManager::GetInstance()->ReformatString(i->ExpMat->GetName());
> i->ResultFile = Filename(matName+String("_")+TexChannelToString(i->ChannelToBake));
> i->ResultFile.SetSuffix("tif");
>
> switch(i->ChannelToBake)
> {
> case CHANNEL_COLOR: i->ExpMat->SetDiffuseTex(i->ResultFile); break;
> case CHANNEL_TRANSPARENCY: i->ExpMat->SetTransparencyTex(i->ResultFile); break;
> case CHANNEL_SPECULARCOLOR: i->ExpMat->SetSpecTex(i->ResultFile); break;
> case CHANNEL_BUMP: i->ExpMat->SetBumpTex(i->ResultFile); break;
> default: GeConsoleOut("Can't set new filename for exportmaterial"); break;
> }
>
> GeConsoleOut(i->ToString());
> if(!resultBitmap->Save(Filename(i->TargetFolder.GetString()+String("\")+i->ResultFile.GetFileString()), FILTER_TIF, 0, 0))
> {
> GeConsoleOut("ERROR: Failed writing texture to disc!");
> }
>
> MultipassBitmap::Free(resultBitmap);
> if(i->ChannelToBake != CHANNEL_BUMP)
> {
> matToBake->Remove();
> Material::Free(matToBake);
> }
> BaseDocument::Free(bakeDoc);
> }
>
> //clean up
> tTagToBake->Remove();
> TextureTag::Free(tTagToBake);
> quadUV = NULL;
> vPlane->Remove();
> BaseObject::Free(vPlane);
> vPlane = NULL;
>
> bakeSettings.FlushAll();
> _
That 'BakerInstruction' is a struct I defined for this job. It contains everything needed to bake the material channel and also stores the results from a baking process. The names of its members should be pretty self-explanatory.
I could also post the 'MakeDefaultBakeSettings(...)' and 'CopyChannel' functions, but they just do what their names imply, although copying the channel of a material to another was a bit tricky.
If you got any questions, feel free to ask.
Hope this helps.