วัตถุประสงค์ของการใช้โปรแกรมมายานั้นนอกจากการสร้างรูปทรงแล้วก็คือการทำภาพเคลื่อนไหว เพื่อที่จะทำให้กลายเป็นแอนิเมชันหรืออะไรต่างๆ
ในบทนี้จะพูดถึงพื้นฐานในการทำภาพเคลื่อนไหว
การทำภาพเคลื่อนไหวในโปรแกรมมายานั้นโดยทั่วไปใช้ระบบที่เรียกว่า
คีย์เฟรม (keyframe) คือกำหนดองค์ประกอบต่างๆของวัตถุตอนเริ่มต้นและตอนท้าย แล้วโปรแกรมจะทำการประมวลผลเพื่อหาค่าของช่วงเวลาระหว่างนั้นให้
นอกจากนี้ยังมีอีกวิธีคือ
เอ็กซ์เพรชชัน (expression) ซึ่งวิธีนั้นจะพูดถึงในบทที่ ๑๕ แต่ในบทนี้จะพูดถึงคีย์เฟรมก่อน
ในหน้าจอของโปรแกรมมายาจะมีเส้นแถบที่มีขีดและตัวเลขเป็นช่วงๆคล้ายไม้บรรทัดอยู่ด้านล่าง แถบนั้นคือ
เส้นเวลา (timeline) บอกถึงเวลาในหน่วยเป็นเฟรม พอกดเครื่องหมาย play แถบด้านล่างก็จะเลื่อนไปเรื่อยๆ ถ้ามีการตั้งคีย์เฟรมเอาไว้แล้วก็จะเห็นภาพมีการเคลื่อนไหว
ในหนึ่งวินาทีจะมีอยู่กี่เฟรมก็แล้วแต่การใช้งาน โดยทั่วไปที่นิยมใช้คือ 24,25,30 ในประเทศไทยส่วนใหญ่แล้วนิยมใช้ 25
การปรับอัตราเฟรมต่อวินาทีทำได้โดยตั้งค่าตอนเริ่มสร้างฉากขึ้นมาใหม่ ให้ดูที่เมนูด้านบน คลิกที่
File (ファイル) แล้วจะเห็นว่าอันแรกคือ
New Scene (新規シーン) ให้กดที่สี่เหลี่ยมด้านขวา
ดูที่หมวด
Default Working Units (既定作業単位) จะเห็น
Time (時間) มีให้เลือกอยู่หลายแบบ ให้เลือกเป็น PAL (25 fps)
จากนั้นกด
New (新規) ก็จะได้ฉากใหม่ที่มีอัตราเฟรมต่อวินาทีเป็น ๒๕
จากนั้นยังมีอีกอย่างที่ควรตั้ง ให้ดูที่เมนูด้านบน คลิกที่
Windows (ウィンドウ) แล้วก็เลือก
Settings/Preferences (設定/プリファレンス) แล้วก็กด
Preferences (プリファレンス) เข้ามาแล้วดูตรงแถบทางซ้าย เลือก
Time Slider (タイム スライダ) จากนั้นดูตรง
Playback speed (再生スピード) เลือกเป็น Real-time[25 fps] (リアル タイム[25 fps])
ตรงนี้หมายความว่าตั้งให้ความเร็วที่แถบเลื่อนเวลาจะเลื่อนไปนั้นตรงกับเวลา จริง จะได้เห็นภาพเคลื่อนที่เร็วตามที่ควรเห็นจริงเวลาที่ทำออกมาเป็นวีดีโอแล้ว
เริ่มต้นมาเส้นเวลานี้จะโล่งๆแบบที่เห็น แต่เมื่อมีการใส่คีย์เฟรมลงไปก็จะมีขีดสีแดงโผล่ขึ้นมา
การใส่คีย์เฟรมด้วยโค้ดภาษาไพธอนทำได้โดยฟังก์ชัน setKeyframe() โดยใส่อาร์กิวเมนต์เป็นวัตถุที่ต้องการตั้งคีย์เฟรม และมีแฟล็กที่สำคัญที่ต้องใส่คือ
- at (attribute) ค่าองค์ประกอบที่ต้องการตั้งคีย์เฟรม
- t (time) เวลาที่ต้องการตั้งคีย์เฟรม โดยหน่วยเป็นคีย์เฟรม หรืออาจใส่เป็นหน่วยวินาทีด้วยการเติม sec ต่อท้ายตัวเลข ระบบจะทำการคำนวณเป็นคีย์เฟรม กรณีใช้หน่วยคีย์เฟรมจะมีเครื่องหมายคำพูดคร่อม (เป็นสายอักขระ) หรือไม่มี (เป็นจำนวนจริง) ก็ได้
- v (value) ค่าขององค์ประกอบที่ต้องการตั้ง
ตัวอย่าง
mc.polyCone(r=2.5,h=5,n='huacharuat')
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=1)
mc.setKeyframe('huacharuat',at='ty',v=27.5,t=26)
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=51)
จากนั้นกดปุ่มเริ่มเล่นที่อยู่ทางขวาของเส้นเวลาให้แถบเลื่อนเวลาเริ่ม เคลื่อนไหวก็จะได้กรวยที่เริ่มเคลื่อนที่จากตำแหน่ง y=2.5 ตอนคีย์เฟรมที่แรกไปถึง y=22.5 ตอนคีย์เฟรมที่ 26 แล้วก็กลับมาที่เดิมที่คีย์เฟรมที่ 51
อาจจะลองจับลากแถบเลื่อนเวลาด้วยเมาส์ไปมาเพื่อให้เห็นความแตกต่าง
กรณีที่แฟล็ก t ไม่ได้ใส่จะเป็นการเลือกใส่คีย์เฟรมที่เวลาปัจจุบัน
การเลือกเวลาปัจจุบันสามารถทำได้ด้วยการเลื่อนแถบเลื่อนเวลา หรือถ้าจะใช้การพิมพ์โค้ดก็ใช้ฟังก์ชัน currentTime() โดยใส่คีย์เฟรมที่ต้องการลงในวงเล็บ เช่น
mc.currentTime(51)
mc.setKeyframe('huacharuat',at='ty',v=2.5)
แบบนี้จะได้ผลเหมือนกับ mc.setKeyframe('huacharuat',at='ty',v=2.5,t=51) แต่ต่างตรงที่พิมพ์เสร็จแล้วแถบเลื่อนเวลาจะไปอยู่ที่ตำแหน่ง t=51
การกำหนดคีย์เฟรมแบบนี้ทำให้เรารู้แน่ว่าตอนที่วัตถุอยู่ในคีย์เฟรมที่เราตั้ง ไว้มันจะมีค่าองค์ประกอบนั้นเท่านั้นแน่นอน แต่จุดที่ไม่ได้ตั้งคีย์เฟรมเอาไว้จะถูกคำนวณอัตโนมัติด้วยวิธีการประมาณค่า ในช่วง ซึ่งเราสามารถรู้ได้โดยการคลิกเวลาที่ต้องการบนเส้นเวลา หรือใช้ฟังก์ชัน currentTime() แล้วใช้ getAttr()
หรือง่ายกว่านั้นคือแค่ใช้ getAttr() แล้วใส่แฟล็ก t (time) ลงไป จะได้ค่าขององค์ประกอบนั้นที่เวลาตามที่ใส่ไป
เพื่อเป็นตัวอย่าง ให้เลือกที่วัตถุ huacharuat แล้วพิมพ์
for t in range(1,52):
print('เฟรมที่ %d: ty = %d'%(t,mc.getAttr('.ty',t=t)))
จะได้ค่าตำแหน่งในแกน y ตั้งแต่เฟรมแรกไปถึงเฟรมที่ 51 หากเอาค่าที่ได้ไปวาดกราฟก็จะรู้ว่าค่าระหว่างกลางนั้นเปลี่ยนแปลงยังไง
อย่างไรก็ตาม ในตัวโปรแกรมมีการวาดกราฟไว้ให้อยู่แล้ว สามารถเปิดดูได้ที่
กราฟอีดิเตอร์ (グラフ エディタ, graph editor) โดยคลิกที่แถบทางซ้ายล่างดังรูป
หรือเปิดจากเมนูด้านบน คลิกที่
Windows (ウィンドウ) แล้วก็เลือก
Animation Editors (アニメーションエディタ) แล้วก็กดที่
Graph Editor (グラフ エディタ) เมื่อเปิดขึ้นมาจะเห็นกราฟของตำแหน่งในแกน y (ต้องกดเลือกที่ตัววัตถุอยู่ ไม่งั้นกราฟจะไม่ขึ้น)
จะเห็นว่ากราฟเป็นเส้นโค้ง โดยมีจุดอยู่ที่ตำแหน่ง 1, 26 และ 51 ซึ่งตั้งคีย์เฟรมไว้
หากเอาเมาส์ไปคลิกที่เส้นจะเห็นว่ามีเส้นตรงปรากฏขึ้นมาทางซ้ายขวาของจุด เส้นเหล่านี้คือเส้นสัมผัสที่ใช้ควบคุมรูปร่างของกราฟ
ที่กราฟถูกสร้างเป็นเส้นโค้งนี้เกิดจากการที่โปรแกรมคำนวณให้ โดยปกติแล้วเส้นกราฟระหว่างจุดที่ตั้งคีย์เฟรมจะถูกปรับให้เป็นแบบอัตโนมัติ (auto, 自動) คือปรับให้โค้งกลมกลืนอย่างเป็นธรรมชาติ
ค่าตั้งต้นนี้สามารถเปลี่ยนแปลงได้ โดยให้ลองไปที่
Windows (ウィンドウ) >
Settings/Perences (設定/プリファレンス) >
Preferences (プリファレンス) แล้วในแถบทางซ้ายเลือก
Animation (アニメーション) ดูที่
Default in tangent (既定のイン接線) และ
Default out tangent (既定のアウト接線) จะมีให้เลือกหลายแบบ โดยทั่วไปค่าตั้งต้นจะอยู่ที่ Auto(自動)
โดยทั่วไปแล้วตั้งให้เป็นอัตโนมัติตอนเริ่มต้นแบบนี้น่าจะดีอยู่แล้ว ดังนั้นไม่ต้องไปทำอะไร อย่างไรก็ตามบางกรณีอาจจะอยากเปลี่ยนการตั้งค่าเส้นให้เป็นแบบอื่น
หากใช้โค้ดไพธอนสามารถทำได้โดยใช้ฟังก์ชัน keyTangent() ซึ่งเป็นฟังก์ชันคำสั่งสำหรับปรับลักษณะกราฟบริเวณที่อยู่ระหว่างคีย์เฟรม
ลองพิมพ์
mc.keyTangent('huacharuat',at='ty',index=(0,2),itt='linear',ott='linear')
กราฟจะกลายเป็นส้นตรง และจะเห็นว่าเส้นสัมผัสโดนหักไปซ้อนทับกับเส้นกราฟ
ในฟังก์ชันนี้อาร์กิวเมนต์คือชื่อวัตถุที่ต้องการตั้งค่า แฟล็กที่ต้องใส่คือ at (attribute) คือค่าองค์ประกอบที่ตั้งคีย์เฟรมไว้
จากนั้นต้องมีแฟล็กสำหรับระบุถึงคีย์เฟรมที่ต้องการปรับแก้ ซึ่งอาจใช้แฟล็ก index (index) หรือ t (time)
กรณีตัวอย่างในนี้ใช้แฟล็ก index ซึ่งเป็นการระบุถึงคีย์เฟรมด้วยลำดับของคีย์เฟรมตามเส้นเวลา โดยที่คีย์เฟรมแรกสุดมีลำดับเป็น 0 ดังนั้นพอใส่ index=(0,2) จึงหมายถึงการเลือกตำแหน่ง 0 ถึง 2 ดังนั้นจึงครอบคลุมคีย์เฟรมทั้ง ๓ ตัว โดยตัวที่อยู่ระหว่างกลางก็ถูกรวมอยู่ด้วย
กรณีใช้เวลาเป็นตัวระบุก็จะใช้ แฟล็ก t โดยสำหรับตัวอย่างนี้หากใช้ t จะเขียนเป็น
mc.keyTangent('huacharuat',at='ty',t=(1,51),itt='linear',ott='linear')
โดยแค่เปลี่ยนจากระบุลำดับเป็นระบุเวลาของคีย์เฟรม จะใช้ index หรือ t ก็ไม่ต่างกันดังนั้นเลือกใช้ตามที่สะดวก
ขอบเขตเวลาจะระบุกว้างเกินกว่าช่วงที่ต้องการก็ได้ ผลที่ได้ไม่ต่างกัน เช่น t=(1,52) แต่ถ้าระบุขาดไปเช่น t=(1,50) แบบนี้คีย์เฟรมที่อยู่ตำแหน่ง t=51 ก็จะไม่ถูกเลือก จึงไม่ถูกแก้ค่าไปด้วย
ส่วนแฟล็ก itt (inTangentType) และ ott (outTangentType) เป็นตัวระบุรูปแบบของเส้นสัมผัสขาเข้า (ฝั่งซ้าย) และขาออก (ฝั่งขวา) ตามลำดับ
ค่าของทั้งสองแฟล็กนี้เป็นสายอักขระที่ตายตัว มีให้เลือกอยู่หลายแบบเช่น spline, linear, flat, step, clamped, auto
ค่าตั้งต้นปกติจะเป็น auto แต่ในที่นี้ใส่เป็น linear ไปหมายถึงทำให้เป็นเชิงเส้น แบบนี้แล้วเส้นกราฟจะกลายเป็นเส้นตรง
หากลองกดเล่นให้วัตถุเคลื่อนไหวดูก็จะเห็นว่าพอขึ้นไปจุดสูงสุดที่เฟรมที่ 26 แล้วจะอยู่ดีๆเปลี่ยนทิศเป็นพุ่งลงมาเลยโดยไม่มีช่วงการหน่วง ดูแล้วไม่ค่อยเป็นธรรมชาติ
การปรับกราฟด้วย itt กับ ott นั้นเป็นการเลือกรูปแบบเพื่อปรับโดยโปรแกรมมีการคำนวณให้อัตโนมัติ แต่หากเราอยากปรับกราฟในรายละเอียดเองก็สามารถทำได้ด้วยแฟล็กอื่นๆ เช่น ia และ oa
ia และ oa เป็นแฟล็กสำหรับตั้งค่ามุมของเส้นสัมผัสขาเข้าและออกตามลำดับ โดยมุมที่ว่านี้มีค่าเท่ากับ arctan(Δx/Δy) โดยที่ x คือเวลาในหน่วยเฟรม (แกนนอนของกราฟ) และ y คือค่าองค์ประกอบที่เราพิจารณาอยู่ หน่วยของมุมในที่นี้โดยทั่วไปใช้หน่วยเป็นองศา
ตัวอย่าง ลองพิมพ์
mc.keyTangent('huacharuat',at='ty',t=(1,1),oa=85)
mc.keyTangent('huacharuat',at='ty',t=(11,51),ia=-85)
mc.keyTangent('huacharuat',at='ty',t=(26,26),ia=-85,oa=85)
จะได้กราฟหน้าตาประหลาด ซึ่งเกิดจากการที่เราไปปรับมุมเข้ากับมุมออกให้ไปกันคนละทิศทางกัน โดยที่จุด t=1 ให้พุ่งออกชัน 85 องศา ที่จุด t=26 ให้พุ่งเข้าหัวทิ่ม -85 องศา และหักเปลี่ยนไปพุ่งออกชน 85 องศาอีก และสุดท้ายที่ t=51 ก็หัวทิ่ม -85 องศา
หากลองพิมพ์
mc.keyTangent('huacharuat',at='ty',t=(1,1),oa=45)
mc.keyTangent('huacharuat',at='ty',t=(11,51),ia=-45)
mc.keyTangent('huacharuat',at='ty',t=(26,26),ia=45,oa=-45)
ก็จะได้กราฟเส้นตรงเหมือนกับตอนทีใช้ itt='linear',ott='linear' นั่นเพราะโดยทั่วไปการตั้งเส้นสัมผัสเป็นชนิด linear ก็คือปรับให้มุมเข้ามีค่าเป็น arctan((t2+t1)/(y(t2-y(t1))) และ มุมออก = -มุมเข้า
ซึ่งในตัวอย่างนี้ได้ arctan((27.5-2.5)/(26-1))=arctan(1)=45 องศา
การกำหนดค่ามุมให้สอดคล้องตามตัวอย่างนี้อาจทำให้ได้กราฟเป็นเส้นตรงจริงๆ แต่อย่างไรก็ตามในกรณีนี้หากค่าองค์ประกอบถูกเปลี่ยนไปแล้วมันก็จะเสียรูปไป เช่นลองพิมพ์ต่อจากตรงนี้ด้วย
mc.setKeyframe('huacharuat',at='ty',v=102.5,t=26)
แบบนี้ก็จะไม่ได้เส้นตรงแล้ว
ในขณะที่หากใช้ itt='linear',ott='linear' มุมจะถูกเปลี่ยนให้เป็นเส้นตรงตลอดโดยอัตโนมัติ
นอกจากแค่ปรับมุมของเส้นสัมผัสแล้วยังมีอีกอย่างหนึ่งที่สำคัญ นั่นคือน้ำหนักของเส้นสัมผัส ซึ่งในตัวอย่างที่ผ่านๆมาเรายังไม่ได้พูดถึง
เพียงแต่ว่าเส้นกราฟบนเส้นเวลาโดยปกติเริ่มแรกนั้นน้ำหนักของเส้นสัมผัสจะถูกผนึก เอาไว้ทำให้ปรับได้แต่มุม หากไม่ได้คิดจะปรับลักษณะของเส้นโค้งอย่างละเอียดมากแล้ว โดยทั่วไปปรับแค่มุมก็อาจจะเพียงพอ
อย่างไรก็ตาม หากอยากปรับน้ำหนักของเส้นเส้นสัมผัสก็สามารถทำได้ โดยเริ่มแรกต้องปลดผนึกก่อน โดยใส่แฟล็ก wt (weightedTangents) โดยใส่เป็น wt=1 จากนั้นก็ค่อยใส่น้ำหนักให้กับเส้นโดยใส่ค่าที่แฟล็ก iw (inWeight) กับ ow (outWeight)
ตัวอย่าง ลบวัตถุเก่าออกก่อนแล้วลองพิมพ์ตามนี้เพื่อสร้างกรวยพร้อมคีย์เฟรมเหมือนตัวอย่างแรกสุด
mc.polyCone(r=2.5,h=5,n='huacharuat')
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=1)
mc.setKeyframe('huacharuat',at='ty',v=27.5,t=26)
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=51)
จากนันก็พิมพ์ต่อด้วยคำสั่งกำหนดน้ำหนักของเส้นสัมผัส
mc.keyTangent('huacharuat',t=(26,26),iw=25,ow=25)
เสร็จแล้วก็จะแปลกใจว่า... ไม่มีอะไรเกิดขึ้นเลย
ที่จริงแล้วนี่เป็นเพราะตอนนี้ยังไม่ได้ปลดผนึกค่ำน้ำหนักของเส้นสัมผัส ดังนั้นให้พิมพ์ใหม่ โดยใส่แฟล็ก wt เพื่อปลดผนึกไว้ก่อน
mc.keyTangent('huacharuat',wt=1)
mc.keyTangent('huacharuat',t=(26,26),iw=25,ow=25)
ก็จะพบว่าได้กราฟที่อ้วนขึ้น นั่นเพราะว่าน้ำหนักของเส้นสัมผัสจุดตรงกลางนั้นสูงขึ้นนั่นเอง จึงดันให้เส้นกราฟยืดออก
นอกจากนี้ยังสามารถกำหนดมุมและน้ำหนักของเส้นสัมผัสโดยใช้แฟล็ก ix iy ox oy (ทั้ง ๔ ตัวนี้ชื่อย่อกับชื่อเต็มเหมือนกัน)
ix คือขนาดของเส้นกำกับเส้นสัมผัสตามแกน x (ในที่นี้คือแกนเวลา) ส่วน iy คือขนาดของเส้นกำกับเส้นสัมผัสตามแกน y (ในที่นี้คือค่าองค์ประกอบ)
ค่า ix และ iy สามารถคำนวณเปลี่ยนเป็นค่ามุม ia และน้ำหนัก iw อีกที
โดย arctan(อัตราเฟรมต่อวินาที*ix/iy)=ia
ให้ระวังว่าหน่วยของ ix เป็นวินาที ไม่ใช่จำนวนเฟรม ซึ่งในกรณีตอนนี้อัตราเฟรมต่อวินาทีเป็น 25
ส่วน ox oy ก็ทำนองเดียวกับ ix iy แค่เปลี่ยนจาก ia เป็น oa
ยกตัวอย่าง ลองใช้ ox=1, oy=25, ix=1, iy=25 จะพบว่าได้กราฟเป็นเส้นตรง เหมือนกับใช้ oa=45 และ ia=45
mc.keyTangent('huacharuat',at='ty',t=(1,1),ox=1,oy=25)
mc.keyTangent('huacharuat',at='ty',t=(11,51),ix=1,iy=-25)
mc.keyTangent('huacharuat',at='ty',t=(26,26),ix=1,iy=25,ox=1,oy=-25)
อีกเรื่องที่อาจจะน่าเสริมอีกหน่อยคือ กรณีที่กดเลือกที่ตัววัตถุแล้วไปคลิกเลือกที่กราฟแล้วอาจไม่ต้องใส่ทั้ง อาร์กิวเมนต์ แฟล็ก at และแฟล็ก t เลย
mc.keyTangent(itt='linear',ott='linear')
การเลือกช่วงกราฟนั้น ถ้าไม่คลิกเลือกที่เส้นกราฟ ก็สามารถใช้โค้ดไพธอนกดเลือกได้ด้วยฟังก์ชัน selectKey()
mc.selectKey('huacharuat',at='ty',t=(1,51))
อาร์กิวเมนต์และแฟล็กที่ใช้จะเหมือนกับในฟังก์ชัน keyTangent() คือชื่อวัตถุเป็นอาร์กิวเมนต์ แฟล็ก at ระบุองค์ประกอบ และใช้ index หรือ t เพื่อระบุขอบเขตที่ต้องการเลือก
นอกจากนี้แล้ว การกำหนดรูปแบบของเส้นสัมผัสนั้นที่จริงสามารถทำได้ตั้งแต่ตอนเริ่มตั้งคีย์ เฟรม โดยใส่แฟล็ก itt กับ ott ลงไปในฟังก์ชัน setKeyframe() เลย ดังนั้นถ้าตัวอย่างเดิมจะเปลี่ยนมาเขียนแบบนี้ก็ได้
mc.polyCone(r=2.5,h=5,n='huacharuat')
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=1,itt='linear',ott='linear')
mc.setKeyframe('huacharuat',at='ty',v=27.5,t=26,itt='linear',ott='linear')
mc.setKeyframe('huacharuat',at='ty',v=2.5,t=51,itt='linear',ott='linear')
จบบทนี้ลงเท่านี้ ตอนนี้เราสามารถทำภาพเคลื่อนไหวอย่างง่ายๆได้แล้ว
การทำภาพเคลื่อนไหวยังมีรายละเอียดที่ต้องพูดถึงอีกมาก จะพูดถึงต่อในบทถัดไปอีก
อ้างอิง