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和100000。
当图像与摄像机的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
See also
SplineMatrix
, which works with TransformMatrix subclasses.
See also
SplineMatrix
类如何与其他TransformMatrix子类同时生效。
下面的列表是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的比例显示。