本文最后更新于654 天前,其中的信息可能已经过时,如有错误请发送邮件到84581927@qq.com
为了减少材质球的数量,减少SetPassCall,美术通常会把贴图打成图集,uv移动的正确的位置。数量少还好,数量多的话会很耗时间。今天来分享一个可以一键解决美术需要做3,4天工作的工具。
功能:
1.在3dmax里面选中的objs,提取他们的diffuseMap,打成图集。
2.把objs的uv,用unwrap uvw把uv也打成图集形式。
本来的uv:
工具处理后的贴图:
工具处理后的uv
原理:
1.使用了bitmap的getPixels,setPixels接口打图集
2.使用了unwrap uvw的scaleSelectedXY接口处理了uv
unwrapMod.scaleSelectedXY 1 0.5 [1,1,0] 代表以[1,1]点为中心向Y轴缩放0.5
3.使用了bin packing的思想把本来就是2的N次方的图片打成图集
报错
源码在这里
global realseBitMapArray = #() global isSetUV = true global isProgress = false struct BitMapData ( public p_bitmap, p_packingSize, p_volume, p_objArray = #(), on create do ( --format "Struct Created: %n" this ) ) struct BitMapDicData ( public p_packingSize, p_Array = #() -- BitMapData数组 ) fn GetUVW obj = ( -- select obj -- if (obj.modifiers[#unwrap_uvw] == undefined)do --添加uv组件 -- ( -- addModifier obj (unwrap_UVW()) -- ) -- unwrapMod = obj.modifiers[#unwrap_uvw] -- max modify mode -- --break() -- subobjectlevel = 3 -- max select all select obj max modify mode unwrapMod = obj.modifiers[#unwrap_uvw] if (unwrapMod == undefined)then --添加uv组件 ( modPanel.addModToSelection (Unwrap_UVW ()) ui:on unwrapMod = obj.modifiers[#unwrap_uvw] ) else ( modPanel.setCurrentObject unwrapMod ) subobjectlevel = 3 max select all return unwrapMod ) fn packing dicData packingSize = ( tempDicData = BitMapDicData() tempDicData.p_packingSize = packingSize for i = 1 to (dicData.p_Array.count) do ( obj = dicData.p_Array[i] if (obj.p_bitmap.width > obj.p_bitmap.height)then --横向矩形 ( --图片换向 tempBitMap = bitmap obj.p_bitmap.height obj.p_bitmap.width color:white realseBitMapArray = append realseBitMapArray tempBitMap for i = 0 to (obj.p_bitmap.width-1) do ( for j = 0 to (obj.p_bitmap.height-1) do ( pixel = getPixels obj.p_bitmap [i,j] 1 linear:true --setPixels tempBitMap [i,j] pixel --根据旋转矩阵得出 setPixels tempBitMap [obj.p_bitmap.height - j, i] pixel ) ) --需要换向的都是原图,不考虑拼的图 --uv换向 if (isSetUV) then ( for p_obj in obj.p_objArray do ( unwrapMod = GetUVW p_obj unwrapMod.unwrap2.RotateSelected (DegToRad(-90)) [0.5,0.5,0] subobjectlevel = 0 collapseStack p_obj ) ) obj.p_bitmap = tempBitMap ) if ( (mod i 2) == 1)then ( picWidth = obj.p_bitmap.width picHeight = obj.p_bitmap.height if(obj.p_bitmap.width == obj.p_bitmap.height)then --正方形 ( picHeight = picHeight * 2 tempBitMapData = BitMapData() tempBitMap = bitmap picWidth picHeight color:white realseBitMapArray = append realseBitMapArray tempBitMap for i = 0 to (obj.p_bitmap.width-1) do ---第一张 ( for j = 0 to (obj.p_bitmap.height-1) do ( pixel = getPixels obj.p_bitmap [i,j] 1 linear:true setPixels tempBitMap [i,j] pixel ) ) --------------------------第一张的UV,上移----------------------------------- if (isSetUV) then ( for innObj in obj.p_objArray do ( unwrapMod = GetUVW innObj -- unwrapMod.unwrap2.scaleSelectedXY 1 0.5 [1,1,0]--上移 unwrapMod.scaleSelectedXY 1 0.5 [1,1,0]--上移 subobjectlevel = 0 collapseStack innObj tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj ) ) ------------------------------------------------------------------------------ if(i != dicData.p_Array.count)then ( obj2 = dicData.p_Array[i+1] for i = 0 to (obj2.p_bitmap.width-1) do ---第二张 ( for j = 0 to (obj2.p_bitmap.height-1) do ( pixel = getPixels obj2.p_bitmap [i,j] 1 linear:true setPixels tempBitMap [i,j + obj2.p_bitmap.height] pixel ) ) if (isSetUV) then ( --------------------------第二张的UV,下移----------------------------------- for innObj in obj2.p_objArray do ( unwrapMod = GetUVW innObj -- unwrapMod.unwrap2.scaleSelectedXY 1 0.5 [0,0,0]--下移 unwrapMod.scaleSelectedXY 1 0.5 [0,0,0]--下移 subobjectlevel = 0 collapseStack innObj tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj ) -------------------------- -------------------------- -------------------------- ) ) tempBitMapData.p_packingSize = packingSize tempBitMapData.p_volume = picWidth * picHeight tempBitMapData.p_bitmap = tempBitMap tempDicData.p_Array = append tempDicData.p_Array tempBitMapData ) else --纵向矩形 ( picWidth = picWidth * 2 tempBitMapData = BitMapData() tempBitMap = bitmap picWidth picHeight color:white realseBitMapArray = append realseBitMapArray tempBitMap for i = 0 to (obj.p_bitmap.width-1) do ---第一张 ( for j = 0 to (obj.p_bitmap.height-1) do ( pixel = getPixels obj.p_bitmap [i,j] 1 linear:true setPixels tempBitMap [i,j] pixel ) ) if (isSetUV) then ( --------------------------第一张的UV,左移----------------------------------- for innObj in obj.p_objArray do ( unwrapMod = GetUVW innObj -- unwrapMod.unwrap2.scaleSelectedXY 0.5 1 [0,0,0]--左移 unwrapMod.scaleSelectedXY 0.5 1 [0,0,0]--左移 subobjectlevel = 0 collapseStack innObj tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj ) -------------------------- -------------------------- -------------------------- ) if(i != dicData.p_Array.count)then ( obj2 = dicData.p_Array[i+1] for i = 0 to (obj2.p_bitmap.width-1) do ---第二张 ( for j = 0 to (obj2.p_bitmap.height-1) do ( pixel = getPixels obj2.p_bitmap [i,j] 1 linear:true setPixels tempBitMap [i + obj2.p_bitmap.width,j] pixel ) ) if (isSetUV) then ( --------------------------第二张的UV,右移----------------------------------- for innObj in obj2.p_objArray do ( unwrapMod = GetUVW innObj -- unwrapMod.unwrap2.scaleSelectedXY 0.5 1 [1,1,0]--右移 unwrapMod.scaleSelectedXY 0.5 1 [1,1,0]--右移 subobjectlevel = 0 collapseStack innObj tempBitMapData.p_objArray = append tempBitMapData.p_objArray innObj ) -------------------------- -------------------------- -------------------------- ) ) tempBitMapData.p_packingSize = packingSize tempBitMapData.p_volume = picWidth * picHeight tempBitMapData.p_bitmap = tempBitMap tempDicData.p_Array = append tempDicData.p_Array tempBitMapData ) ) ) return tempDicData ) rollout TidyRollout "整理地形图集&UV工具" ( button tidyBtn "整理" width:100 height:50 on tidyBtn pressed do ( if( $ != undefined) then ( bitMapArray = #() bitMapDic = #() outBitMapArray = #() if(isProgress)then progressStart "正在整理图片(打图集)" for obj in $ do ( if (not (isGroupHead obj))then ( -- print obj if (obj.material != undefined or obj.material.diffuseMap != undefined )do -- 把图片,图片体积,记录 ( -- break() tempData = undefined for b in bitMapArray do -----分辨是否同一个贴图 ( if (b.p_bitmap.fileName == obj.material.diffuseMap.bitmap.fileName)then ( tempData = b exit ) ) --处理MultiMaterial if (classof (obj.material) == MultiMaterial)then ( obj.material = obj.material.materialList[1] ) if (tempData == undefined) then ( tempData = BitMapData() tempData.p_bitmap = obj.material.diffuseMap.bitmap tempData.p_volume = tempData.p_bitmap.width * tempData.p_bitmap.height bitMapArray = append bitMapArray tempData ) outBitMapArray = append outBitMapArray obj.material tempData.p_objArray = append tempData.p_objArray obj ) ) ) if(isProgress)then progressUpdate 10 if (bitMapArray.count > 1)then ( --------------------------------------------------sort-------------------------------------------------------------- fn compareFN v1 v2 = ( case of ( (v1.p_volume < v2.p_volume) : -1 (v1.p_volume > v2.p_volume) : 1 default: 0 ) ) qsort bitMapArray compareFN --按体积排序 --------------------------------------------------sort-------------------------------------------------------------- -------------------------------------------------存字典------------------------------------------------------------- for obj in bitMapArray do ( --算出打包的size obj.p_packingSize = obj.p_volume / bitMapArray[1].p_volume --把准备打包的数据存在 字典bitMapDic里 if (bitMapDic.count == 0)then ( tempDicData = BitMapDicData() tempDicData.p_packingSize = obj.p_packingSize tempDicData.p_Array = append tempDicData.p_Array obj bitMapDic = append bitMapDic tempDicData ) else ( inIf = false for dic in bitMapDic do ( if (obj.p_packingSize == dic.p_packingSize)then ( dic.p_Array = append dic.p_Array obj inIf = true ) ) if (not inIf)then ( tempDicData = BitMapDicData() tempDicData.p_packingSize = obj.p_packingSize tempDicData.p_Array = append tempDicData.p_Array obj bitMapDic = append bitMapDic tempDicData ) ) ) -------------------------------------------------存字典------------------------------------------------------------- ----------------------------------------------2的N次方循环---------------------------------------------------------- for i = 0 to 10 do ( tempDicData = undefined if(isProgress)then progressUpdate ( ( (2+i) / 10.0) * 100) for obj in bitMapDic do ( if (obj.p_packingSize == 2^i)then ( tempDicData = packing obj (2^(i+1)) --打图集,tempDicData打出来的图集信息 exit ) ) -- print (1111111) -- print tempDicData if (tempDicData != undefined and tempDicData.p_Array.count != 0)then ( inIf = false for obj in bitMapDic do ( if(obj.p_packingSize == tempDicData.p_packingSize)then --找到p_packingSize一样的 ( for bit in (tempDicData.p_Array) do --逐个插入 ( obj.p_Array = append obj.p_Array bit ) inIf = true exit ) ) if (not inIf)do --找不到 p_packingSize一样的 ( index = -1 for iter=1 to (bitMapDic.count) do ( if(bitMapDic[iter].p_packingSize > tempDicData.p_packingSize)then --找一个比他大的p_packingSize ( index = iter exit ) ) if (index == -1)then --找不到判断是否可以继续打图集 ( bitMapDic = append bitMapDic tempDicData if (tempDicData.p_Array.count == 1)then exit--结束循环 ) else --找得到插在他前面 ( insertItem tempDicData bitMapDic (index-1) ) ) ) else ( messageBox "tempDicData为空!!!!!!!!!!" exit ) ) ----------------------------------------------2的N次方循环---------------------------------------------------------- ----------------------------------------------存最终图集------------------------------------------------------------ outBitMapDic = bitMapDic[bitMapDic.count] outBitMap = outBitMapDic.p_Array[1].p_bitmap outBitMap.filename = SelectSaveBitmap caption:"Select a file" gamma:&gma metadata:&data if (outBitMap.filename != "undefine") do save outBitMap gamma:gma metadata:data -- outBitMap.filename = "C:Users/Administrator/Desktop/testImage.png" -- save outBitMap if (isSetUV)then ( for obj in outBitMapArray do ( obj.diffuseMap.bitmap = outBitMap ) ) ----------------------------------------------存最终图集------------------------------------------------------------ ------------------------------------------------释放内存------------------------------------------------------------ for obj in realseBitMapArray do ( close obj free obj ) close outBitMap free outBitMap if(isProgress)then ( progressUpdate 100 progressEnd() ) free realseBitMapArray free bitMapArray free bitMapDic free outBitMapArray gc() ------------------------------------------------释放内存------------------------------------------------------------ ) else ( if(isProgress)then ( progressUpdate 100 progressEnd() ) ) ) else ( if(isProgress)then ( progressUpdate 100 progressEnd() ) messageBox "You should Pick a Obj !!!!!!!!!!" ) ) ) createDialog TidyRollout 200 100
————————————————
版权声明:本文为CSDN博主「a11董常伟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_35411438/article/details/112369236