目的
Photoshopで異なる複数のテクスチャから、 目的のDDSを書き出すEF-12より、この辺りの作業です
ツール
・Windows (Nvidiaのツールが動くのがWIndowsなので)・Photoshop CS5(スクリプトが使えれば多分OK) ・Photoshop Plugin Nvidia DDS PluginであるNvidiaのDDSツールもスクリプトから制御出来ました。 超便利。コレだけでも調査したかいがあった〜
素材
以下のテクスチャ素材 そのままDDSに書き出す素材 ・_d デカール ・_n ノーマル Dentに合成するテクスチャ ・_h 高さ ・_ao 遮蔽 Glossに合成するテクスチャ ・_s 輝度 ・_pow 硬度 です。ちょっとここらアタリ、調査不足でしたので命名規則は適当です orz流れ
画面の開発環境はCS6です、実行はCS5でした :p
Photoshopで以上の6種類のテクスチャを開きます。 で、こういった順で処理をします。 _dnttテクスチャの作成 _h > dnt の Rチャンネルに _ao > dnt のBチャンネルに _dnt > DDS(DTX5_NM形式) で保存 _glossテクスチャの作成 _s >glossのRチャンネルに _pow > glossのBチャンネルに _gloss > DDS(DTX5_NM形式) で保存 _d > DDS(可変あり) で保存 _n > DDS(DTX5_NM形式) で保存 です。計6種類のテクスチャを
4種のDDSテクスチャにまとめ書き出しました
Photoshop Script
そのコードです 1日で作った付け焼き刃ですので、 エラー処理など、効率化などはしておりません サンプルとして見てください//mergeTex //20120831 savedds //EF12用にカスタム debug = true // 初期設定=========================================================== ex1 = ["dnt","h","ao","",""] ex2 = ["gloss","s","pow","",""] strDeffuse = "d" strNormal = "n" DXT1_RGB = 0; DXT1_RGBA_1Bit = 1; DXT5_RGBA = 3; DXT5_NM = 24; closeNewDoc = true; function log(in_data){ if (debug ) alert(in_data) } //SAVEDDS ======================================================= function saveDDS(in_path,in_ddsType){ var idsave = charIDToTypeID( "save" ); var desc14 = new ActionDescriptor(); var idAs = charIDToTypeID( "As " ); var desc15 = new ActionDescriptor(); var idbarF = charIDToTypeID( "barF" ); desc15.putBoolean( idbarF, true ); var idfdev = charIDToTypeID( "fdev" ); desc15.putDouble( idfdev, 3.000000 ); var idfbia = charIDToTypeID( "fbia" ); desc15.putDouble( idfbia, 0.000000 ); var idurad = charIDToTypeID( "urad" ); desc15.putDouble( idurad, 5.000000 ); var iduamo = charIDToTypeID( "uamo" ); desc15.putDouble( iduamo, 0.500000 ); var iduthr = charIDToTypeID( "uthr" ); desc15.putDouble( iduthr, 0.000000 ); var idxstf = charIDToTypeID( "xstf" ); desc15.putDouble( idxstf, 1.000000 ); var idxthf = charIDToTypeID( "xthf" ); desc15.putDouble( idxthf, 1.000000 ); var idqual = charIDToTypeID( "qual" ); desc15.putInteger( idqual, 71 ); var iderdi = charIDToTypeID( "erdi" ); desc15.putBoolean( iderdi, false ); var iderdw = charIDToTypeID( "erdw" ); desc15.putInteger( iderdw, 1 ); var idusfa = charIDToTypeID( "usfa" ); desc15.putBoolean( idusfa, false ); var idtxfm = charIDToTypeID( "txfm" ); desc15.putInteger( idtxfm, in_ddsType );//ddsType var idweig = charIDToTypeID( "weig" ); desc15.putInteger( idweig, 0 ); var idtmty = charIDToTypeID( "tmty" ); desc15.putInteger( idtmty, 0 ); var idmmty = charIDToTypeID( "mmty" ); desc15.putInteger( idmmty, 32 ); var idsmip = charIDToTypeID( "smip" ); desc15.putInteger( idsmip, 0 ); var idbina = charIDToTypeID( "bina" ); desc15.putBoolean( idbina, false ); var idprem = charIDToTypeID( "prem" ); desc15.putBoolean( idprem, false ); var idfilm = charIDToTypeID( "film" ); desc15.putBoolean( idfilm, false ); var idalpb = charIDToTypeID( "alpb" ); desc15.putBoolean( idalpb, false ); var idbord = charIDToTypeID( "bord" ); desc15.putBoolean( idbord, false ); var idbrdr = charIDToTypeID( "brdr" ); desc15.putDouble( idbrdr, 0.000000 ); var idbrdg = charIDToTypeID( "brdg" ); desc15.putDouble( idbrdg, 0.000000 ); var idbrdb = charIDToTypeID( "brdb" ); desc15.putDouble( idbrdb, 0.000000 ); var idmmft = charIDToTypeID( "mmft" ); desc15.putInteger( idmmft, 2 ); var idfdcl = charIDToTypeID( "fdcl" ); desc15.putBoolean( idfdcl, false ); var idfdaf = charIDToTypeID( "fdaf" ); desc15.putBoolean( idfdaf, false ); var idftworl = charIDToTypeID( "f2rl" ); desc15.putDouble( idftworl, 0.500000 ); var idftwogl = charIDToTypeID( "f2gl" ); desc15.putDouble( idftwogl, 0.500000 ); var idftwobl = charIDToTypeID( "f2bl" ); desc15.putDouble( idftwobl, 0.500000 ); var idftwoal = charIDToTypeID( "f2al" ); desc15.putDouble( idftwoal, 0.500000 ); var idfddl = charIDToTypeID( "fddl" ); desc15.putInteger( idfddl, 0 ); var idfafm = charIDToTypeID( "fafm" ); desc15.putDouble( idfafm, 0.150000 ); var idbafh = charIDToTypeID( "bafh" ); desc15.putDouble( idbafh, 0.500000 ); var iddthc = charIDToTypeID( "dthc" ); desc15.putBoolean( iddthc, false ); var iddthzero = charIDToTypeID( "dth0" ); desc15.putBoolean( iddthzero, false ); var idsmth = charIDToTypeID( "smth" ); desc15.putInteger( idsmth, 0 ); var idfilg = charIDToTypeID( "filg" ); desc15.putDouble( idfilg, 2.200000 ); var idfieg = charIDToTypeID( "fieg" ); desc15.putBoolean( idfieg, false ); var idfilw = charIDToTypeID( "filw" ); desc15.putDouble( idfilw, 10.000000 ); var idover = charIDToTypeID( "over" ); desc15.putBoolean( idover, false ); var idfblr = charIDToTypeID( "fblr" ); desc15.putDouble( idfblr, 1.000000 ); var idnmcv = charIDToTypeID( "nmcv" ); desc15.putBoolean( idnmcv, false ); var idncnv = charIDToTypeID( "ncnv" ); desc15.putInteger( idncnv, 1009 ); var idnflt = charIDToTypeID( "nflt" ); desc15.putInteger( idnflt, 1040 ); var idnmal = charIDToTypeID( "nmal" ); desc15.putInteger( idnmal, 1033 ); var idnmbr = charIDToTypeID( "nmbr" ); desc15.putBoolean( idnmbr, false ); var idnmix = charIDToTypeID( "nmix" ); desc15.putBoolean( idnmix, false ); var idnmiy = charIDToTypeID( "nmiy" ); desc15.putBoolean( idnmiy, false ); var idnmiz = charIDToTypeID( "nmiz" ); desc15.putBoolean( idnmiz, false ); var idnmah = charIDToTypeID( "nmah" ); desc15.putBoolean( idnmah, true ); var idnswp = charIDToTypeID( "nswp" ); desc15.putBoolean( idnswp, false ); var idnmsc = charIDToTypeID( "nmsc" ); desc15.putDouble( idnmsc, 4.000000 ); var idnmnz = charIDToTypeID( "nmnz" ); desc15.putInteger( idnmnz, 0 ); var idusbi = charIDToTypeID( "usbi" ); desc15.putBoolean( idusbi, false ); var idlien = charIDToTypeID( "lien" ); desc15.putBoolean( idlien, false ); var idshdi = charIDToTypeID( "shdi" ); desc15.putBoolean( idshdi, false ); var idshfi = charIDToTypeID( "shfi" ); desc15.putBoolean( idshfi, false ); var idshmm = charIDToTypeID( "shmm" ); desc15.putBoolean( idshmm, true ); var idshan = charIDToTypeID( "shan" ); desc15.putBoolean( idshan, true ); var idclrc = charIDToTypeID( "clrc" ); desc15.putInteger( idclrc, 0 ); var idvdxone = charIDToTypeID( "vdx1" ); desc15.putBoolean( idvdxone, true ); var idvdxtwo = charIDToTypeID( "vdx2" ); desc15.putBoolean( idvdxtwo, true ); var idvdxthree = charIDToTypeID( "vdx3" ); desc15.putBoolean( idvdxthree, true ); var idvdxfive = charIDToTypeID( "vdx5" ); desc15.putBoolean( idvdxfive, true ); var idvfourfourfour = charIDToTypeID( "v444" ); desc15.putBoolean( idvfourfourfour, true ); var idvfivefivefive = charIDToTypeID( "v555" ); desc15.putBoolean( idvfivefivefive, true ); var idvfivesixfive = charIDToTypeID( "v565" ); desc15.putBoolean( idvfivesixfive, true ); var idveighteighteight = charIDToTypeID( "v888" ); desc15.putBoolean( idveighteighteight, true ); var idalph = charIDToTypeID( "alph" ); desc15.putBoolean( idalph, false ); var idusra = charIDToTypeID( "usra" ); desc15.putBoolean( idusra, false ); var idusfs = charIDToTypeID( "usfs" ); desc15.putInteger( idusfs, 0 ); var idprev = charIDToTypeID( "prev" ); desc15.putBoolean( idprev, false ); var idrdep = charIDToTypeID( "rdep" ); desc15.putInteger( idrdep, 3000 ); var idlomm = charIDToTypeID( "lomm" ); desc15.putBoolean( idlomm, false ); var idsflp = charIDToTypeID( "sflp" ); desc15.putBoolean( idsflp, false ); var idlflp = charIDToTypeID( "lflp" ); desc15.putBoolean( idlflp, false ); var idscar = charIDToTypeID( "scar" ); desc15.putDouble( idscar, 1.000000 ); var idscag = charIDToTypeID( "scag" ); desc15.putDouble( idscag, 1.000000 ); var idscab = charIDToTypeID( "scab" ); desc15.putDouble( idscab, 1.000000 ); var idscaa = charIDToTypeID( "scaa" ); desc15.putDouble( idscaa, 1.000000 ); var idbiar = charIDToTypeID( "biar" ); desc15.putDouble( idbiar, 0.000000 ); var idbiag = charIDToTypeID( "biag" ); desc15.putDouble( idbiag, 0.000000 ); var idbiab = charIDToTypeID( "biab" ); desc15.putDouble( idbiab, 0.000000 ); var idbiaa = charIDToTypeID( "biaa" ); desc15.putDouble( idbiaa, 0.000000 ); var idsiar = charIDToTypeID( "siar" ); desc15.putDouble( idsiar, 1.000000 ); var idsiag = charIDToTypeID( "siag" ); desc15.putDouble( idsiag, 1.000000 ); var idsiab = charIDToTypeID( "siab" ); desc15.putDouble( idsiab, 1.000000 ); var idsiaa = charIDToTypeID( "siaa" ); desc15.putDouble( idsiaa, 1.000000 ); var idbiir = charIDToTypeID( "biir" ); desc15.putDouble( idbiir, 0.000000 ); var idbiig = charIDToTypeID( "biig" ); desc15.putDouble( idbiig, 0.000000 ); var idbiib = charIDToTypeID( "biib" ); desc15.putDouble( idbiib, 0.000000 ); var idbiia = charIDToTypeID( "biia" ); desc15.putDouble( idbiia, 0.000000 ); var idoutw = charIDToTypeID( "outw" ); desc15.putBoolean( idoutw, false ); var idclcL = charIDToTypeID( "clcL" ); desc15.putBoolean( idclcL, true ); var idNVIDIADthreeD_DDS = stringIDToTypeID( "NVIDIA D3D/DDS" ); desc14.putObject( idAs, idNVIDIADthreeD_DDS, desc15 ); var idIn = charIDToTypeID( "In " ); desc14.putPath( idIn, new File( in_path ) ); executeAction( idsave, desc14, DialogModes.NO ); } // メモ=========================================================== function folderserch(in_folderPath,aTex,bTex){ } function OpneFile(){ filename = "Macintosh HD:ps_text:headline.txt"; fileObj = new File(filename); flag = fileObj.open("r"); if (flag == true) { alert("ファイルを開きました"); fileObj.close(); }else{ alert("ファイルが開けませんでした"); } } // チャンネルの移動=========================================================== function moveChannel(sDoc, tDoc, tChan) { app.activeDocument = sDoc //ソースのドキュメントの複製 dupDoc = activeDocument.duplicate(); //log(dupDoc.name) //統合 dupDoc.flatten(); //グレースケール dupDoc.changeMode(ChangeMode.GRAYSCALE); //コピー dupDoc.selection.selectAll(); dupDoc.activeLayer.copy(); //閉じる dupDoc.close(SaveOptions.DONOTSAVECHANGES); //移動 //ターゲットをアクティブドキュメントに app.activeDocument = tDoc //チャンネルを指定 if(tChan == "r") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Red=Red'))] else if(tChan == "g") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Green=Green'))] else if(tChan == "b") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Blue=Blue'))] else if(tChan == "a") { activeDocument.channels.add() } //app.activeDocument.activeChannels = activeDocument.channels.length - 1 //ペースト activeDocument.paste() return true } // ターゲドキュメント作成=========================================================== function createTragetDoc(in_name) { preferences.rulerUnits = Units.PIXELS; w = activeDocument.width.value; h = activeDocument.height.value; tagetDoc = documents.add(w,h,72,in_name); return tagetDoc; } // ソースファイルの取得=========================================================== function getSorceDoc(in_name){ docs = documents; for ( var i = 0; i < docs.length; i++){ var dName = docs[i].name dName = dName.substring( 0, dName.lastIndexOf(".") ); if( dName == in_name){ return docs[i] } } return false } // マージのメイン関数=========================================================== function merge(base,r,g,b,a,outname,fPath){ //最初にドキュメントを作成する var newDocName = base + "_" + outname var targetDoc = createTragetDoc(newDocName) var sorceDoc = false //r を移動 if ( r != ""){ sorceName = base + "_" + r; sorceDoc = getSorceDoc(sorceName); if ( sorceDoc ){ moveChannel(sorceDoc,targetDoc,"r") } } //g を移動 if ( g != ""){ sorceName = base + "_" + g; sorceDoc = getSorceDoc(sorceName); if ( sorceDoc ){ moveChannel(sorceDoc,targetDoc,"g") } } //b を移動 if ( b != ""){ sorceName = base + "_" + b; sorceDoc = getSorceDoc(sorceName); if ( sorceDoc ){ moveChannel(sorceDoc,targetDoc,"b") } } //a を移動 if ( a != ""){ sorceName = base + "_" + a; sorceDoc = getSorceDoc(sorceName); if ( sorceDoc ){ moveChannel(sorceDoc,targetDoc,"a") } } //savedds savePath = fPath + "\\" + base + "_" + outname + ".dds"; //log(savePath) if ( a == "" && b == ""){ saveDDS(savePath,DXT5_NM); } else if (a == "") { saveDDS(savePath,DXT1_RGB); } else { svaDDS(savePath,DXT5_RGBA); } //ddsを閉じる if(closeNewDoc) activeDocument.close(); return true } // sorce2ddsSave dds保存=========================================================== function sorce2ddsSave(baseName, dds,in_prefix, fPath){ targetName = baseName + "_" + in_prefix; sorceDoc = getSorceDoc(targetName); if(sorceDoc == false) return; //アクティブドキュメントの変更(おまじない) app.activeDocument = sorceDoc; //ddsのチェック ddsType = 3 if(String(dds) == "DXT1_RGB") ddsType = DXT1_RGB; if(String(dds) == "DXT1_RGBA_1Bit") ddsType = DXT1_RGBA_1Bit; if(String(dds) == "DXT5_RGBA") ddsType = DXT5_RGBA; if(String(dds) == "DXT5_NM") ddsType = DXT5_NM; //log(ddsType) //複製 dupDoc = activeDocument.duplicate() //保存 savePath = fPath + "\\" + targetName + ".dds"; saveDDS(savePath,ddsType) //ddsを閉じる if(closeNewDoc) activeDocument.close(); return true } // メイン=========================================================== function main(){ if (app.documents.length ==0){ alert("Cancel No Docment") return; //ドキュメントが開かれていない場合処理なし } try { fPath = activeDocument.path } catch ( e ) { alert("pleas saveDocments"); return } dName = activeDocument.name dName = dName.substring( 0, dName.lastIndexOf(".") ); dName = dName.substring( 0, dName.lastIndexOf("_") ); uDlg = new Window('dialog','サンプル',[200,100,580,380]); uDlg.sText = uDlg.add("statictext",[10,10,275,10+45], "BaseName"); uDlg.eText = uDlg.add("edittext",[100,10,275,10+20], dName); uDlg.cBox1 = uDlg.add("checkbox",[10,50,275,50+25], "Merge 1"); uDlg.r1 = uDlg.add("edittext",[020,80,020+30,080+20], ex1[1]); uDlg.g1 = uDlg.add("edittext",[070,80,070+30,080+20], ex1[2]); uDlg.b1 = uDlg.add("edittext",[120,80,120+30,080+20], ex1[3]); uDlg.a1 = uDlg.add("edittext",[170,80,170+30,080+20], ex1[4]); uDlg.out1 = uDlg.add("edittext",[220,80,220+60,080+20], ex1[0]); uDlg.cBox2 = uDlg.add("checkbox",[10,120,275,120+25], "Merge 2"); uDlg.r2 = uDlg.add("edittext",[020,150,020+30,150+20], ex2[1]); uDlg.g2 = uDlg.add("edittext",[070,150,070+30,150+20], ex2[2]); uDlg.b2 = uDlg.add("edittext",[120,150,120+30,150+20], ex2[3]); uDlg.a2 = uDlg.add("edittext",[170,150,170+30,150+20], ex2[4]); uDlg.out2 = uDlg.add("edittext",[220,150,220+60,150+20],ex2[0]); uDlg.cBox3 = uDlg.add("checkbox",[10,180,100,180+25], "ddsSave"); uDlg.deffuse = uDlg.add("edittext",[80,180,80+30,180+20], strDeffuse); uDlg.dList3 = uDlg.add("dropdownlist",[130,180,130+200,180+25],["DXT1_RGB","DXT1_RGBA_1Bit","DXT5_RGBA","DXT5_NM"]); uDlg.dList3.selection = 0; uDlg.cBox4 = uDlg.add("checkbox",[10,210,100,210+25], "ddsSave"); uDlg.normal = uDlg.add("edittext",[80,210,80+30,210+20], strNormal); uDlg.dList4 = uDlg.add("dropdownlist",[130,210,130+200,210+25],["DXT1_RGB","DXT1_RGBA_1Bit","DXT5_RGBA","DXT5_NM"]); uDlg.dList4.selection = 3 uDlg.okBtn = uDlg.add("button",[220,240,320,240+25], "Create", { name:"ok"}); //ボタンを押されたときの設定 //view_1 uDlg.okBtn.onClick = function (){ if(uDlg.cBox1.value) merge(uDlg.eText.text,uDlg.r1.text, uDlg.g1.text, uDlg.b1.text, uDlg.a1.text, uDlg.out1.text,fPath); if(uDlg.cBox2.value) merge(uDlg.eText.text,uDlg.r2.text, uDlg.g2.text, uDlg.b2.text, uDlg.a2.text, uDlg.out2.text,fPath); if(uDlg.cBox3.value) sorce2ddsSave(uDlg.eText.text, uDlg.dList3.selection, uDlg.deffuse.text, fPath); if(uDlg.cBox4.value) sorce2ddsSave(uDlg.eText.text, uDlg.dList4.selection, uDlg.normal.text, fPath); refresh(); uDlg.close() alert("Finish") } uDlg.show(); } main()これで、テクスチャの作業に集中出来ます。 といっても、PSD1枚からの必要テクスチャの書き出しが必要かもしれませんが(w
まとめ
で、完成したのが9/1でコンテスト提出日の早朝でした :pアフォすぎる w
まあ、とりあえずコンテストに応募しました :p
背景ですので、競合は少ないと思いますがw
一番開発に必要なのは
スケジューリングでしたとさw
追記
3D人さんから教わったんだけど。こんな便利なツールが・・・。
QSM
Quick Save Maps v0.6.4 日本語版 - 勝手に制作!Photoshopにて複数テクスチャを手軽に書き出せる拡張ツール
もうコレで良いよね orz
情報を制したものが強い :p ってことでした。 コード参考にしよう orz
0 件のコメント:
コメントを投稿