01
06


해당 글은 PolyCount의 Monster님의 스크립트를 사용함.


http://polycount.com/discussion/131349/maxscript-gradient-map



1. 여러오브젝트를 선택해서 실행하면 각자의 오브젝트마다 생성하기 때문에, UV 셋 단위로 Attach 시켜서 사용하길 권장함.

2. middle 컬러를 약간 더 어둡게 하는게 더 나은 결과를 얻을 수 있음.

3. 컬러 옆에있는 슬라이더는 위로올리면 위쪽 컬러가 적게, 아래쪽 컬러가 넓게 나타난다.

    (개인적으로 1~2 눈금정도 올려서 사용)

4. 기본컬러도 좋지만, 색 베리에이션을 위해 HSV 43, 134, 252 / 119, 151, 116 / 151, 159, 32 를 사용하면 독특한 색감을 만들어 낼 수 있다.




( --SCRIPT THAT CREATES A GRADIENT BITMAP ON A MODEL FROM TOP TO BOTTOM rollout monsterGradientRollout "Gradient Map Tool" ( --SAVES ALL CONTROLS TO AN INI fn SaveControlSettings thisRol thisINI = ( for c in thisRol.controls do ( case classof c of ( SpinnerControl : setINISetting thisINI thisRol.name c.name (c.value as string) EditTextControl : setINISetting thisINI thisRol.name c.name c.text CheckboxControl : setINISetting thisINI thisRol.name c.name (c.checked as string) ComboBoxControl : setINISetting thisINI thisRol.name c.name (c.selection as string) ColorPickerControl : setINISetting thisINI thisRol.name c.name (c.color as string) ) ) ) --LOADS ALL CONTROLS FROM AN INI fn LoadControlSettings thisRol thisINI = ( if doesFileExist thisINI do ( for c in thisRol.controls do ( if classof c != GroupStartControl and classof c != GroupEndControl do ( local controlValue = getINISetting thisINI thisRol.name c.name if controlValue != "" and controlValue != undefined do ( case classof c of ( SpinnerControl : c.value = controlValue as number EditTextControl : c.text = controlValue CheckboxControl : c.checked = controlValue as BooleanClass ComboBoxControl : c.selection = controlValue as number ColorPickerControl : c.color = execute (controlValue) ) ) ) ) ) ) group "Render Options" ( spinner spnX "Width" range:[32,8192,1024] type:#integer align:#right spinner spnY "Height" range:[32,8192,1024] type:#integer align:#right spinner spnPadding "Padding" range:[0,32,4] type:#integer align:#right spinner spnChannel "UV Channel" range:[1,99,1] type:#integer align:#right colorPicker colBackground "Background" color:(color 0 0 0) align:#right checkbox chkHack "Use Wide Texture Hack?" checked:true align:#right ) group "Gradient Colors" ( colorPicker colGradient3 "Top" color:(color 255 255 255) align:#right colorPicker colGradient2 "Middle" color:(color 128 128 128) align:#right colorPicker colGradient1 "Bottom" color:(color 0 0 0) align:#right slider sldCol2Pos "" range:[0.0,1.0,0.5] type:#float orient:#vertical offset:[-40,-80] ) group "Output" ( checkbox chkDisplay "Open After Render?" checked:true align:#left label lblOutput "Output to..." align:#left editText edtOutputPath "" text:"$temp\\" readOnly:true width:148 align:#center button btnOutputPath "Browse..." width:65 align:#center across:2 button btnOutputTemp "Reset" width:65 align:#center ) button btnRender "Render Gradient Map" width:148 height:32 on monsterGradientRollout open do ( clearlistener() LoadControlSettings monsterGradientRollout "$temp/monsterGradientRollout.ini" ) on sldCol2Pos rightClick do ( sldCol2Pos.value = 0.5 ) on monsterGradientRollout close do ( SaveControlSettings monsterGradientRollout "$temp/monsterGradientRollout.ini" ) on btnOutputTemp pressed do ( edtOutputPath.text = "$temp\\" chkHack.checked = true spnChannel.value = 1 spnPadding.value = 4 spnX.value = 1024 spnY.value = 1024 colBackground.color = (color 0 0 0) colGradient3.color = (color 255 255 255) colGradient2.color = (color 128 128 128) colGradient1.color = (color 0 0 0) ) on btnOutputPath pressed do ( outPath = getSavePath caption:"Render Files To..." initialDir:maxfilepath if outPath != undefined do ( edtOutputPath.text = outPath + "\\" ) ) on btnRender pressed do ( proceed = true --COLLECT OBJECTS WITH NO UV CHANNELS ON THE TARGET CHANNEL noMapObjs = for obj in selection where (meshop.getNumMaps obj.mesh) - 1 < spnChannel.value collect obj.name --STOP THE PROCESS IF ANY INVALID CHANNELS ARE PRESENT if noMapObjs.count != 0 do ( proceed = false str = "The specified mapping channel doesn't exist on objects:\n" for o in noMapObjs do ( str += (o + "\n") ) messageBox str title:"No Mapping Channel" ) --STOP THE PROCESS IF NOTHING IS SELECTED if selection.count == 0 do ( proceed = false ) --CONTINUE WITH REDRAW OFF if proceed do with redraw off ( max create mode max hold clearlistener() outPath = edtOutputPath.text --SAVE THIS SETTING AND ENABLE IT TO ALLOW CANCELING saveEscape = escapeEnable escapeEnable = true --SETUP THE SCENE unhide objects dolayer:true hide objects unhide selection --FIX POSSIBLE ERRORS resetxform selection collapsestack selection selection.backfacecull = on --CREATE A MATERIAL AND A GRADIENT ON IT'S DIFFUSE newMaterial = StandardMaterial() newMaterial.selfIllumAmount = 100 gradientMap = gradient() newMaterial.diffuseMap = gradientMap gradientMap.coords.U_angle = 90 gradientMap.coords.mappingType = 0 gradientMap.coords.mapping = 2 gradientMap.color1 = colGradient1.color gradientMap.color2 = colGradient2.color gradientMap.color3 = colGradient3.color gradientMap.color2Pos = 1 - sldCol2Pos.value --HACK TO FIX TEXTURES WIDE NOT RENDERING PROPERLY if spnX.value > spnY.value and chkHack.checked do ( tileAmount = spnX.value as float / spnY.value as float vTile = (spnY.value as float / spnX.value as float) vOffset = vTile / 2.0 xFormMod = uvw_xform() xFormMod.V_Tile = vTile xFormMod.V_Offset = 1.0 - vTile addModifier selection xFormMod ) --APPLY MATERIAL TO SELECTION selection.material = newMaterial --SET UP THE RENDER renderers.current = Default_Scanline_Renderer() backgroundColor = colBackground.color ambientColor = color 255 255 255 for obj in selection do ( obj.removeAllBakeElements() --DELETE THE FILE IF IT EXISTS gMapName = (outPath + obj.name + "_gr.tga") deleteFile gMapName --CREATE THE DIFFUSE BAKE ELEMENT difElement = DiffuseMap() difElement.enabled = true difElement.filenameUnique = false difElement.fileType = gMapName difElement.lightingOn = false difElement.shadowsOn = false difElement.filterOn = true difElement.outputSzX = spnX.value difElement.outputSzY = spnY.value --SETUP THE OBJ FOR BAKING bobj = obj.INodeBakeProperties bobj.addBakeElement difElement bobj.bakeEnabled = true bobj.bakeChannel = spnChannel.value bobj.nDilations = spnPadding.value --TURN OFF PROJECTION MAPPING obj.INodeBakeProjProperties.enabled = false ) render renderType:#bakeSelected frame:#current vfb:off progressBar:true outputwidth:spnX.value outputheight:spnY.value outputSize:[spnX.value,spnY.value] --COLLECT MAPS FOR DISPLAY bmpList = for obj in selection collect obj.name --RESTORE THE ESCAPE SETTING AND RELOAD THE FILE escapeEnable = saveEscape fetchmaxfile quiet:true --DISPLAY ALL RENDERED MAPS if chkDisplay.checked do ( --TRY TO RELOAD THE TEXTURES FROM DISK freescenebitmaps() gc() for obj in bmpList do ( local bmpGradient = openbitmap (outPath + obj + "_gr.tga") if bmpGradient != undefined do ( --ROUND ABOUT WAY OF FORCING A RELOAD ON THE BMP bmpTex = bitmaptexture bitmap:bmpGradient bmpTex.reload() display bmpGradient ) ) ) ) forcecompleteredraw() ) ) createDialog monsterGradientRollout 

)


COMMENT