3D舞台 link
3D舞台,正如其名稱所指,是一個在三維空間中放置可視組件的概念。 Ren’Py在3D舞台中渲染可視組件時將計算合適的透視效果,並啟用Z軸維度、燈光和深度渲染效果。
坐標系 link
要理解3D舞台的話,可能最重要的點是Ren’Py使用的3D坐標系。 這是在2D坐標系中放置可視組件的方式:
在2D坐標系中,整個矩形就是界面的尺寸。可見區域的寬和高通過 gui.init()
項進行配置(通常在新建遊戲項目時配置)。
3D舞台從原有的坐標系中擴展出了一個新軸——Z軸,其方向正對觀察者視線。 圖像坐標在Z軸方向的值大於0時,該物體距離觀察者近(圖像比原尺寸大); 圖像坐標在Z軸方向的值小於0時,該物體距離觀察者遠(圖像比原尺寸小)。
最後,當圖像在3D坐標系中旋轉時,各個軸的變化情況如下:
繞Z軸旋轉,X和Y軸數值變動。
繞X軸旋轉,Y和Z軸數值變動。
繞Y軸旋轉,Z和X軸數值變動。
這些坐標系的要點解釋,是為了使Ren’Py開發者更容易從2D舞台轉入3D舞台。 當導入3D模型後,還需要根據模型坐標進行坐標變換,使模型能正確顯示。
攝影機 link
攝影機的初始位置由參數 gui.init()
控制。
Ren’Py會根據 width 和 fov 計算出默認的 z 軸坐標。在 fov 預設值為75的情況下:
當 width = 1280,z軸坐標大約為834
當 width = 1920,z軸坐標大約為1251
當 width = 3840,z軸坐標大約為2502
實際的z軸坐標與這裡給的數值有一個小於1的誤差。
預設的z軸坐標可以通過樣式特性 perspective
或配置項 config.perspective
進行修改。
Ren’Py會自動給攝影機坐標設置一個坐標偏移量(width / 2, height / 2, z)。 攝影機觀看方向為Z軸的負無窮方向。
這個初始的 z 軸距離也是攝影機到某個特殊平面的距離。 在此特殊平面上的圖像,正好能顯示原來的尺寸(忽略整個應用窗口的縮放效果)。 增大攝影機的z軸坐標可以讓所有顯示內容變小,相反則會讓顯示內容變大。
最後一點, perspective
和 config.perspective
設置了攝影機可視範圍,預設的最近和最遠距離分別是100和10000.
當圖像與攝影機的z軸距離小於100或大於100000時,圖像將不會顯示。
- define config.perspective = (100, z, 100000) link
當
perspective
沒有設置為一個3元的元組時使用的預設值。z
的值取決於遊戲對三維空間的需求。
使用3D舞台 link
使用3D舞台時,首先需要使用 camera
語句啟用一個圖層。如果沒有指定具體圖層的名稱,則預設使用 master
圖層。
常用方法是:
# 啟用master圖層作為3D舞台圖層
camera:
perspective True
創作者可能還會想要設置一個預設的攝影機位置。詳見下面的內容。
相應的,也可以指定一個別的圖層並僅在該圖層啟用3D舞台。
# 啟用background圖層作為3D舞台圖層
camera background:
perspective True
顯示圖像(背景和sprite)則與2D坐標系中相同:
scene bg washington
show lucy mad at right
show eileen happy
所有可視組件都可以在3D空間內移動:
scene bg washington:
xalign 0.5 yalign 1.0 zpos -1000
show lucy mad:
xalign 1.0 yalign 1.0 zpos 100
show eileen happy:
xalign 0.5 yalign 1.0 zpos 200
指定一個ATL變換後,不再使用預設的變換,因此有必要顯式聲明 xalign
和 yalign
的值,分別對應可視組件在x和y軸的坐標。
當然,變換也可以像下面這樣使用:
transform zbg:
zpos -100
transform z100:
zpos 100
transform z200:
zpos 200
scene bg washington at center, zbg
show lucy mad at right, z100
show eileen happy at center, z200
如果嘗試過3D舞台,你會發現背景圖片周圍有一些空白空間。
這是因為背景向後移動後,顯示的尺寸變小了,不能填充整個螢幕。
Ren’Py提供了一個簡單方式修復這個問題—— zzoom
。
將 zzoom
特性設置為True後,無論圖像在z軸負方向的值是多少,都會放大圖像填充整個螢幕。
這對背景圖像很有效:
transform zbg:
zpos -100 zzoom True
使用ATL也可以調整zpos的值,如同調整xpos和ypos一樣:
show eileen happy at center:
zpos 0
linear 4.0 zpos 200
需要注意,zpos與幾個特殊位置(比如 left
和 right
)以及位置相關特性(比如 xalign
和 yalign
)一起使用時,
可能出導致奇怪的問題。因為Ren’Py會將圖像放在一個三維的有體積的矩形中(就像一個方塊,但各邊長度不一致),並對圖像應用透視效果,
最終導致部分圖像移出螢幕範圍。
攝影機也可以移動,使用 camera
語句。例如:
camera:
perspective True
xpos 0
linear 3.0 xpos 500
需要移動攝影機時,最好使用比整個窗口還要大的背景圖片。
如果在某個sprite上應用了zpos值但沒有任何效果,原因可能是在 camera
語句後面忘記添加 perspective
從句了。
攝影機可以轉動,比如:
camera:
perspective True
rotate 45
注意攝影機轉動後的效果,與可視組件旋轉相反方向類似。
深度 link
默認情況下,Ren’Py根據聲明順序顯示圖像,最後聲明的圖像覆蓋在其他所有圖像之上。 這個機制會導致一些小問題,比如距離攝影機更近的圖像(使用透視效果)被遠處的圖像遮擋住。
如果不想要在遊戲中的圖像顯示層級出現類似問題,可以讓GPU根據深度 gl_depth
排列圖像順序,使用:
camera:
perspective True
gl_depth True
名義上處於相同深度的圖像可能會相互覆蓋和顯示錯誤。將這些圖像壓制(flatten)為單一圖像並同時顯示就能解決該問題。
矩陣變化 link
Ren’Py中可以使用 matrixtransform
變化特性,將某個矩陣應用到可視組件上,實現三維空間中圖像的伸縮、位移和旋轉。
matrixtransform
特性可以使用一個 Matrix()
實例或transformmatrix(定義在下一節),並應用到顯示圖像的4個角的頂點上。
Ren’Py使用 matrixanchor
變換特性使矩陣應用更方便。
matrixanchor
的預設值是(0.5, 0.5),並使用通用Ren’Py錨點規則轉換為圖像內部的像素偏移值。
(如果是正整數,視為像質數;否則視為整個圖像尺寸的比例值。)
Ren’Py將矩陣變換應用到圖像上時,首先將圖像錨點設置(0, 0, 0)。應用矩陣變換後,再將錨點回復為原值。 默認情況下,變換矩陣會應用到圖像中心位置。
例如:
show eileen happy at center:
matrixtransform RotateMatrix(45, 0, 0)
會將圖像沿著其水平中軸做旋轉。圖像頂部向z軸負方向移動,圖像底部向z軸正方向移動。
多個矩陣可以使用乘法連接,依次從右到左實現變換效果。 例如:
show eileen happy at center:
matrixtransform RotateMatrix(45, 0, 0) * OffsetMatrix(0, -300, 0)
圖像將向上平移300像素,然後沿X軸旋轉45度。
結構相似原則 link
在ATL中,對 matrixtransform
特性進行插值時,要求使用的TransformMatrix對象具有相似結構。
這表示相同類型的TransformMatrix,使用相同順序相乘。
下面的樣例中,會對圖像進行旋轉和平移,然後再轉回去:
show eileen happy at center:
matrixtransform RotateMatrix(0, 0, 0) * OffsetMatrix(0, 0, 0)
linear 2.0 matrixtransform RotateMatrix(45, 0, 0) * OffsetMatrix(0, -300, 0)
linear 2.0 matrixtransform RotateMatrix(0, 0, 0) * OffsetMatrix(0, 0, 0)
對matrixtransform的第一步設置看起來似乎是多餘的,但實際並非如此,這步確定了後續插值使用的矩陣結構。 如果不在第一步設置矩陣結構,後面的插值都將略過。
TransformMatrix link
Matrix對象只適合靜態變換,對動畫變換沒什麼用。 還有一種可以將普通矩陣參數化的方法。
TransformMatrix是一個基類,擴展得到的一系列使用矩陣創建的類。 Ren’Py調用TransformMatrix類的實例,並得到返回矩陣結果。 TransformMatrix已很好集成在ATL中,可以使用matrixtransform實現動畫。
transform xrotate:
matrixtransform RotateMatrix(0.0, 0.0, 0.0)
linear 4.0 matrixtransform RotateMatrix(360.0, 0.0, 0.0)
repeat
TransformMatrix的子類必須要實現 __call__
方法。該方法需要兩個參數:
插值計算用的舊對象。這個對象可以是任意類,如果不存在舊對象則為None。
介於0.0到1.0之間的一個數值,表示插值比例。0.0對應舊對象的值,1.0表示完全使用新對象的值。
內建的TransformMatrix子類 link
下面的列表是Ren’Py內建的TransformMaxtrix子類:
- OffsetMatrix(x, y, z) link
TransformMatrix子類,將頂點移動固定數值後,返回一個矩陣。
- RotateMatrix(x, y, z) link
TransformMatrix子類,將可視組件繞原點旋轉後,返回一個矩陣。
- x, y, x
繞遠點旋轉的數量,單位是度。
旋轉按如下順序實行:
在Y/Z平面順時針旋轉x度。
在Z/X平面順時針旋轉y度。
在X/Y平面順時針旋轉z度。
- ScaleMatrix(x, y, z) link
TransformMatrix子類,縮放可視組件後,返回一個矩陣。
- x, y, x
各軸縮放係數。
變換特性 link
下列變換特性可以在3D舞台中使用。
- matrixanchor link
- Type:
(position, position)
- Default:
(0.5, 0.5)
該特性指定圖像關聯的錨點位置矩陣。 如果變數是浮點數,是與子組件尺寸相關的比例值;否則,表示像質數。
應用其他變換特性,比如point_to、orientation、xrotate、yrotate、zrotate和matrixtransform,必須設置的原點(0, 0, 0)的坐標。 該特性會將matrixtransform應用的變換對象的值設置為原點(0, 0, 0)的位置。
- point_to link
- Type:
(float, float, float), Camera, or None
- Default:
None
該特性給定了一個坐標,表示指向。相機或可視組件經過變換後,可能發生旋轉並面向指定的坐標,並且相機或可視組件移動後始終保持面向此坐標。
若該值為None,就不會發生旋轉。
若該值不是None,可能是一個三元元組或
Camera()
的實例。 (x, y, z)格式的元組表示目標興趣點坐標。Camera實例表示相機坐標。Note point_to isn’t updated automatically. so, you should write like below if you want it is updated 注意point_to的值不會自動更新。想要更新的話,請按下列方式寫腳本:
# 艾琳總是正面朝向相機。 show eileen happy at center: point_to Camera() 0 repeat
- class Camera(layer='master') link
該類的實例可以用作point_to特性的值,表示指定圖層上的相機坐標。
- layer
圖層名。
- orientation link
- Type:
(float, float, float) or None
- Default:
None
該特性會旋轉相機或可視組件。三個數值分辨表示圍繞x、y和z軸的旋轉,單位是度(degree)。 應用在可視組件上順序分別為x、y、z軸。應用在相機上順序分別是z、y、x軸。
當需要對旋轉的值進行插值計算時,會使用最短路徑算法,在新舊兩個值之間的計算結果。
若該特性值為None,不應用任何旋轉。
- xrotate link
- Type:
float or None
- Default:
None
該特性表示相機或可視組件繞著x軸旋轉。數值表示旋轉角度,單位是度(degree)。 應用在可視組件上順序分別為x、y、z軸。應用在相機上順序分別是z、y、x軸。
若該特性值為None,不繞x軸方向旋轉。
- yrotate link
- Type:
float or None
- Default:
None
該特性表示相機或可視組件繞著y軸旋轉。數值表示旋轉角度,單位是度(degree)。 應用在可視組件上順序分別為x、y、z軸。應用在相機上順序分別是z、y、x軸。
若該特性值為None,不繞y軸方向旋轉。
- zrotate link
- Type:
float or None
- Default:
None
該特性表示相機或可視組件繞著z軸旋轉。數值表示旋轉角度,單位是度(degree)。 應用在可視組件上順序分別為x、y、z軸。應用在相機上順序分別是z、y、x軸。
若該特性值為None,不繞z軸方向旋轉。
- matrixtransform link
- Type:
None or Matrix or TransformMatrix
- Default:
None
若非空,該特性指定的矩陣用於變換子組件的頂點變換。 該變換對象用作子組件變換位置與螢幕坐標間的轉換。
對該特性進行插值計算時,必須使用TransformMatrix對象,並且這些對象具有相似結構。
- perspective link
- Type:
True or False or Float or (Float, Float, Float)
- Default:
None
該特性應用到某個變換時,啟用透視渲染效果。 特性值應該是個3元元組,分別表示最近平面、1:1平面z軸距離和最遠平面。
如果值是一個浮點數,最近和最遠平面從配置項
config.perspective
獲取。 如果值是True,所有3個數值都從配置項config.perspective
獲取。當perspective特性不是False時,
xpos
、ypos
、zpos
和rotate
的值是反轉的, 表示相對攝影機的位置,而不是某個子組件自身的坐標。由於透視變換假設結果是與窗口對其的,所以不要用
xanchor
、yanchor
、anchor
、align
、center
。
- zpos link
- Type:
float
- Default:
0
改特性表示子組件在z軸方向的偏移。 當perspective特性值是False時,可以直接使用該特性值,否則需要乘以-1後再使用。
如果設置該特性後子組件消失,可能的原因是作為父組件的可視組件本身的zpos是False。
- zzoom link
- Type:
bool
- Default:
False
若該特性值為True,1:1平面(zone)的z軸距離將於該可視組件的zpos值保持一致。 子組件則根據 (zone - zpos) / zone 在x和y軸縮放。
改特性用作背景的可視組件,在 zpos 為負值的情況下,不會出現顯示過小無法覆蓋整個螢幕的情況。 該項設置為True後,背景圖像始終將以1:1的比例顯示。