-- ProceduralTextureBaker v1.2, 27/8/2014 ------------------------------------------- -- Christopher Grant @ HMC Architects, 2006 -- Web: http://www.christophergrant.com -- Email: chris@christophergrant.com -- This and tons of other scripts are available at www.scriptspot.com. The "spot" for 3ds scripts! -- -- Description: -- Replaces procedural textures with rendered bitmap at specified size. Designed as tool to aid in -- exporting materials to other 3d apps. Great way to essentially "bake" your max materials. For instance -- you might be using a nested tile / bitmap which of course can't be easily exported. Simply pick the -- map size you want to bake and all your procedural maps will be baked (rendered) as bitmaps and replaced in your -- scene. See below for detailed list of supported material/map types. -- -- Compatibility List: -- * Fully compatible with: Standard, Architectural, VRay, Multi-Sub, Blend, Composite and Shellac materials -- * 2D map types: Bricks (Tile), ColorCorrection, Checker, FallOff, Gradient, Gradient Ramp, Mask, sciAnaComp, Swirl -- * 3D map types: Cellular, Dent, Marble, Noise, Perlin Marble, Smoke, Speckle, Splat, Stucco, Waves, Wood -- -- NOTE: -- There is no way to exactly represent a 3D map as a 2D texture. You may have a perfect noise map applied using world -- coordinates that when using UV looks stretched. I can't change that. This is just a quick little tool made for those -- instances where you just want to get a file into another program but really need some of your nested procedurals. -- For me, I often have bitmaps inside of noise maps for grass or bitmaps inside of tile maps for ground/ceilings/walls. -- This tool lets me "bake" that info into a simple map. Also, I might have tiling of 10 on a submap, rotation of 45 -- on another map, and mirror checked on another map. Not every program supports this, so I can once again "bake" those -- map changes into a new bitmap. -- -- Installation: -- Click MAXScript / Run Script and select this script from wherever you downloaded it to. This will "install" -- the script into 3ds. Now, go to Customize / Customize User Interface. You'll find the script in the "CG_Tools" -- category as "Procedural Texture Baker" ... Just assign it a keyboard shortcut or stick it in a menu and you're ready to go. -- -- Tip: -- Although undo supposedly works, keep in mind this is changing en masse a ton of things. Save you file first, just in case. -- -- History: -- -- 7/3/2006 - 01 dev. start working with tile maps only. concept code. -- - 02 break out into functions. test usage. -- - 03 currently works on vray+standard. converts diff/bump/refl/refr maps. need UI. needprogress bar. -- 7/5/2006 - 04 add reflect/refract support to std.mat... break main into another fn. convert to macroscript. -- - 05 develop UI framework. -- - 06 continue connecting UI features. add mask, gradient, gradient ramp, noise and smoke map support. -- - 07 3d maps don't work with max8 - bug in rendermap. Or maybe they do. Weird... Added CCorrect and Checker. -- - 08 Added opacity map support in std/vray mats. Added blend/composite/shellac/arch/multi-sub materials. -- - 09 added option to include bitmap textures. -- - 10 name change. made more sense. -- 7/6/2006 - 11 Changed material / map support. Added full standard mat, arch mat and vray mat support. Added 3d map support. -- 27/8/2014 - 12 This version (1.2) adds support for FallOff and ColorCorrection on 3DS Max 2014 (by: Francisco Toledo!) -- -- Developer Notes: -- * Would be nice to have checkboxes for map types to convert. Might be worth implementing. -- * Progress bar doesn't seem to give the correct feedback. Hmmm... -- * 3D procedurals seem dicey. Sometimes they render as black. Must be memory leak / bug somewhere. Most likely out of my control. -- If this happens to you, restart max and try again. -- * DOH. Just found the getNumSubTexmaps function which would have made the VRay mat conversion way slicker! oh well. ------------------------------------------------------------------ ------------------------------------------------------------------ ----- BEGIN MACROSCRIPT -------------------------------- ------------------------------------------------------------------ ------------------------------------------------------------------ macroScript cgRPT Category:"CG_Tools" toolTip:"Procedural Texture Baker" buttontext:"Procedural Texture Baker" ( ------------------------------------------------------------------ ----- GLOBAL VARIABLES -------------------------------- ------------------------------------------------------------------ global cgCompatibleTexMaps = #(Bricks, Cellular, ColorCorrection, Checker, Dent, FlatColor, Gradient, Gradient_Ramp, Noise, Marble, Mask, sciAnaComp, Smoke, Speckle, Splat, Stucco, swirl, Water, Wood) --value stores compatible procedural maps for rendering global cgCompatibleTexMapsstrings = #() --build array of map types from compatible maps above for i in cgCompatibleTexMaps do append cgCompatibleTexMapsstrings (i as string) global cgRPTpath = "C:" global cgRPText = ".png" global cgRPTsize = [1024,1024] global cgRPTbitmaps = FALSE -- UI globals global cgRPT_floater global cgRPT_about global cgRPT_main ------------------------------------------------------------------ ----- FUNCTIONS --------------------------------------- ------------------------------------------------------------------ function cgCheckValidProcMap themap = ( --get class of current texture map texmapclass = classof themap if texmapclass == Bitmaptexture then if cgRPTbitmaps == TRUE do return TRUE --IF user wants to include cropped bitmaps --verify current procedural map part of global compatible tex maps array if finditem cgCompatibleTexMaps texmapclass != 0 then return TRUE else return FALSE --invalid map, skip it by returning false ) --creates bitmap texture and copies coordinates from existing map into it. function cgCopyCoords src = ( dest = Bitmaptexture() try ( b = dest.coords a = src.coords b.mapChannel = a.mapChannel b.mappingType = a.mappingType b.UVW_Type = a.UVW_Type ) catch() --catches maps which don't have coordinates but still creates the new bitmap return dest ) function cgRendReplace curmat curTex = ( --file name from path + mat name + texture name + extension fname = cgRPTpath + "\\" + curmat.name + "_" + (classof curTex) as string + "_" + curTex.name + cgRPText --render texture map rm = renderMap curTex size:cgRPTsize fileName:fname scale:200 --picked arbitrary scale which seemed right to me... not sure though what long term ramifications could be??? save rm close rm --new bitmaptexture created. copy coords from procedural. set filename newTexmap = cgCopyCoords curTex newTexmap.filename = fname newTexmap.name = curTex.name return newTexmap ) function cgUpdateSize thesize = --sets global size variable and updates UI display ( cgRPTsize = [thesize,thesize] cgRPT_main.spin_Size.value = thesize ) ------------------------------------------------------------------ ----- MAIN SCRIPT FUNC -------------------------------- ------------------------------------------------------------------ function cgRenderProceduralTextures curmat = ( case (classof curmat) of ( --VRAY MATERIAL (SUPPORTS ALL MAP CHANNELS AS OF VRAY 1.49.28) VrayMtl: ( ---- Diffuse ---- curTex = curmat.texmap_diffuse if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_diffuse = cgRendReplace curmat curTex ---- Reflect ---- curTex = curmat.texmap_reflection if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_reflection = cgRendReplace curmat curTex ---- HGlossiness ---- curTex = curmat.texmap_hilightGlossiness if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_hilightGlossiness = cgRendReplace curmat curTex ---- RGlossiness ---- curTex = curmat.texmap_reflectionGlossiness if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_reflectionGlossiness = cgRendReplace curmat curTex ---- Fresnel IOR ---- curTex = curmat.texmap_reflectionIOR if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_reflectionIOR = cgRendReplace curmat curTex ---- Refract ---- curTex = curmat.texmap_refraction if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_refraction = cgRendReplace curmat curTex ---- Glossiness ---- curTex = curmat.texmap_refractionGlossiness if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_refractionGlossiness = cgRendReplace curmat curTex ---- IOR ---- curTex = curmat.texmap_refractionIOR if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_refractionIOR = cgRendReplace curmat curTex ---- Translucent ---- curTex = curmat.texmap_translucent if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_translucent = cgRendReplace curmat curTex ----- Bump ------ curTex = curmat.texmap_bump if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_bump = cgRendReplace curmat curTex ----- Displace ------ curTex = curmat.texmap_displacement if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_displacement = cgRendReplace curmat curTex ----- Opacity ------ curTex = curmat.texmap_opacity if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_opacity = cgRendReplace curmat curTex ----- Environment ------ curTex = curmat.texmap_environment if curTex != undefined and cgCheckValidProcMap curtex do curmat.texmap_environment = cgRendReplace curmat curTex ) --STANDARD MATERIAL (SUPPORTS ALL MAP CHANNELS IN STANDARD MATERIAL) Standardmaterial: ( ----- loop through all maps in material ------ mapcount = 1 for curTex in curmat.maps do ( if curTex != undefined do if cgCheckValidProcMap curtex == TRUE do curmat.maps[mapcount] = cgRendReplace curmat curTex mapcount+=1 ) ) --ARCHITECURAL MATERIAL (SUPPORTS ALL MAP CHANNELS IN ARCHITECTURAL MATERIAL) Architectural: ( ----- loop through all maps in material ------ mapcount = 1 for curTex in curmat.maps do ( if curTex != undefined do if cgCheckValidProcMap curtex == TRUE do curmat.maps[mapcount] = cgRendReplace curmat curTex mapcount+=1 ) ) --MULTI/SUB-OBJECT MATERIAL Multimaterial: ( for subs in curmat do ( cgRenderProceduralTextures subs ) ) --BLEND MATERIAL (SUPPORTS TWO MAT CHANNELS + MASK SLOT IN BLEND MATERIAL) Blend: ( if curmat.map1 != undefined do cgRenderProceduralTextures curmat.map1 if curmat.map2 != undefined do cgRenderProceduralTextures curmat.map2 if curmat.mask != undefined do cgRenderProceduralTextures curmat.mask ) --COMPOSITE MATERIAL (SUPPORTS BASE MATERIAL AND ALL AVAILABLE SUB MATS IN COMPOSITE MATERIAL) compositematerial: ( if curmat.baseMaterial != undefined do cgRenderProceduralTextures curmat.baseMaterial for subs in curmat.materialList do if subs != undefined do cgRenderProceduralTextures subs ) --SHELLAC MATERIAL (SUPPORTS BASE AND SHELLAC MATERIAL) Shellac: ( if curmat.Base_Material != undefined do cgRenderProceduralTextures curmat.Base_Material if curmat.Shellac_Material != undefined do cgRenderProceduralTextures curmat.Shellac_Material ) ) ) ------------------------------------------------------------------ ----- BUILD INTERFACE --------------------------------- ------------------------------------------------------------------ rollout cgRPT_main "Main..." rolledup:false ( group "Basic Settings" ( label lbl_Size "Output Map Size: " align:#left across:2 spinner spin_Size "" range:[0,4096,1024] type:#integer scale:32 button btn_Size1 "256" width:50 across:5 button btn_Size2 "512" width:50 button btn_Size3 "1024" width:50 button btn_Size4 "2048" width:50 button btn_Size5 "4096" width:50 label lbl_Path "Output Folder: " align:#left button btn_Path "C:\\" width:235 align:#left ) group "Operate On: " ( radiobuttons radioOutputWhat labels:#("ALL Materials", "Selected Obj Materials") columns:1 align:#left ) group "Render Procedurals..." ( button btn_Go "GO" width:235 height:50 progressbar go_prog color:blue ) ------------------------------------------------------------------ ----- ROLLOUT UI BEHAVIORS --------------------------------------- ------------------------------------------------------------------ --When user changes resolution on btn_Size1 pressed do cgUpdateSize 256 --calls function which updates size global + UI on btn_Size2 pressed do cgUpdateSize 512 on btn_Size3 pressed do cgUpdateSize 1024 on btn_Size4 pressed do cgUpdateSize 2048 on btn_Size5 pressed do cgUpdateSize 4096 on spin_Size entered do cgUpdateSize spin_Size.value --When user changes path on btn_Path pressed do ( fpath = getSavePath caption: "Select folder to output rendered maps" initialDir:cgRPTpath if fpath != undefined then ( cgRPTpath = fpath btn_Path.caption = fpath ) ) --When user presses big ol "GO" button on btn_Go pressed do ( undo "Render Procedural Textures" on ( count = 0 --intialize progress bar counter case radioOutputWhat.state of ( 1: --OUTPUT ALL SCENE MATERIALS for i in scenematerials do --loop through all materials ( go_prog.value = 100.*count/scenematerials.count --update progressbar cgRenderProceduralTextures i --render material count+=1 --update count ) 2: --OUTPUT SELECTED OBJECT MATERIALS ONLY for i in selection do --loop through selected object ( go_prog.value = 100.*count/scenematerials.count --update progressbar cgRenderProceduralTextures i.material --render selected obj material count+=1 --update count ) ) go_prog.value=0 --reset progress bar to zero ) ) ) rollout cgRPT_proc "Select Textures to Export" rolledup:true ( checkbox chk_Bitmaps "Include Bitmaps (for baking transform / crop)" checked:FALSE label lbl_note "UNFINISHED. SHOWS COMPATIBLE MAPS ONLY." MultiListBox mlb_Textures "Maps:" items:cgCompatibleTexMapsstrings on chk_Bitmaps changed theState do ( cgRPTbitmaps = chk_Bitmaps.checked ) ) rollout cgRPT_about "About..." rolledup:true ( label lbl_name "Christopher Grant" label lbl_date "7.06.2006" hyperLink hl_web2 "3D Portfolio: christophergrant.com" address:"http://www.christophergrant.com" visitedColor: (color 200 200 200) align:#center hyperLink hl_email "Email: chris@christophergrant.com" address:"mailto:chris@christophergrant.com" visitedColor: (color 200 200 200) align:#center ) ------------------------------------------------------------------ ----- CREATE FLOATER ---------------------------------- ------------------------------------------------------------------ if cgRPT_floater != undefined do closerolloutfloater cgRPT_floater cgRPT_floater = newRolloutFloater "Procedural Texture Baker" 275 440 addRollout cgRPT_main cgRPT_floater addRollout cgRPT_proc cgRPT_floater addRollout cgRPT_about cgRPT_floater )