モデルベースのレンダリング link
多くのビジュアルノベルのように Rend'Py では 2 次元の矩形画像が主に使用されていますが、近代的な GPU に見られる機能を利用できるようにしたモデルベースのレンダラーが内部にはあります。これにより他では出来ない多くのビジュアルエフェクトを可能にします。
警告すると、これは Ren'Py の最も高度な機能の1つです。多くの場合でモデルベースのレンダリングが背後でどのように動いているかを理解する必要はなく、 matrixcolor
や Live2D のような機能のサポートはモデルベースのレンダリングの動作を理解しなくても使用できます。しかし理解すればそのような機能を追加できるでしょう。このドキュメントはかなり高度な制作者または Ren'Py 本体に機能を追加したい開発者を対象とします。
モデルベースのレンダリングは Ren'Py の最も高度な機能の1つであり、このドキュメントは先に OpenGL, OpenGL ES, GLSL ES のマニュアルを読んでおかなければ理解が難しいでしょう。さらに直接 GPU ドライバーに渡される部分があり、それらは間違った入力も受け付けてしまうので、複数種類のハードウェアでのチェックが重要となります。
モデル、レンダリング、描画処理 link
Ren'Pyが画面に描画する基本的なものはモデルです。モデルは次の要素で構成されます :
1つ以上の三角形のメッシュ。三角は3つの角となる頂点で構成され、それぞれ2次元、または三次元の位置を格納し、追加情報を持つ場合もあります。追加情報の多くはテクスチャの座標です。
0枚以上のテクスチャー。ゲームで動作可能な正確な枚数は GPU によって制限されます。すべての GPU は 1 つのモデルにつき最低 3 つのテクスチャをサポートするはずです。テクスチャとは GPU に直接または render-to-texture 操作でロードされた 画像データを含む矩形のことです。
シェーダーパーツ名の一覧。Ren'Py はこれらのシェーダーパーツを使って、モデルをレンダリングするために GPU 上で実行されるプログラムであるシェーダーを作成します。シェーダーパーツの名前の前に "-" をつけると、そのシェーダーパーツを使用しないようにできます。
uniform 値。 uniform は、そのモデル全体で一定である追加データです。例えばそのモデルが solid カラーを表現するなら、その色が uniform です。
GL プロパティー。GL プロパティーは minification/magnification モードやカラーマスクのようなレンダリング方法をさらに制御するためのフラグです。
Ren'Py は通常複数のものを画面に描画するので、 Render
オブジェクトのツリーを作成します。これらのレンダーオブジェクトは、モデルや他のレンダーを子として持てます ( 後述するように、レンダーオブジェクトをモデルにもできます)。レンダーは以下のものを含みます。 :
各子に対して適用される2次元のオフセットを含む子のリスト
3次元空間において、子がどのように transform されるかを記述した
Matrix
描画時にモデルに適用されるシェーダーパーツ名のリスト、uniform、GLプロパティー
ポリゴンを切り取る描画可能空間が更新されるべきかどうかを決定するフラグ。
Ren'Py は、レンダーのツリーを深度優先で探索し、モデルに出会うまで画面を描画します。この探索の間、Ren'Pyはモデルの位置を transform する matrix, ポリゴンの切り取り、シェーダーパーツのリスト、uniform、gl プロパティーを更新します。この探索の過程でモデルに遭遇すると、適切なシェーダプログラムが GPU 上で起動され、すべての情報が渡され、描画処理が実行されます。
どこでモデルが作成されるか link
Ren'Py は通常の操作の一環として、自動的にモデルを作成します。モデルがどこで作られるかを理解する主な動機は、モデルが描画処理に対応し、それゆえシェーダーが適用される単位となるからです。
- 画像と画像マニピュレータ
これらはメッシュを持つモデルを作成し、そのメッシュには画像の矩形をカバーする2つの三角形を含みます。そのメッシュにはテクスチャ座標も含みます。このモデルは "renpy.texture" シェーダを使用します。
Solid()
Solid Displayable は 2 つの三角形を含むメッシュを作成し、テクスチャ座標はありません。このモデルは "renpy.solid "シェーダーを使用し、その色は
u_renpy_solid_color
の uniform に配置されています。Dissolve()
,ImageDissolve()
,AlphaDissolve()
,Pixellate()
,AlphaMask()
,Flatten()
これらの transform と Displayable はそれぞれその目的に必要なメッシュ、シェーダー、 uniform を持つモデルを作成します。
- Live2D
Live2D Displayable はレンダリング時に複数のモデルを作成し一般的にレイヤーごとに1つのモデルがあります。
Transform()
と ATLmesh
が True またはblur
が使用されているなら、 Transform はモデルを作成します。この場合、Transform の子はテクスチャにレンダリングされ、そのモデルに関連するメッシュとして最初のテクスチャのメッシュが使用されます。すべての transform がモデルを作成するわけではありません。いくつかの transform は単に Render にシェーダーや uniform を追加するだけです (
blur
やalpha
を使用する transform など ) 。その他の transform は単純に幾何学的な影響を与えるものです。Render
transform は
mesh
attribute が True ならモデルを作成します。この場合、その Render の子はテクスチャにレンダリングされ、そのモデルに関連するメッシュとして最初のテクスチャのメッシュが使用されます。
将来的にモデルを作成するさらに他の方法が Ren'Py に追加されると期待されます。
シェーダープログラムの生成 link
Ren'Py はまずシェーダーパーツ名のリストを組み立てて、シェーダープログラムを生成します。このリストは、 "renpy.geometry", レンダーから取得したシェーダーパーツのリスト、描画中のModelにあるシェーダーパーツのリストで構成されています。
その後、シェーダーパーツは重複排除されます。 "-" で始まるシェーダーパーツはリストから削除され、先頭の "-" を除いたものと同じシェーダーパーツも削除されます ( つまり "-renpy.geometry" はそれ自身と "renpy.geometry" を削除します ) 。
続いて Ren'Py は、シェーダーパーツのリストを受け取り、変数、関数、 vertex シェーダーパーツ、フラグメントシェーダーパーツのリストを取得します。これらは順番にシェーダーのソースコード生成に使われます。 vertex シェーダーとフラグメントシェーダーのパーツは、番号の小さいものから大きいものへと優先順位をつけて含まれます。
つまり、あるシェーダで作成された変数は、そのシェーダパーツのリストにある他のシェーダから成るあらゆるパーツからアクセスできるようになります。 Python の関数のように、シェーダ間の干渉を防ぐためのスコープは存在しません。
Ren'Py はこれまでに使用されたすべてのシェーダーパーツの組み合わせを game/cache/shaders.txt にキャッシュしておき、起動時にそれらを読み込みます。シェーダーの使用に大きな変更があった場合は、このファイルを編集または削除して、有効なデータで再作成できるようするべきです。
カスタムシェーダーの作成 link
renpy.register_shader 関数を呼び出して GLSL シェーダーの部品を提供すると新しいシェーダーパーツが作成できます。
一般的に、シェーダーパーツは "mygame.recolor" や "mylibrary.warp" のような "namespace.part" の形式であるべきです。 "renpy." や "live2d." で始まる名前は _ で始まる始まるもの同様に Ren'Py で予約されています。
- renpy.register_shader(name, **kwargs) link
これはシェーダーパーツの登録をします。 name とその後に続くキーワード引数を受け取ります。
- name
登録するシェーダーパーツの名前の文字列です。アンダースコアや "renpy." で始まる名前は Ren'Py で予約されています。
- variables
登録するシェーダーパーツで使用される変数です。これらは行ごとに (uniform や attribute, varying のような)ストレージに続いて、型、セミコロンとなるべきです。例
variables=''' uniform sampler2D tex0; attribute vec2 a_tex_coord; varying vec2 v_tex_coord; '''
- vertex_functions
指定するなら vertex シェーダーに含まれる関数を含める文字列です。
- fragment_functions
指定するなら fragment シェーダーに含まれる関数を含める文字列です。
他のキーワード引数は "fragment_200" や "vertex_300" のように
vertex_
やfragment_
から始まり、優先度を表す数値で終わるべきです。これらは優先度の数値順に適切なシェーダーに配置されるテキストを指定します。
Ren'Py では次の型の変数のみをサポートします。 :
float (Python の浮動小数点)
vec2 (2つの浮動小数のタプル)
vec3 (3 つの浮動小数のタプル)
vec4 ( 4 つの浮動小数のタプル)
int (Python の整数)
ivec2 (2 つの整数のタプル)
ivec3 (3 つの整数のタプル)
ivec4 (4 つの整数のタプル)
bool (Python のブール値)
bvec2 (2 つのブール値のタプル)
bvec3 (3 つのブール値のタプル)
bvec4 (4 つのブール値のタプル)
type[n] ([type] 型(上記いずれかの型)の [n] 要素の配列 (例えば、 int[5] は 5 つの整数の配列))
mat2 (
Matrix
)mat3 (
Matrix
)mat4 (
Matrix
)sampler2D (Displayabe または Displayables か Render を指定する文字列)
Uniform 変数は u_ で、 attribute は a_, varying 変数 は v_ で始めるべきです。 u_renpy_ や a_renpy、v_renpy で始まる変数は後述する標準的な変数同様に予約されています。
優先順位に対する基本的な考え方としては、優先度 100 でジオメトリを設定し、優先度 200 で初期のフラグメントカラー(gl_FragColor)を決定し、より高い番号の優先度ではその色を変更するエフェクトを適用できます。
こちらはレンダリングに使用される各モデルにグラデーションを適用するカスタムシェーダーパーツの例です。
init python:
renpy.register_shader("example.gradient", variables="""
uniform vec4 u_gradient_left;
uniform vec4 u_gradient_right;
uniform vec2 u_model_size;
varying float v_gradient_done;
attribute vec4 a_position;
""", vertex_300="""
v_gradient_done = a_position.x / u_model_size.x;
""", fragment_300="""
float gradient_done = v_gradient_done;
gl_FragColor *= mix(u_gradient_left, u_gradient_right, gradient_done);
""")
これによりカスタムシェーダーが transform を使用して適用できます。
transform gradient:
shader "example.gradient"
u_gradient_left (1.0, 0.0, 0.0, 1.0)
u_gradient_right (0.0, 0.0, 1.0, 1.0)
show eileen happy at gradient
前述したように、example.gradient シェーダの gradient_done
変数は、同じリストから適用される他のすべてのシェーダからアクセス可能になります。これは、あるシェーダシステムにオプションのパーツがある場合に便利ですが、独立した2つのシェーダを使用する場合に名前の衝突を引き起こす可能性もあります。
GLSL Version サポートされる GLSL のバージョンはプラットフォームに依存しますが、最も制限されるのはモバイルとウェブプラットフォームです。これらは GLSL ES 1.00 を使用します。 Ren'Py は高い精度を持つよう変数を宣言して、 2-62 から 262 の範囲の浮動小数点数をサポートします。 0 でな浮動小数点数は 2-62 と 262 の間の大きさであるべきで、整数は -216 から 216 までであるべきです。実際のハードウェアはしばしばより大きな範囲をサポートしますが、これは保証外です。
カスタムシェーダーのデバッグに役立つ変数があります。 :
- define config.log_gl_shaders = False link
True なら GLSL シェーダープログラム用のソースコードが起動時に log.txt に書き加えられます。
シェーダー パーツのローカル変数 link
変数は、接頭辞として u__
, a__
, v__
または l__
のいずれかを使用してシェーダローカルに宣言できます。このときすべてのドットがアンダースコアに置き換えられたシェーダー名で二重アンダースコアが置き換えられます。たとえば、シェーダ名が example.gradient
の場合、接頭辞 u__
は u_example_gradient_
に置き換えられます。
これは主な用途は テキストシェーダー であり、そこではほとんどの uniform がシェーダーローカルです。また、シェーダー内のローカル変数は l__
と宣言する必要があります。
Transform とモデルベースのレンダラリング link
モデルベースのレンダリングは次のプロパティーを ATLと Transform()
に追加します :
- mesh link
- Type:
None or True or tuple
- Default:
None
None でなければ、この Transform はモデルとしてレンダリングされます。 つまり :
メッシュが作成されます。これが 2 要素のタプルなら、 x 方向と y 方向のメッシュ内のポイント数として取得されます(各次元で少なくとも 2 でなければいけません)。 True の場合、そのメッシュは子から取得されます。
この transform の子はテクスチャにレンダリングされます。
renpy.texture シェーダーが追加されます。
デフォルトでは、メッシュで使用されるテクスチャはミップマップが作成されません。ミップマップが必要な場合は、
gl_mipmap
を True に設定する必要があります。
- mesh_pad link
- Type:
None または tuple
- Default:
None
None でない場合、これは 2 成分または 4 成分のタプルにです。 mesh が True でこれが与えられた場合、これはメッシュで使用されるテクスチャに適用されるテクスチャのサイズにパディングを適用します。 2 成分ののタプルは右と下にパディングを適用し、4成分のタプルは左、上、右、下にパディングを適用します。
gl_pixel_perfect
プロパティーと組み合わせるとメッシュにテキストをレンダリングできます。 Ren'Py においてテキストは画面の解像度で描画されるため、メッシュに適用されるテクスチャの境界を越える可能性があります。数ピクセルのパディングを追加すると、テクスチャはより大きくなり、すべてのピクセルが表示されるようになります。例transform adjust_text: mesh True mesh_pad (10, 0) gl_pixel_perfect True shader "shaders.adjust_text"
上記はそのシェーダーに渡されるテクスチャに、そのテキストのすべてのピクセルを含むことを保証します。
- shader link
- Type:
None or str or list of str
- Default:
None
None またはこのレンダーを通して到達するモデル、 ( モデルが作成されるなら ) このレンダーに適用されるシェーダーパーツ名、シェーダーパーツ名のリストです。
- blend link
- Type:
None or str
- Default:
None
None または文字列です。この文字列が
config.gl_blend_func
で検索され、gl_blend_func プロパティーの値を取得します。ブレンドモードの変更に使用されます。サポートしているデフォルトのブレンドモードは "normal", "add", "multiply", "min", and "max" です(それぞれ通常、加算、乗算、比較(暗), 比較(明) の合成モードに相当します)。
加えて、 u_renpy でない u_ で始まる uniform は Transform プロパティーとして利用できます。 GL プロパティー は gl_ で始めると Transformプロパティとして利用できるようになります。例えば color_mask プロパティは gl_color_mask として利用可能です。
Blend 関数 link
- define config.gl_blend_func = { ... } link
ブレンドモード名をブレンド関数に対応付ける辞書です。ブレンドモードは、後述する gl_blend_func プロパティーに提供されます。
デフォルトのブレンドモードです
gl_blend_func["normal"] = (GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
gl_blend_func["add"] = (GL_FUNC_ADD, GL_ONE, GL_ONE, GL_FUNC_ADD, GL_ZERO, GL_ONE)
gl_blend_func["multiply"] = (GL_FUNC_ADD, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_FUNC_ADD, GL_ZERO, GL_ONE)
gl_blend_func["min"] = (GL_MIN, GL_ONE, GL_ONE, GL_MIN, GL_ONE, GL_ONE)
gl_blend_func["max"] = (GL_MAX, GL_ONE, GL_ONE, GL_MAX, GL_ONE, GL_ONE)
Ren'Py は乗算済みアルファを使用しているため、ピクセルが不透明でない場合、これらの一部の結果は直感に反する可能性があります。GPU では、色 (r, g, b, a) は (r * a, g * a, b * a, a) として表され、ブレンド関数はこれらの事前に乗算された色を使用します。描画されるものが完全に不透明でない場合、ペイントソフトでのこれらのブレンドモードからものとこれは異なる結果になる場合があります。
Float, Sample, Vector Uniform link
次の uniform はすべてのモデルで利用可能です。
vec2 u_model_size
Ren'Py に渡すモデルの幅と高さです。これはサイズのある 2D model に対してのみ有効であり、3d model では (0, 0) です。
float u_lod_bias
テクスチャ参照に適用される詳細バイアスのレベルです。これは Transform で設定されるかもしれません。デフォルト値は
config.gl_lod_bias
から取得され、デフォルトでは -0.5 です。この値は Ren'Py が常に次の大きなレベルを選択して、それをスケールダウンするようにバイアスをかけます。float u_time
そのフレームの時間です。エポックは未定義なので秒ごとに増える数値として扱うとよいです。この時間は 86400 の剰余なので、一日ごとに 0.0 にリセットされます。
vec4 u_random
フレームごとに (非常に高い確率で) 異なる 0.0 から 1.0 の間の 4 つの乱数です。
vec4 u_viewport
これは現在内部に描画が行われている viewport を指定します。 u_viewport.xy は ウィンドウの左下隅を基準にした viewport の左下隅の座標です。 u_viewport.pq はその viewport の幅と高さを表します。
vec2 u_virtual_size
これはゲームの仮想サイズです (
config.screen_width
,config.screen_height
) 。これを使用して、gl_Position 座標から仮想座標に変換使用できます。 :v_position = u_virtual_size * vec2(gl_Position.x * .5 + .5, -gl_Position.y * .5 + .5)
vec2 u_drawable_size
ウィンドウの描画可能領域のサイズです。ゲーム実行時の解像度でのピクセル数になります。例えば 1280x720 のゲームが 1980x1080 にスケーリングされていれば、これは (1920, 1080) になります。
sampler2D tex0
,sampler2D tex1
,sampler2D tex2
テクスチャが利用可能なら、対応するサンプラーがこの変数に格納されます。
vec2 res0
,vec2 res1
,vec2 res2
テクスチャが利用可能なら、そのテクスチャのサイズがこれらの変数に格納されます。テクスチャがディスクから読み込まれたときはこれは画像ファイルのサイズで、テクスチャにレンダリングされた後はレンダリングされたテクスチャ上で描画されるピクセルの数です。
加えて、 sampler uniform が利用可能なら、 __res
を接尾辞に加えると、下層のテクスチャーサイズを含む vec2 が所得できます。例えば u_markup__res
は u_markup
テクスチャーのサイズを与えます。
vec4 uniform が利用可能なら、 __premul
を接尾辞に加えると、下層の乗算済みの色を含む vec4 が所得できます。例えば u_color_premul
は RGB チャンネルのアルファチャンネルで乗算済みの色を与えます。
Matrix Uniform link
以下の uniform はすべてのモデルに用意されています。これは、モデルのレンダリングに perspective
プロパティーを指定された 1 つの transform のみが使用されることを前提としています。perspective
を持つ複数の transform が使用されている場合、 perspective が設定されている最も内側の transform が world 空間と view 空間を定義します。
mat4 u_projection
これは、 view 空間から OpenGL viewport に座標を変換するマトリックスです。これは Ren'Py によって送信され、
perspective
プロパティーを指定された transform によってそのプロパティのー効果をカプセル化するために更新されます。mat4 u_view
これは、 world 空間から view 空間に頂点座標を変換するマトリックスです。これはデフォルトでは単位行列に設定されていますが、
perspective
プロパティーを指定された transform によって設定でき、その場合は配置、回転、スケーリングの効果がこのマトリックスにカプセル化されます。mat4 u_model
これは、 model 空間から world 空間に頂点座標を変換するマトリックスです。
mat4 u_projectionview
このマトリックスには
u_projection * u_view
が含まれています。これは、GPU に送信する必要がある uniform の数と、シェーダーで実行する必要がある作業の量を最小限に抑えるために存在します。mat4 u_transform
これは
u_projectionview * u_model
と同じです。これは、頂点座標を直接 OpenGL viewport に変換するマトリックスです。これは、GPU に送信する必要がある uniform の数とシェーダーで実行する必要がある作業の量を最小限に抑える、および古いバージョンの Ren'Py との互換性のために存在します。
これらの方法に加えて、Ren'Py はマトリックスに接尾辞が追加されたときに特定の関数によりマトリックスを合成できます
__inverse
マトリックスに追加すると、その行列の逆行列が返されます。例えば、
u_projection_inverse
は逆 projection 行列です。__transpose
マトリックスに追加すると、その行列の転置行列が返されます。例えば、
u_view_transpose
は view 行列の転置です。__inverse_transpose
マトリックスに追加すると、その行列の転置の逆行列が返されます。たとえば、
u_model_inversetranspose
はモデル行列の転置の逆行列です。これは法線を変換する場合に便利です。
Attribute link
次の attribute は、すべてのモデルで使用できます。
vec4 a_position
レンダリングされる頂点の位置です。これは、テクスチャの左上隅を基準とした仮想ピクセル単位です。
テクスチャが利用可能なら、次の attribute も使用可能です :
vec2 a_tex_coord
この頂点を投影するテクスチャ内部の座標です。
テクスチャが利用可能なら、次の attribute も使用可能です :
vec3 a_normal
レンダリングされた頂点の位置
テクスチャが利用可能なら、次の attribute も使用可能です :
vec3 a_tangent
レンダリングされた頂点のタンジェント
vec3 a_bitangent
レンダリングされたbitangent の位置
GL プロパティー link
GLプロパティーは、OpenGLやモデルベースのレンダラのグローバルな状態を変更します。これらのプロパティは Transform や Render.add_property()
関数で使用できます。
gl_blend_func
あればこれは6要素のタプルが期待され、すでに描画されているピクセルと描画するピクセルを合成する方程式と、その方程式のパラメータを設定するために使用されます。
具体的にはこれは (rgb_equation, src_rgb, dst_rgb, alpha_equation, src_alpha, dst_alpha) です。これらは次の呼び出しで使用されます。
glBlendEquationSeparate(rgb_equation, alpha_equation) glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha)
これらの関数が何をしているかは OpenGLのドキュメントを参照してください。OpenGL 定数は renpy.uguu からインポートできます。
init python: from renpy.uguu import GL_ONE, GL_ONE_MINUS_SRC_ALPHA
一般的に
blend
transform プロパティーがこれを使用する簡単な方法です。gl_color_mask
これには、ピクセルの4つのチャンネル(赤、緑、青、アルファ)に対応する真偽値の4タプルが期待されます。あるチャンネルが True であれば、描画処理でそのピクセルに書き込みます。そうでなければ、描画は行われません。
gl_cull_face
None でなければ、カメラから遠ざかっている三角形を削除するプロセスである face culling が有効になります。これを行うには、どちらの面が表面で、どちらが裏面であるかを知る必要があります。表面は、頂点の windling order (巻き上げ順)で決定され、これは "cw" (時計回り) または "ccw" (反時計回り) のいずれかです。値は Ren'Py の座標系 (+Y が下) で使用され、OpenGL 座標系とは逆です。
gl_depth
True の場合、 深度バッファをクリアし、この Displayable とこの Displayable の子に対して z バッファ法でのレンダリングを有効にします。
透明なピクセルであっても、任意のピクセルを描画すると、深度バッファが更新されることに注意してください。そのため透明度のある画像に使用すると、予期せぬ問題が発生する可能性があります( 別の方法として
show
ステートメントのzorder
やbehind
節を検討してください)。gl_pixel_perfect
True のとき、Ren'Py はメッシュの最初の頂点が画面上のピクセルと一致するように移動します。これは主にテキストと組み合わせて、テキストがシャープに保たれるようにするために使用されます。
次のプロパティーは、 mesh
が設定された Transform または Model()
によってテクスチャが作成されるときのみ、プロパティメソッドに渡され効果を持ちます。
gl_drawable_resolution
True または設定されていない場合、テクスチャーはウィンドウがゲームを表示しているのと同じ解像度でレンダリングされます。 False ならその Displayable の仮想解像度でレンダリングされます。
gl_anisotropic
与えられた場合、これはメッシュに渡されるテクスチャが異方性で作成されてるかどうかを判断します。異方性とは、テクスチャーが X と Y で異なる量だけズームされたときに、複数のテクセル(テクスチャピクセル)がサンプリングされる機能です。
これはデフォルトでは True です。 Ren'Py は Pixellate のような特定のエフェクトのためにこれを False に設定します。
gl_mipmap
与えられた場合、これはメッシュに渡されるテクスチャがミップマップで作成されるかどうかを決定します。デフォルトは True です。
gl_texture_wrap
与えられた場合、これはメッシュに適用されるテクスチャがどのようにラップされるかを決定します。これには2要素のタプルが期待され、最初の要素は GL_TEXTURE_WRAP_S を、 2番目の要素は GL_TEXTURE_WRAP_T を設定するために用いられます。これらは通常、作成されたテクスチャの X 軸と Y 軸を表します。
値は OpenGL に含まれ、 renpy.uguu からインポートされます。
init python: from renpy.uguu import GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, GL_REPEAT
これは、特定のテクスチャ用にカスタマイズすることもできます。 gl_texture_wrap_tex0 は最初のテクスチャをコントロールし、 gl_texture_wrap_tex1 は2番目のテクスチャを、 gl_texture_wrap_tex2 は3番目、 gl_texture_wrap_tex3 は4番目のテクスチャを制御します。Transforms ではこの4つのみが利用可能ですが Render.add_property には "texture_wrap_tex4" や "texture_wrap_myuniform" も渡せます。
GLTF モデル Displayable link
GLTFModel displayble により、 GLTF ファイル形式の 3D モデルをロードできます。これは、他のプログラムで作成した 3D モデルがあり、Ren'Py で表示したい場合に使用すべきものです。
- class GLTFModel(filename: 'str', shader: 'str | tuple[str]' = (), tangents: 'bool' = False, zoom: 'float' = 1.0, report: 'bool' = False, **kwargs) link
GLTF 形式で 3D モデルを 読み込む displayable です。この形式は多くの 3D ツールでサポートされています。Ren'Py は Open Asset Importer (assimp) ライブラリ を使用して GLTF モデルを読み込みます。
Ren'Py の 2D レイアウトシステムの目的上、GLTFModel の幅と高さはゼロです。デフォルトでは、モデルはそれを含むファイルにあるサイズでロードされます。必要に応じて、 zoom を使用して拡大縮小できます。
複数のモデルを使用している場合は、深度テストを有効にするために、カメラに
gl_depth True
プロパティーを指定する必要があります。Ren'Py は現在、モデルの間引きを実行していないため、完全にレンダリングできるほど単純なモデルの使用が重要です。- filename
表示するモデルのファイル名
- shader
使用するシェーダーの名前の文字列または文字列のタプルです。
- tangents
True なら tangent がメッシュに含まれます。
- zoom
モデルに適用される倍率係数です。多くのモデルは素直に -1 から 1 の範囲を使用するため、モデルを表示するためにこれを非常に大きくする必要がある場合があります。
- report
True の場合、モデルのレポートがログに出力されます。これには、モデルが使用する uniform が含まれます。
GLTF 形式で 3D モデルを 読み込む displayable です。この形式は多くの 3D ツールでサポートされています。Ren'Py は Open Asset Importer (assimp) ライブラリ を使用して GLTF モデルを読み込みます。
Ren'Py の 2D レイアウトシステムの目的上、GLTFModel の幅と高さはゼロです。デフォルトでは、モデルはそれを含むファイルにあるサイズでロードされます。必要に応じて、 zoom を使用して拡大縮小できます。
複数のモデルを使用している場合は、深度テストを有効にするために、カメラに
gl_depth True
プロパティーを指定する必要があります。Ren'Py は現在、モデルの間引きを実行していないため、完全にレンダリングできるほど単純なモデルの使用が重要です。- filename
表示するモデルのファイル名
- shader
使用するシェーダーの名前の文字列または文字列のタプルです。
- tangents
True なら tangent がメッシュに含まれます。
- zoom
モデルに適用される倍率係数です。多くのモデルは素直に -1 から 1 の範囲を使用するため、モデルを表示するためにこれを非常に大きくする必要がある場合があります。
- report
True の場合、モデルのレポートがログに出力されます。これには、モデルが使用する uniform が含まれます。
注意点がいくつかあります :
一部のモデルは非常に小さく、100倍または1000倍にズームする必要があります。
各モデルによって生成される uniform が異なる可能性があります。
report=True で GLTF モデルを作成し、log.txt を見てサイズと何が利用可能かの確認をお勧めします。その後、モデルをスケーリングし、適切なシェーダーを作成できます。
制限 link
GLTFModel には現在デフォルトのシェーダーが含まれていないため、シェーダーを定義して含める必要があります。以下は、GLTFModel で使用できるシェーダーの 1 つです
init python:
renpy.register_shader("example.lighting", variables="""
uniform mat4 u_model__inverse_transpose;
uniform vec4 u_color_diffuse;
uniform vec4 u_color_specular;
uniform sampler2D u_tex_diffuse;
varying vec3 v_normal;
varying vec2 v_tex_coord;
attribute vec3 a_normal;
attribute vec2 a_tex_coord;
""", vertex_201="""
v_normal = (u_model__inverse_transpose * vec4(a_normal, 1.0)).xyz;
v_tex_coord = a_tex_coord;
""", fragment_201="""
// The direction of the light.
vec3 lightDir = normalize(vec3(0.0, -1000.0, 1000.0));
vec3 normal = normalize(v_normal);
float lambertian = max(dot(normal, lightDir), 0.0);
vec4 diffuse_color = texture2D(u_tex_diffuse, v_tex_coord.xy);
diffuse_color *= vec4(lambertian * u_color_diffuse.rgb * u_color_diffuse.a, u_color_diffuse.a);
vec3 viewDir = normalize(vec3(0.0, 0.0, -1.0));
vec3 halfDir = normalize(lightDir + viewDir);
float specular = pow(max(dot(normal, halfDir), 0.0), 4.0);
vec4 specular_color = vec4(u_color_specular.rgb * u_color_specular.a * specular, u_color_specular.a * specular);
gl_FragColor = diffuse_color + specular_color;
if (gl_FragColor.a < 0.9) {
discard;
}
""")
これは、単一の光源に基づいてモデルに拡散照明と反射光を適用する非常に単純なシェーダーであり、より優れたシェーダーが作成されるまでの実験を目的としています。
GLTFModel は透明なサーフェスをうまくサポートしていません。上記の discard コマンドは透過性をエミュレートしますが、順序が少し間違っており、誤りが発生する可能性があります。
モデル Displayable link
モデル Displayable はモデルベースのレンダラーで使用するためのモデルを作成するのに役立ちます。
- class Model(size=None, **properties) link
これは Ren'Py にモデルベースのレンダラーで使用する 2D や 3D のモデルを作成させる Displayable であり、ここで指定したシェーダーを使用して単一の処理により、または囲んでいるTransform や Displayable によって選択されて描画されます。
- size
None でなければ幅と高さのタプルで、そのモデルのサイズを指定するのに使用されます。指定されないと、そのモデルは与えられた領域のサイズになります。テクスチャへの fit パラメータがより優先されます。
mesh メソッドが呼び出されない場合、少なくとも1つのテクスチャを与えられれば Ren'Py がテクスチャをロードする方法に合わせて a_position と a_tex_coord を設定するメッシュが作成され、そうでなければ a_position のみを設定するメッシュが使用されます。
このクラスのすべてのメソッドはそのメソッドが呼び出された Displayable を返すのでチェーン呼び出しが出来ます。
- child(displayable, fit=False) link
これは focus と main パラメーターが True に設定される他は texture メソッドと同じです。
- grid_mesh(width, height) link
width x height の等間隔のポイントを持つグリッドで構成されるメッシュを作成し、各ポイントを垂直および水平方向の最も近いポイントに接続し、作成されたグリッド内の各長方形を三角形に分割します。
- width, height
水平、垂直方法のポイント数で、少なくとも2以上の整数です。
- property(name, value) link
gl プロパティーの値を設定します。
- name
GL プロパティーの名前を指定する文字列で、 "gl_" 接頭辞を含みます。
- value
gl プロパティーの値
- shader(shader) link
このモデルにシェーダーを追加します。
- shader
このモデルで使用するシェーダーの名前の文字列です。
- texture(displayable, focus=False, main=False, fit=False, texture_wrap=None) link
指定の Displayable をレンダリングしてこのモデルにテクスチャを追加します。追加される最初のテクスチャは
tex0
で、 2つ目はtex1
と続きます。- focus
True なら、フォーカスイベントがその Displayable に渡されます。ここではそのモデルに対する相対座標がその Displayable に帯する相対座標と 1:1 で対応すると想定しています。
- main
True なら、これは Displayable インスペクターに検知されるこの Displayable のメインの子としてマークされます。
- fit
True なら、モデルにはその Displayable のサイズが指定されます。これは1つのテクスチャに対してのみ True でしょう。
- texture_wrap
None またはこのテクスチャに適用される gl_texture wrap GL プロパティー です。
- uniform(name, value) link
シェーダーに渡される uniform の値を設定します。
- name
uniform の名前の文字列で、 "u_" を接頭辞に持ちます。
- value
uniform の値です。浮動小数、浮動小数の2, 3, 4要素のタプルまたはマトリックスです。
モデル Displayable 例 link
このモデル Displayable は、ATL transform と組み込みのシェーダを組み合わせてディゾルブ transform 作成に使用できます。
transform dt(delay=1.0, new_widget=None, old_widget=None):
delay delay
Model().texture(old_widget).child(new_widget)
shader [ 'renpy.dissolve' ]
u_renpy_dissolve 0.0
linear delay u_renpy_dissolve 1.0
モデル Displayable を Displayable の子に使用すると 2つ共が Ren'Py 内にモデルを作成するので、 mesh
と互換性がなくなります。
アニメーションシェーダー link
u_time
に依存してアニメーションするシェーダーを使用するとき、画面のすべてのシェーダーが表示されるすべてのフレームで実行されてさえ、 Ren'Py が一定の FPS では動作せず、再描画する displayable がなければ、5 FPS の最小フレームレートに落ち込むことに気をつけてください。
ATL transform でアニメーションシェーダーを使用するとき、このことがシェーダーにカクツキを起こさせたり、使用している transform が他に再描画を起こさせない場合、画面の他のオブジェクトがアニメーションする間だけ正常にアニメーションさせたりするかもしれません。この場合は空の ATL ループを加えて再描画の実行を強制できます。
transform fancy_shader:
shader 'my_fancy_shader'
pause 0
repeat
pause 0
はそのフレームを可能な限り早く繰り返します。 pause
に pause 1.0/30
のような異なる値を設定して、最終フレームレートの指定もできます。
シェーダー パーツ link
Ren'Py が使うシェーダーパーツの一覧は デフォルトのシェーダーパーツ を参照してください。