ゆっくりとひねり出すブログ

かなりスローペースで何かを書いていきます。

お茶にごしスクリプト

mayaのこつぶスクリプト置いておくよ。

import maya.cmds as cmds
def setWinPos(w,h):
	for i in cmds.lsUI(wnd=1)[1:-1]:
		cmds.window(i,e=1,tlc=(w,h))

#========================================
# 画面外にウィンドウにあるとき、指定位置に移動させる。
# setWinPos(0,0)
#========================================

import maya.cmds as cmds
import os,datetime
def showScnTimeInTitleBar():
	title = cmds.window('MayaWindow',q=1,t=1)
	currentFile = cmds.file(sceneName=1,q=1)
	dt = os.stat(currentFile).st_mtime
	timeTmp = str(datetime.datetime.fromtimestamp(dt)).split(":")
	time = (":".join([timeTmp[0],timeTmp[1]]).replace("-","/"))
	if not title[-16:] == time:
		cmds.window('MayaWindow',e=1,t= title +"   "+ time)

#=================================================
# 実行するとタイトルバーにシーンファイルの更新時刻が追記される
# showScnTimeInTitleBar()
#=================================================

別に大したものじゃないけどね。

エフェクト?メイキング(後編)

今回ばかりは、とある作品がすごすぎて
まさか最優秀は頂けるとは思っていませんでしたので驚きました。。
色々と配慮いただいた結果でしょうけど、お心遣いに感謝です。
 
ゲームエフェクトコンテスト 結果発表の様子はこちらです。
 
受賞コメントがかなり軽過ぎでごめんなさい。。
キチガイで賞 くらいだと思ってたので。

 

エフェクトを見た何名かの方から

一体どうなってんの? というコメントを頂きました。  

発想の話は前回の記事に書いてますので、
今回はデータ作りをどうようにやっているのかについて
記念に書き留めておきます。
 
僕はそれほどエフェクトデザイナーとしてのキャリアがあるわけではないので、
これが正解だとか、為になるようなことは書けませんが、
こんなもんかくらいに見てもらえたらと。
 
(書き終えてみたらほとんど反省文になってました)
 
ラフで検討
まず、最初に思いついたカットである、振り向きざまに敵を一掃するカット。
これの色味とか形を帰りの電車の中でiPhoneお絵描きしてます。
 
 
BrushesXPというアプリをつかってました。
Elena Kolchina「Brushes XP
 
 
ざっくり画を決めたらあとは作りながら考えます。 
とはいえ、ある程度のデータ構成はこの時点でイメージしてます。
 
 
例えば、
帯の部分はポリゴンを生成するトレイル系の機能はフリップした部分が細くなったりしやすいので筒状ポリゴンのUVスクロールでいこう、とか。
 

f:id:sayjing:20150320024641j:plain

 
あとはテクスチャ2をマスクとして使って徐々に表示させればいけるだろうとか。
 
データを作りだす前に考えちゃってます。
 
データの作り方を画作り段階でイメージすると
データ作成は迷わなくてラクだと思いますがそれは仕事です。。
面白い表現とかレベルアップはしにくいかも。
「この表現したいから素材作るためにhoudini勉強しよう」とかが理想です。よね。
 
ってか、ああーもう少し輪郭が目立たないようにすればよかったなぁ
10分くらい調整して出力し直せば大分マシなったのになぁ後悔。
 
キャラ
前回は温泉でBGらしいものは作りましたし
某エフェクト作画の巨匠
「エフェクトはキャラクターだ」
今度はBISHAMONでキャラを作れと神は仰っている。
 
後半に登場する女の人は
ゼルダ スカイウォードソードのファイ(青い精霊)のような精神体をイメージ。
 
ポリゴンモデルで表現するのは
BISHAMON上でのライティング調整ができない(と思います)ので
板ポリズムにテクスチャを貼る方法にしてみる。
 

f:id:sayjing:20150319065143j:plain

 
Sculptrisでコネコネし、パーツ分けしてテクスチャにしてます。
もうちょっと資料とか見て作ればよかったぁ 崩れすぎ
 
 
ただ、最後のカットは目から粒子を出したかったので、
どう頭をひねっても頭部モデルは必要でした。
 
ZBrushのZremesherでサクッと自動リトポしてます。
 
BISHAMON上でライティングってどうなるんだろう。。
最悪ライトをテクスチャにベイクする必要があるなあとか考えてましたが

f:id:sayjing:20150320040849j:plain

あれ、まあいいかこれで!と。(素のポリ)

首の付け根に襟を足せばよかったなぁ、これはひどい

 
目の粒子はGPUパーティクルの制御がイマイチわからず、
かなり不思議なゴールモデルを使ってます。嗚呼
 
もうメイキングっていうか懺悔。
 
揺れもの
気を取り直して なびく髪の毛について。
テクスチャをモデルと逆回転させて相殺する昔ながら?の手法です。
 
