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會根據 widthfov 計算出默認的 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或大於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變換後,不再使用預設的變換,因此有必要顯式聲明 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 True

使用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 從句了。

攝影機可以轉動,比如:

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時, xposyposzposrotate 的值是反轉的, 表示相對攝影機的位置,而不是某個子組件自身的坐標。

由於透視變換假設結果是與窗口對其的,所以不要用 xanchoryanchoranchoraligncenter

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