3D舞台 link

3D舞台,正如其名稱所指,是一個在三維空間中放置可視組件的概念。 Ren’Py在3D舞台中渲染可視組件時將計算合適的透視效果,並啟用Z軸維度、燈光和深度效果。

坐標系 link

要理解3D舞台的話,可能最重要的點是Ren’Py使用的3D坐標系。 這是在2D坐標系中放置可視組件的方式:

_images/axes_3d_1.png

在2D坐標系中,整個矩形就是界面的尺寸。可見區域的寬和高通過 gui.init() 項進行配置(通常在新建遊戲項目時配置)。

_images/axes_3d_2.png

3D舞台從原有的坐標系中擴展出了一個新軸——Z軸,其方向正對觀察者視線。 圖像坐標在Z軸方向的值大於0時,該物體距離觀察者近(圖像比原尺寸大); 圖像坐標在Z軸方向的值小於0時,該物體距離觀察者遠(圖像比原尺寸小)。

_images/axes_3d_3.png

最後,當圖像在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軸坐標可以讓所有顯示內容變小,相反則會讓顯示內容變大。

最後一點, perspectiveconfig.perspective 設置了攝影機可視範圍,預設的最近和最遠距離分別是100和10000. 當圖像與攝影機的z軸距離小於100或大於10000時,圖像將不會顯示。

使用3D舞台 link

使用3D舞台時,首先需要使用 camera 語句指定圖層。常用方法是:

camera:
    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變換後,不再使用預設的變換,因此有必要顯式聲明 xalignyalign 的值,分別對應可視組件在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 False

使用ATL也可以調整zpos的值,如同調整xpos和ypos一樣:

show eileen happy at center:
    zpos 0
    linear 4.0 zpos 200

需要注意,zpos與幾個特殊位置(比如 leftright )以及位置相關特性(比如 xalignyalign )一起使用時, 可能出導致奇怪的問題。因為Ren’Py會將圖像放在一個三維的有體積的矩形中(就像一個方塊,但各邊長度不一致),並對圖像應用透視效果, 最終導致部分圖像移出螢幕範圍。

攝影機也可以移動,使用 camera 語句。例如:

camera:
    perspective True
    xpos 0
    linear 3.0 xpos 500

需要移動攝影機時,最好使用比整個窗口還要大的背景圖片。

如果在某個sprite上應用了zpos值但沒有任何效果,原因可能是在 camera 語句後面忘記添加 perspective 從句了。

深度 link

默認情況下,Ren’Py根據聲明順序顯示圖像,最後聲明的圖像覆蓋在其他所有圖像之上。 這個機制會導致一些小問題,比如距離攝影機更近的圖像(使用透視效果)被遠處的圖像遮擋住。

如果不想要在遊戲中的圖像顯示層級出現類似問題,可以讓GPU根據深度排列圖像順序,使用 If your game shows images out of order like this, you can tell the 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度。

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)

該特性指定圖像關聯的錨點位置矩陣。 如果變數是浮點數,是與子組件尺寸相關的比例值;否則,表示像質數。

該特性會將matrixtransform應用的變換對象的值設置為原點(0, 0, 0)的位置。

matrixtransform link
Type:None or Matrix or TransformMatrix
Default:None

若非空,該特性指定的矩陣用於變換子組件的頂點變換。 該變換對象用作子組件變換位置與螢幕坐標間的轉換。

perspective link
Type:True or False or Float or (Float, Float, Float)
Default:False

該特性應用到某個變換時,啟用透視渲染效果。

特性值應該是個3元元組,分別表示最近平面、1:1平面z軸距離和最遠平面。 如果值是一個浮點數,最近和最遠平面從配置項 config.perspective 獲取。 如果值是True,所有3個數值都從配置項 config.perspective 獲取。

當perspective特性不是False時, xposyposzpos 的值是反轉的, 表示相對攝影機的位置,而不是某個子組件自身的坐標。

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的比例顯示。