1秒で1回転するならテクスチャの速度に1/60 (0.01666) を設定して、
テクスチャがその場にとどまっている状態にします。
 
次に、筒状のモデルをろくろのように回転させて確認しつつ
シルエットの揺れ具合を確認しながら法線方向に凸凹変形させます。

f:id:sayjing:20150320041823g:plain

一つだとすぐバレるので二層にしてます。
 
そういえばメタルギアソリッド3のヘイロー降下のときに服がたなびいてるのって
揺れ用の骨に薄くウェイト振って回転させてるんだろうか…
それともシェイプなのかな?
 
敵エフェクト
敵っぽいノイズエフェクトについて
 
ゼルダ トワイライトプリンセスの敵のブロックノイズエフェクトや、
電脳コイルのノイズっぽいイメージを出したかったんですが
デザインがイマイチ固まらず。
正直、今回から実装された歪み機能を使ってみたかっただけですね。
 
ブロックノイズだけだと有害な物質感が足りないので
maya Fluidで簡単な煙の連番を二種類ほど出力して
悪い物質から溢れ煙を足してみました。(強引
テクスチャ

f:id:sayjing:20150320041931g:plain

多分使ってないのもあるけど、すべての使用テクスチャです。

汎用性のあるテクスチャがほとんどないところに突貫工事感が出てますな。。

 

ファイナル

いきなり駆け足になりましたが、

 文章を考えるの苦手なのでちょっと疲れてきました。

ラストの2カットです。

 
縦に伸びるフレアを足したりガイナ的な集中線を追加したりして完成!
なんだか出来上がったものは最初に考えてたものとは別物になっちゃいました。
 
 って、書いてたら丁度トロフィーが届きました!!
 

f:id:sayjing:20150321131959j:plain

成 田 星 人 w
 
これは、、ずしりときますね。
ここまで書いてた記事の文体がラフすぎたので直しちゃうくらい恐縮です。
こんなの贈られてしまうと、背筋正しますよそりゃ。。
 
お! 
 
すでにコンテスト作品の高解像度ムービーがfacebookにアップされていました!

https://www.facebook.com/GameEffectContest

chiさんの和風スプラッシュ綺麗だなぁ。

ここまで読ませておいて申し訳ないんですが、

この記事を読むよりchiさんの作品を見る方がよっぽど勉強になります。

コマ送りで見ましょう!!

エフェクト?メイキング(前編)

コンテストに応募してみました。(参加は三回目)

マッチロック株式会社さまの開発するBISHAMON(http://www.matchlock.co.jp/products/

というゲームエフェクトツールを使用したエフェクトコンテスト。

 

今回は愛がテーマということだったので

ハートを使おうかなー

プリキュ⚪︎的な変身シーンにしようかなー

などと考えていたのだけど、たまたま夢を見たのでそのワンシーンから膨らませるかーとなり、寝起きに夢で見たワンシーンを書きとめた。

f:id:sayjing:20141230225509j:plain

なんかエフェクトコンテストなのにキャラがいる。。
 
かつて有名なエフェクト作画の巨匠がGDC
「エフェクトはキャラクターだ」とたしか仰っていた。
ひっくり返せば「キャラもエフェクトだ」と…言える!
 
大きく曲解してるかもしれないけど
納得したところでその他のカットも考えてみた。
 
f:id:sayjing:20150227160652j:plain
 
イメージとしては、落ち込む女の子の精神体みたいなものが悪い何かに襲われ
 
f:id:sayjing:20150225090226j:plain
そこに未来の自分か母か何かが格好良く助けに入る感じ。
 
f:id:sayjing:20150225090149j:plain
…エフェクトって単体で見せるよりは、ゲームやカットシーンに組み込んで見せた方が面白いとは思うんだけど、
これだとエフェクトコンテストなのにエフェクト以外の作業量が多過ぎるよね。あとで気付いた!
 
とりあえずカメラを決めるための最低限必要なオブジェクトを作成。
 
f:id:sayjing:20150110135736j:plain
 
特に尺の規定は設けてないようだったけれど、長くても10秒〜15秒と仰ってたのに19秒越えしてしまった。。
なので泣く泣く削って16秒に。
まだ超えてるやん
 
カメラアニメーションをほぼFixさせたら今度はカットごとにエフェクトの方向性を固めよう。
途中段階のスクリーンショットを撮っておいて仕事帰りの電車で親指レタッチ。
 
f:id:sayjing:20150225215055j:plain
ぬー、、とにかく色のせて誤魔化すぞ!
 
f:id:sayjing:20150225215613j:plain
アニメ的な効果線をパカパカさせて誤魔化す!
 
f:id:sayjing:20150225215633j:plain
ごちゃごちゃさせて誤魔化せー!
 
今思うと誤魔化すことばっかり考えてたな。。
せっかく自由に作っていいんだから、作りたいエフェクトだけ作ればよかった。
 
 
BISHAMONにはMayaからアニメーションを持ってくる機能はまだないようだった。
かといってエミッターのアニメーションを、ビュー上で操作できないBISHAMONでつけるのはなかなか大変そう。。
ためしにBISHAMONのシーンファイルをエディタで開いてみると綺麗なXMLではないか。
ということで直接書き込んでいく事にした。
 
MayaにてアニメーションをXMLの記述に書き換えるスクリプトを書いていて気付いたんだけど、
BISHAMONのアニメーションカーブの挙動がちょっとわからない。。
スプラインキーに設定されたウェイト(スロープ?)を垂直に近づけると値が8000くらいにまで上がる。
プログラム的には一般的なんだろうか?
カーディナルカーブってこういうもの?
疎いのでわからない。。
 
とりあえずMayaからウェイトの値までは正確に持ってこれなかった。
Mayaからのアニメーションエクスポートは素直に実装を待ちましょ。
 
 
そんなこんなで、ようやくエフェクトを作る下準備ができた。
後編へ続く(?)
 

maya->Bishamon アニメーションカーブ (突貫

"""
選択したオブジェクトのアニメーションカーブ情報をBISHAMONの記述に変換
"""
import math
import maya.cmds as cmds

min = cmds.playbackOptions(query=True,min=True)
max = cmds.playbackOptions(query=True,max=True)

selObj = cmds.ls(sl=True)
nodes = cmds.keyframe(selObj,query=True,name=True)

for node in nodes:
    keyTimes = cmds.keyframe(node,query=True,tc=True)
    values = cmds.keyframe(node,query=True,vc=True)
    intans = cmds.keyTangent(node,query=True,itt=True)
    intans = [w.replace('auto', 'Spline') for w in intans]
    intans = [w.replace('fixed', 'Linear') for w in intans]
    intans = [w.replace('linear', 'Linear') for w in intans]
    intans = [w.replace('spline', 'Spline') for w in intans]
    outtans = cmds.keyTangent(node,query=True,ott=True)
    inAngles = [round(x,8) for x in cmds.keyTangent(node,q=True,inAngle=True)]
    outAngles = [round(x,8) for x in cmds.keyTangent(node,q=True,outAngle=True)]
    if node.split("_")[1]=="translateX":
        txv = values
        intantx = intans
        inAngletx = inAngles
        outAngletx = outAngles
    elif node.split("_")[1]=="translateY":
        tyv = values
        intanty = intans
        inAnglety = inAngles
        outAnglety = outAngles
    elif node.split("_")[1]=="translateZ":
        tzv = values
        intantz = intans
        inAngletz = inAngles
        outAngletz = outAngles
    elif node.split("_")[1]=="rotateX":
        rxv = values
        intanrx = intans
        inAnglerx = inAngles
        outAnglerx = outAngles
    elif node.split("_")[1]=="rotateY":
        ryv = values
        intanry = intans
        inAnglery = inAngles
        outAnglerz = outAngles
    elif node.split("_")[1]=="rotateZ":
        rzv = values
        intanrz = intans
        inAnglerz = inAngles
        outAnglerz = outAngles

print"======= TRANSLATE ========"

for i in range(0,len(keyTimes)):
    print("<KeyframeVector3d Frame=\"" + str((keyTimes[i] - min) / (max - min)) + "\" ElementKeyframeType=\"" + intantx[i] +" " + intanty[i] + " " + intantz[i] + "\" ElementSlopeL=\"" + str(inAngletx[i]) + " " + str(inAnglety[i]) + " " + str(inAngletz[i]) + "\" ElementSlopeR=\"" + str(inAngletx[i]) + " " + str(inAnglety[i]) + " " + str(inAngletz[i]) + "\" KeyframeTpe=\"Constant\" SlopeL=\"0\" SlopeR=\"0\">")
    print(" <Value X=\""+ str(txv[i]) +"\" Y=\""+ str(tyv[i]) +"\" Z=\""+ str(tzv[i]) +"\" />")
    print("</KeyframeVector3d>")

print"======= ROTATE ======="

for i in range(0,len(keyTimes)):
    print("<KeyframeVector3d Frame=\"" + str((keyTimes[i] - min) / (max - min)) + "\" ElementKeyframeType=\"" + intanrx[i] +" " + intanry[i] + " " + intanrz[i] + "\" ElementSlopeL=\"" + str(inAnglerx[i]) + " " + str(inAnglery[i]) + " " + str(inAnglerz[i]) + "\" ElementSlopeR=\"" + str(inAnglerx[i]) + " " + str(inAnglery[i]) + " " + str(inAnglerz[i]) + "\" KeyframeTpe=\"Constant\" SlopeL=\"0\" SlopeR=\"0\">")
    print(" <Value X=\""+ str(rxv[i]) +"\" Y=\""+ str(ryv[i]) +"\" Z=\""+ str(rzv[i]) +"\" />")
    print("</KeyframeVector3d>")

print"======= END ======="

追記:フレームの計算を修正