renpy/doc/3dstage.html

633 lines
44 KiB
HTML
Raw Normal View History

2023-01-18 22:13:55 +00:00
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3D Stage &#8212; Ren&#39;Py Documentation</title>
<link rel="stylesheet" href="_static/renpydoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="_static/js/jquery-fix.js"></script>
<script type="text/javascript" src="_static/bootstrap-3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="_static/bootstrap-sphinx.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Live2D Cubism" href="live2d.html" />
<link rel="prev" title="Layered Images" href="layeredimage.html" />
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
</head><body>
<div id="navbar" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">
Ren&#39;Py Documentation</a>
<span class="navbar-text navbar-version pull-left"><b>7.5.3</b></span>
</div>
<div class="collapse navbar-collapse nav-collapse">
<ul class="nav navbar-nav">
<li><a href="https://www.renpy.org">Home Page</a></li>
<li><a href="https://www.renpy.org/doc/html/">Online Documentation</a></li>
<li class="dropdown globaltoc-container">
<a role="button"
id="dLabelGlobalToc"
data-toggle="dropdown"
data-target="#"
href="index.html">Site <b class="caret"></b></a>
<ul class="dropdown-menu globaltoc"
role="menu"
aria-labelledby="dLabelGlobalToc"><ul>
<li class="toctree-l1"><a class="reference internal" href="quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="gui.html">GUI Customization Guide</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="language_basics.html">Language Basics</a></li>
<li class="toctree-l1"><a class="reference internal" href="label.html">Labels &amp; Control Flow</a></li>
<li class="toctree-l1"><a class="reference internal" href="dialogue.html">Dialogue and Narration</a></li>
<li class="toctree-l1"><a class="reference internal" href="displaying_images.html">Displaying Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="menus.html">In-Game Menus</a></li>
<li class="toctree-l1"><a class="reference internal" href="python.html">Python Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="conditional.html">Conditional Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="audio.html">Audio</a></li>
<li class="toctree-l1"><a class="reference internal" href="movie.html">Movie</a></li>
<li class="toctree-l1"><a class="reference internal" href="voice.html">Voice</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="text.html">Text</a></li>
<li class="toctree-l1"><a class="reference internal" href="translation.html">Translation</a></li>
<li class="toctree-l1"><a class="reference internal" href="displayables.html">Displayables</a></li>
<li class="toctree-l1"><a class="reference internal" href="transforms.html">Transforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="transitions.html">Transitions</a></li>
<li class="toctree-l1"><a class="reference internal" href="atl.html">Animation and Transformation Language</a></li>
<li class="toctree-l1"><a class="reference internal" href="matrixcolor.html">Matrixcolor</a></li>
<li class="toctree-l1"><a class="reference internal" href="layeredimage.html">Layered Images</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">3D Stage</a></li>
<li class="toctree-l1"><a class="reference internal" href="live2d.html">Live2D Cubism</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="style.html">Styles</a></li>
<li class="toctree-l1"><a class="reference internal" href="style_properties.html">Style Properties</a></li>
<li class="toctree-l1"><a class="reference internal" href="screens.html">Screens and Screen Language</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_actions.html">Screen Actions, Values, and Functions</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_special.html">Special Screen Names</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_optimization.html">Screen Language Optimization</a></li>
<li class="toctree-l1"><a class="reference internal" href="config.html">Configuration Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="preferences.html">Preference Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="store_variables.html">Store Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="mouse.html">Custom Mouse Cursors</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="launcher.html">Launcher</a></li>
<li class="toctree-l1"><a class="reference internal" href="developer_tools.html">Developer Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="director.html">Interactive Director</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="nvl_mode.html">NVL-Mode Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="input.html">Text Input</a></li>
<li class="toctree-l1"><a class="reference internal" href="side_image.html">Side Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="rooms.html">Image Gallery, Music Room, and Replay Actions</a></li>
<li class="toctree-l1"><a class="reference internal" href="drag_drop.html">Drag and Drop</a></li>
<li class="toctree-l1"><a class="reference internal" href="sprites.html">Sprites</a></li>
<li class="toctree-l1"><a class="reference internal" href="keymap.html">Customizing the Keymap</a></li>
<li class="toctree-l1"><a class="reference internal" href="achievement.html">Achievements</a></li>
<li class="toctree-l1"><a class="reference internal" href="history.html">Dialogue History</a></li>
<li class="toctree-l1"><a class="reference internal" href="multiple.html">Multiple Character Dialogue</a></li>
<li class="toctree-l1"><a class="reference internal" href="splashscreen_presplash.html">Splashscreen and Presplash</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="statement_equivalents.html">Statement Equivalents</a></li>
<li class="toctree-l1"><a class="reference internal" href="save_load_rollback.html">Saving, Loading, and Rollback</a></li>
<li class="toctree-l1"><a class="reference internal" href="persistent.html">Persistent Data</a></li>
<li class="toctree-l1"><a class="reference internal" href="trans_trans_python.html">Transforms and Transitions in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="gui_advanced.html">Advanced GUI</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_python.html">Screens and Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="modes.html">Modes</a></li>
<li class="toctree-l1"><a class="reference internal" href="cdd.html">Creator-Defined Displayables</a></li>
<li class="toctree-l1"><a class="reference internal" href="cds.html">Creator-Defined Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom_text_tags.html">Custom Text Tags</a></li>
<li class="toctree-l1"><a class="reference internal" href="character_callbacks.html">Character Callbacks</a></li>
<li class="toctree-l1"><a class="reference internal" href="file_python.html">File Access</a></li>
<li class="toctree-l1"><a class="reference internal" href="color_class.html">Color Class</a></li>
<li class="toctree-l1"><a class="reference internal" href="matrix.html">Matrix</a></li>
<li class="toctree-l1"><a class="reference internal" href="model.html">Model-Based Rendering</a></li>
<li class="toctree-l1"><a class="reference internal" href="other.html">Other Functions and Variables</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="build.html">Building Distributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="updater.html">Web Updater</a></li>
<li class="toctree-l1"><a class="reference internal" href="android.html">Android</a></li>
<li class="toctree-l1"><a class="reference internal" href="chromeos.html">Chrome OS/Chromebook</a></li>
<li class="toctree-l1"><a class="reference internal" href="ios.html">iOS</a></li>
<li class="toctree-l1"><a class="reference internal" href="iap.html">In-App Purchasing</a></li>
<li class="toctree-l1"><a class="reference internal" href="gesture.html">Gestures</a></li>
<li class="toctree-l1"><a class="reference internal" href="raspi.html">Raspberry Pi</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="security.html">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="problems.html">Dealing with Problems</a></li>
<li class="toctree-l1"><a class="reference internal" href="environment_variables.html">Environment Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="self_voicing.html">Self-Voicing</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="editor.html">Text Editor Integration</a></li>
<li class="toctree-l1"><a class="reference internal" href="skins.html">Skins</a></li>
<li class="toctree-l1"><a class="reference internal" href="translating_renpy.html">Translating Ren'Py</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog (Ren'Py 7.x-)</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog6.html">Changelog (Ren'Py 6.11 - 6.99)</a></li>
<li class="toctree-l1"><a class="reference internal" href="incompatible.html">Incompatible Changes</a></li>
<li class="toctree-l1"><a class="reference internal" href="distributor.html">Distributor Notes</a></li>
<li class="toctree-l1"><a class="reference internal" href="license.html">License</a></li>
<li class="toctree-l1"><a class="reference internal" href="credits.html">Credits</a></li>
<li class="toctree-l1"><a class="reference internal" href="sponsors.html">Ren'Py Development Sponsors</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="thequestion.html">Script of The Question</a></li>
<li class="toctree-l1"><a class="reference internal" href="thequestion_nvl.html">NVL-mode script for The Question</a></li>
</ul>
</ul>
</li>
</ul>
<form class="navbar-form navbar-right" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search" />
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3">
<div id="sidebar" class="bs-sidenav" role="complementary"><ul>
<li><a class="reference internal" href="#">3D Stage</a><ul>
<li><a class="reference internal" href="#coordinates">Coordinates</a></li>
<li><a class="reference internal" href="#camera">Camera</a></li>
<li><a class="reference internal" href="#using-the-3d-stage">Using the 3D Stage</a></li>
<li><a class="reference internal" href="#depth">Depth</a></li>
<li><a class="reference internal" href="#matrix-transforms">Matrix Transforms</a><ul>
<li><a class="reference internal" href="#structural-similarity">Structural Similarity</a></li>
</ul>
</li>
<li><a class="reference internal" href="#transformmatrix">TransformMatrix</a></li>
<li><a class="reference internal" href="#built-in-transformmatrix-subclasses">Built-In TransformMatrix Subclasses</a></li>
<li><a class="reference internal" href="#transform-properties">Transform Properties</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="col-md-9 content">
<div class="section" id="d-stage">
<span id="dstage"></span><h1>3D Stage<a class="headerlink" href="#d-stage" title="Permalink to this headline"> link</a></h1>
<p>The 3D Stage, named after the stages that plays are performed on, is a concept
that allows displayables to be positioned in 3 dimensions. Ren'Py will then
render the displayables with the proper perspective, and will also make the
z dimension avalable, to make things like lighting and depth rendering
possible.</p>
<div class="section" id="coordinates">
<h2>Coordinates<a class="headerlink" href="#coordinates" title="Permalink to this headline"> link</a></h2>
<p>Probably the most important thing to understand about the 3D Stage is the
coordinate system that Ren'Py uses for the 3D state. Here's the coordinate
system that's used to place displayables in 2D:</p>
<img alt="_images/axes_3d_1.png" src="_images/axes_3d_1.png" />
<p>In 2D, the rectangle is the size of the screen, and the width and height
of the visible area is set using <a class="reference internal" href="gui_advanced.html#gui.init" title="gui.init"><code class="xref py py-func docutils literal notranslate"><span class="pre">gui.init()</span></code></a> (usually when first making
a new game).</p>
<img alt="_images/axes_3d_2.png" src="_images/axes_3d_2.png" />
<p>The 3D stage extends this coordinate system with a new axis, one facing
towards the viewer, so that values greater than 0 bring an image closer
(and make it bigger), and those less than 0 move the image away from the viewer
(and make it smaller).</p>
<img alt="_images/axes_3d_3.png" src="_images/axes_3d_3.png" />
<p>Finally, when a rotation in 3d happens, it's in the directions given here:</p>
<ul class="simple">
<li>When rotating around Z, X moves toward Y.</li>
<li>When rotating around X, Y moves toward Z.</li>
<li>When rotating around Y, Z moves toward X.</li>
</ul>
<p>These coordinate systems are based on those used in Ren'Py, making it
easy to move from 2D to the 3D stage. When importing 3D models, coordinate
transforms may be applied to ensure the model coordinates are sensible.</p>
</div>
<div class="section" id="camera">
<h2>Camera<a class="headerlink" href="#camera" title="Permalink to this headline"> link</a></h2>
<p>The initial placement of the camera is controlled by the parameters to
<a class="reference internal" href="gui_advanced.html#gui.init" title="gui.init"><code class="xref py py-func docutils literal notranslate"><span class="pre">gui.init()</span></code></a>. First, Ren'Py uses <cite>width</cite> and <cite>fov</cite> to compute the
default <cite>z</cite> distance. For the default <cite>fov</cite> of 75:</p>
<ul class="simple">
<li>When width = 1280, z is about 834</li>
<li>When width = 1920, z is about 1251</li>
<li>When width = 3840, z is about 2502</li>
</ul>
<p>Where the actual value of z is less than 1 higher than the values given
here. The default z placement can be overridden with the <a class="reference internal" href="#transform-property-perspective"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">perspective</span></code></a>
style property, or the <code class="xref std std-var docutils literal notranslate"><span class="pre">config.perspective</span></code> variable.</p>
<p>Ren'Py automatically applies an offset of (<cite>width</cite> / 2, <cite>height</cite> / 2, <cite>z</cite>)
to the camera, and it looks down the -Z axis.</p>
<p>The <cite>z</cite> distance is also the distance from the camera to the plane where
pixels on-screen have the same size as they do in the original images (ignoring
window scaling). Increasing the camera's z position will make everything
smaller, while decreasing it will make everything bigger.</p>
<p>Finally, <a class="reference internal" href="#transform-property-perspective"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">perspective</span></code></a> and <code class="xref std std-var docutils literal notranslate"><span class="pre">config.perspective</span></code> describe the
near and far planes, defaulting to 100 and 100000, respectively. This
means than when an image is closer than 100 z-units from the camera,
it disappears, and it also disappears if it's more than 100,000 z-units
away.</p>
</div>
<div class="section" id="using-the-3d-stage">
<h2>Using the 3D Stage<a class="headerlink" href="#using-the-3d-stage" title="Permalink to this headline"> link</a></h2>
<p>The first thing to do to use the 3D stage is to enable it for a layer, using
the <code class="docutils literal notranslate"><span class="pre">camera</span></code> statement. This is usually done with:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">camera</span><span class="p">:</span>
<span class="na">perspective</span> <span class="kc">True</span>
</pre></div>
</div>
<p>though it's possible that you'll want to include a default camera position, as
described below.</p>
<p>Showing images (backgrounds and sprites) works the same way as it does in
when using 2D coordinates.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">scene</span> <span class="n">bg</span> <span class="n">washington</span>
<span class="k">show</span> <span class="n">lucy</span> <span class="n">mad</span> <span class="k">at</span> <span class="n">right</span>
<span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span>
</pre></div>
</div>
<p>However, it's possible to use transforms to move these displayables in
three dimensional space:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">scene</span> <span class="n">bg</span> <span class="n">washington</span><span class="p">:</span>
<span class="na">xalign</span> <span class="mf">0.5</span> <span class="na">yalign</span> <span class="mf">1.0</span> <span class="na">zpos</span> <span class="o">-</span><span class="mi">1000</span>
<span class="k">show</span> <span class="n">lucy</span> <span class="n">mad</span><span class="p">:</span>
<span class="na">xalign</span> <span class="mf">1.0</span> <span class="na">yalign</span> <span class="mf">1.0</span> <span class="na">zpos</span> <span class="mi">100</span>
<span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span><span class="p">:</span>
<span class="na">xalign</span> <span class="mf">0.5</span> <span class="na">yalign</span> <span class="mf">1.0</span> <span class="na">zpos</span> <span class="mi">200</span>
</pre></div>
</div>
<p>As an ATL transform is given, the default transform is not used, and it's
necessary to specify <a class="reference internal" href="atl.html#transform-property-xalign"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">xalign</span></code></a> and <a class="reference internal" href="atl.html#transform-property-yalign"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">yalign</span></code></a> to position the
displayable in the x and y axes. Of course, transforms can also be used.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">transform</span> <span class="n">zbg</span><span class="p">:</span>
<span class="na">zpos</span> <span class="o">-</span><span class="mi">100</span>
<span class="k">transform</span> <span class="n">z100</span><span class="p">:</span>
<span class="na">zpos</span> <span class="mi">100</span>
<span class="k">transform</span> <span class="n">z200</span><span class="p">:</span>
<span class="na">zpos</span> <span class="mi">200</span>
<span class="k">scene</span> <span class="n">bg</span> <span class="n">washington</span> <span class="k">at</span> <span class="n">center</span><span class="p">,</span> <span class="n">zbg</span>
<span class="k">show</span> <span class="n">lucy</span> <span class="n">mad</span> <span class="k">at</span> <span class="n">right</span><span class="p">,</span> <span class="n">z100</span>
<span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span> <span class="k">at</span> <span class="n">center</span><span class="p">,</span> <span class="n">z200</span>
</pre></div>
</div>
<p>If you try this, you'll see an empty space around the background. That's
because by moving it back, it becomes smaller, and doesn't fill the screen.
Ren'Py has an easy way of fixing this problem - <a class="reference internal" href="#transform-property-zzoom"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">zzoom</span></code></a>. Setting
the tpref:<cite>zzoom</cite> property to True will scale an image by the amount it was shrunk
due to having a negative zpos. It's useful for backgrounds.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">transform</span> <span class="n">zbg</span><span class="p">:</span>
<span class="na">zpos</span> <span class="o">-</span><span class="mi">100</span> <span class="na">zzoom</span> <span class="kc">False</span>
</pre></div>
</div>
<p>It's also possible to use ATL to vary zpos, just like you would xpos and
ypos.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span> <span class="k">at</span> <span class="n">center</span><span class="p">:</span>
<span class="na">zpos</span> <span class="mi">0</span>
<span class="n">linear</span> <span class="mf">4.0</span> <span class="na">zpos</span> <span class="mi">200</span>
</pre></div>
</div>
<p>Note that zpos can interact strangely with positions like <code class="docutils literal notranslate"><span class="pre">left</span></code> and <code class="docutils literal notranslate"><span class="pre">right</span></code>,
and with <a class="reference internal" href="style_properties.html#style-property-xalign"><code class="xref std std-propref docutils literal notranslate"><span class="pre">xalign</span></code></a> and <a class="reference internal" href="style_properties.html#style-property-yalign"><code class="xref std std-propref docutils literal notranslate"><span class="pre">yalign</span></code></a>. That's because Ren'Py will
position the images in a three dimensional rectangular volume (like a cube, but
not all the sides are the same length), and then apply perspective to the image,
which can cause parts of the image to move offscreen.</p>
<p>It's possible to move the camera, as well, using <code class="docutils literal notranslate"><span class="pre">camera</span></code>. For example,</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">camera</span><span class="p">:</span>
<span class="na">perspective</span> <span class="kc">True</span>
<span class="na">xpos</span> <span class="mi">0</span>
<span class="n">linear</span> <span class="mf">3.0</span> <span class="na">xpos</span> <span class="mi">500</span>
</pre></div>
</div>
<p>When doing this, it probably makes sense to use background images that are
larger than the window.</p>
<p>If you apply a zpos to a sprite, and it doesn't take effect, the reason is
probably because you omitted the <code class="docutils literal notranslate"><span class="pre">perspective</span></code> clause of the <code class="docutils literal notranslate"><span class="pre">camera</span></code>
transform.</p>
<p>The camera can be rotated, with:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">camera</span><span class="p">:</span>
<span class="na">perspective</span> <span class="kc">True</span>
<span class="na">rotate</span> <span class="mi">45</span>
</pre></div>
</div>
<p>As the camera is what is rotating, the rotation is in the opposite
direction as one that rotates a displayable.</p>
</div>
<div class="section" id="depth">
<h2>Depth<a class="headerlink" href="#depth" title="Permalink to this headline"> link</a></h2>
<p>By default, Ren'Py will display the images in its usual order, with the last
image to be shown above the others. This might lead to odd results, like
an image that is closer (using perspective) beign shown behind one that's
farther away.</p>
<p>If your game shows images out of order like this, you can tell the GPU
to sort by depth, using <code class="xref std std-tpref docutils literal notranslate"><span class="pre">gl_depth</span></code>:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">camera</span><span class="p">:</span>
<span class="na">perspective</span> <span class="kc">True</span>
<span class="na">gl_depth</span> <span class="kc">True</span>
</pre></div>
</div>
<p>Slight rounding errors can cause images that are nominally at the same depth to
appear above or below each other. Flattening these images and displaying them
together may be the solution to this.</p>
</div>
<div class="section" id="matrix-transforms">
<h2>Matrix Transforms<a class="headerlink" href="#matrix-transforms" title="Permalink to this headline"> link</a></h2>
<p>Ren'Py uses the <a class="reference internal" href="#transform-property-matrixtransform"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">matrixtransform</span></code></a> transform property to apply a matrix
to displayables, which allows an image to be scaled, offset, and rotated in
three-dimensional space. This property takes either a <a class="reference internal" href="matrix.html#Matrix" title="Matrix"><code class="xref py py-func docutils literal notranslate"><span class="pre">Matrix()</span></code></a> or a
TransformMatrix (defined below), and applies it to the vertices at the corners
of the images being displayed.</p>
<p>Ren'Py uses the <a class="reference internal" href="#transform-property-matrixanchor"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">matrixanchor</span></code></a> transform property to make applying a
matrix easier. This defaults to (0.5, 0.5), and is translated to a pixel offset
inside the image being transformed using the usual Ren'Py anchor rules. (If it's
an integer or abolute, it's considered a number of pixels, otherwise it's a
fraction of the size of the image.)</p>
<p>Ren'Py applies the image by first shifting the image so the anchor is at (0, 0, 0).
It then applies the transform, and then shifts it back by the same amount. Using
the defaults, this means that the matrix will be applied to the center of the
image.</p>
<p>For example:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span> <span class="k">at</span> <span class="n">center</span><span class="p">:</span>
<span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mi">45</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>Will rotate the image around the line going horizontally through it's center. The
top of the image will move back, and then bottom of the image will move
forwards.</p>
<p>Matrixes can be chained together with multiplication. It's easiest to think
about them being applied right to left. In this example:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span> <span class="k">at</span> <span class="n">center</span><span class="p">:</span>
<span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mi">45</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="n">OffsetMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">300</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>The image will be shifted up by 300 pixels, and then will be rotated around
the X axis.</p>
<div class="section" id="structural-similarity">
<h3>Structural Similarity<a class="headerlink" href="#structural-similarity" title="Permalink to this headline"> link</a></h3>
<p>In ATL, interpolating a the <a class="reference internal" href="#transform-property-matrixtransform"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">matrixtransform</span></code></a> property requires the
use of TransformMatrixes that have structural similarity. That means the same
types of TransformMatrix, multiplied together in the same order.</p>
<p>As an example, the following will rotate and offset, then move back:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span> <span class="k">at</span> <span class="n">center</span><span class="p">:</span>
<span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="n">OffsetMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">linear</span> <span class="mf">2.0</span> <span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mi">45</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="n">OffsetMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">300</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">linear</span> <span class="mf">2.0</span> <span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="n">OffsetMatrix</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>While the first setting of matrixtransform may seem unnecessary, it is required
to provide a base for the first linear interpolation. If it wasn't present, that
interpolation would be skipped.</p>
</div>
</div>
<div class="section" id="transformmatrix">
<h2>TransformMatrix<a class="headerlink" href="#transformmatrix" title="Permalink to this headline"> link</a></h2>
<p>While Matrix objects are suitable for static transformations, they're not
useful for animating changing transformations. It's also useful to have a way of
taking common matrices and encapsulating them in a way that allows the
matrix to be parameterized.</p>
<p>The TransformMatrix is a base class that is is extended by a number of
Matrix-creating classes. Instances of TransformMatrix are called by Ren'Py,
and return Matrixes. TransformMatrix is well integrated with ATL, allowing
for matrixtransform animations.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">transform</span> <span class="n">xrotate</span><span class="p">:</span>
<span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">)</span>
<span class="n">linear</span> <span class="mf">4.0</span> <span class="na">matrixtransform</span> <span class="n">RotateMatrix</span><span class="p">(</span><span class="mf">360.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">)</span>
<span class="k">repeat</span>
</pre></div>
</div>
<p>Subclasses of TransformMatrix are expected to implement the <code class="docutils literal notranslate"><span class="pre">__call__</span></code> method.
This method takes:</p>
<ul class="simple">
<li>An old object to interpolate off of. This object may be of any class,
and may be None if no old object exists.</li>
<li>A value between 0.0 and 1.0, representing the point to interpolate.
0.0 is entirely the old object, and 1.0 is entirely the new object.</li>
</ul>
</div>
<div class="section" id="built-in-transformmatrix-subclasses">
<h2>Built-In TransformMatrix Subclasses<a class="headerlink" href="#built-in-transformmatrix-subclasses" title="Permalink to this headline"> link</a></h2>
<p>The following is the list of TransformMatrix subclasses that are built into
Ren'Py.</p>
<dl class="function">
<dt id="OffsetMatrix">
<code class="descname">OffsetMatrix</code><span class="sig-paren">(</span><em>x</em>, <em>y</em>, <em>z</em><span class="sig-paren">)</span><a class="headerlink" href="#OffsetMatrix" title="Permalink to this definition"> link</a></dt>
<dd><p>A TransformMatrix that returns a matrix that offsets the vertex by a fixed amount.</p>
</dd></dl>
<dl class="function">
<dt id="RotateMatrix">
<code class="descname">RotateMatrix</code><span class="sig-paren">(</span><em>x</em>, <em>y</em>, <em>z</em><span class="sig-paren">)</span><a class="headerlink" href="#RotateMatrix" title="Permalink to this definition"> link</a></dt>
<dd><p>A TransformMatrix that returns a matrix that rotates the displayable around the
origin.</p>
<dl class="docutils">
<dt><cite>x</cite>, <cite>y</cite>, <cite>z</cite></dt>
<dd>The amount to rotate around the origin, in degrees.</dd>
</dl>
<p>The rotations are applied in order:</p>
<ul class="simple">
<li>A clockwise rotation by <cite>x</cite> degrees in the Y/Z plane.</li>
<li>A clockwise rotation by <cite>y</cite> degrees in the Z/X plane.</li>
<li>A clockwise rotation by <cite>z</cite> degrees in the X/Y plane.</li>
</ul>
</dd></dl>
<dl class="function">
<dt id="ScaleMatrix">
<code class="descname">ScaleMatrix</code><span class="sig-paren">(</span><em>x</em>, <em>y</em>, <em>z</em><span class="sig-paren">)</span><a class="headerlink" href="#ScaleMatrix" title="Permalink to this definition"> link</a></dt>
<dd><p>A TransformMatrix that returns a matrix that scales the displayable.</p>
<dl class="docutils">
<dt><cite>x</cite>, <cite>y</cite>, <cite>z</cite></dt>
<dd>The factor to scale each axis by.</dd>
</dl>
</dd></dl>
</div>
<div class="section" id="transform-properties">
<h2>Transform Properties<a class="headerlink" href="#transform-properties" title="Permalink to this headline"> link</a></h2>
<p>The following transform properties are used by the 3D Stage.</p>
<blockquote>
<div><a class="reference internal" href="#transform-property-perspective"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">perspective</span></code></a>, <a class="reference internal" href="#transform-property-matrixanchor"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">matrixanchor</span></code></a>, <a class="reference internal" href="#transform-property-matrixtransform"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">matrixtransform</span></code></a>, <a class="reference internal" href="#transform-property-zpos"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">zpos</span></code></a>, <a class="reference internal" href="#transform-property-zzoom"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">zzoom</span></code></a></div></blockquote>
<dl class="transform-property">
<dt id="transform-property-matrixanchor">
<code class="descname">matrixanchor</code><a class="headerlink" href="#transform-property-matrixanchor" title="Permalink to this definition"> link</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">(position, position)</td>
</tr>
<tr class="field-even field"><th class="field-name">Default:</th><td class="field-body">(0.5, 0.5)</td>
</tr>
</tbody>
</table>
<p>This gives the position of the matrix anchor relative to the image. If the
variables are floats, this is relative to the size of the child, otherwise
it's absolute pixels.</p>
<p>This sets the location of the (0, 0, 0) point that matrixtransform applies
its transform to.</p>
</dd></dl>
<dl class="transform-property">
<dt id="transform-property-matrixtransform">
<code class="descname">matrixtransform</code><a class="headerlink" href="#transform-property-matrixtransform" title="Permalink to this definition"> link</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">None or Matrix or TransformMatrix</td>
</tr>
<tr class="field-even field"><th class="field-name">Default:</th><td class="field-body">None</td>
</tr>
</tbody>
</table>
<p>If not None, this gives a matrix that is used to transform the vertices
of the child of the transform. The transformation goes from the coordinates
used by the screen to the coordinates used by the child of the transform.</p>
<p>Interpolations involving this property are only supported when using a
TransformMatrix, and when the TransformMatrix values are structurally similar,
as described above.</p>
</dd></dl>
<dl class="transform-property">
<dt id="transform-property-perspective">
<code class="descname">perspective</code><a class="headerlink" href="#transform-property-perspective" title="Permalink to this definition"> link</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">True or False or Float or (Float, Float, Float)</td>
</tr>
<tr class="field-even field"><th class="field-name">Default:</th><td class="field-body">None</td>
</tr>
</tbody>
</table>
<p>When applied to a transform, this enables perspective rendering. This
takes a triple, giving the near plane, z-distance to the 1:1 plane, and
far plane.</p>
<p>If a single float, the distances to the near and far planes are taken
from <code class="xref std std-var docutils literal notranslate"><span class="pre">config.perspective</span></code>. If True, all three values are taken
from that variable.</p>
<p>When perspective is not false, the meaning of the <a class="reference internal" href="atl.html#transform-property-xpos"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">xpos</span></code></a>, <a class="reference internal" href="atl.html#transform-property-ypos"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">ypos</span></code></a>,
<a class="reference internal" href="#transform-property-zpos"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">zpos</span></code></a>, and <a class="reference internal" href="atl.html#transform-property-rotate"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">rotate</span></code></a> are inverted, providing the effect of positioning the
camera rather than the child.</p>
<p>As the perspective transformation assumes it's aligned with the window,
it doesn't make sense to reposition it using <a class="reference internal" href="atl.html#transform-property-xanchor"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">xanchor</span></code></a>, and <a class="reference internal" href="atl.html#transform-property-yanchor"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">yanchor</span></code></a>,
or properties that set those, such as <a class="reference internal" href="atl.html#transform-property-anchor"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">anchor</span></code></a>, <a class="reference internal" href="atl.html#transform-property-align"><code class="xref std std-tpref docutils literal notranslate"><span class="pre">align</span></code></a>, <code class="xref std std-tpref docutils literal notranslate"><span class="pre">center</span></code>,
etc.</p>
</dd></dl>
<dl class="transform-property">
<dt id="transform-property-zpos">
<code class="descname">zpos</code><a class="headerlink" href="#transform-property-zpos" title="Permalink to this definition"> link</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">float</td>
</tr>
<tr class="field-even field"><th class="field-name">Default:</th><td class="field-body">0</td>
</tr>
</tbody>
</table>
<p>This offsets the child along the z-axis. When perspective is false,
this is used directly, otherwise it is multiplied by -1 and used.</p>
<p>If setting this causes the child to disappear, it's likely that the
transform is not being used with a displayable where zpos is False.</p>
</dd></dl>
<dl class="transform-property">
<dt id="transform-property-zzoom">
<code class="descname">zzoom</code><a class="headerlink" href="#transform-property-zzoom" title="Permalink to this definition"> link</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Type:</th><td class="field-body">bool</td>
</tr>
<tr class="field-even field"><th class="field-name">Default:</th><td class="field-body">False</td>
</tr>
</tbody>
</table>
<p>If this is true, the z-distance to the 1:1 plane (<cite>zone</cite>) is determined,
along with this displayable's zpos. The child is then scaled by (<cite>zone</cite> - <cite>zpos</cite>) / <cite>zone</cite>
in the x and y axes.</p>
<p>The intended use for this is in displaying a background with a negative <cite>zpos</cite>, which
would normally make the background small. Setting this to true means that the background
will be displayed at 1:1 size.</p>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-right">
<a href="#">Back to top</a>
</p>
<p>
&copy; Copyright 2012-2022, Tom Rothamel.<br/>
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.6.<br/>
</p>
</div>
</footer>
</body>
</html>