mieki256's diary



2021/09/20(月) [n年前の日記]

#1 [love2d] love2dでテクスチャ付きポリゴンを歪めずに描画したい。その3

love2d 11.3 上で、テクスチャ付きポリゴンを描画したい。できれば四角形を歪ませない状態で描画したい。

昨日、公式フォーラムで、Shader を使って実現している事例を ―― Perspective.lua、Demo v8.love という実装例を見かけたわけだけど。

_Textured Polygons for All! - LoVE
_Textured Polygons for All! - Page 13 - LOVE

昔の love2d 用に書かれたスクリプトだから love2d 11.3 では動かなかったわけで。

ということで、love2d 11.3 でも動くように修正してみた。

_demo_v8_love2d_11_3.zip

ダウンロードして、拡張子 .zip を .love にリネームすれば、以下の指定で実行できる。
love demo_v8_love2d_11_3.love

ちなみに、手元の環境、Windows10 x64 21H1 + love2d 11.3 では、.zip のままでも一応実行はできた。
love demo_v8_love2d_11_3.zip

念のために書いておくけど、.loveファイルの正体は、.zipファイルの拡張子を .love へとリネームしたもの。.love を .zip にリネームし直せば、解凍して中身を取り出すことができる。

動作させた際の様子は以下。




ちゃんと遠近感がついた感じの見た目で変形できていることが分かるかなと。素晴らしい。

構成ファイルについて。 :

一応念のために、各ファイルも置いておく。

_Perspective.lua
_shader.fs
_conf.lua
_main.lua

使用画像は、main.lua と同階層に textures というフォルダを作って、その中に入れておく。実際に使うのはどれか1ファイルだけど…。

_uvcheckermap01-512.png
_breaking_benjamin.png
_ff_nub.png
_lenac.jpg

これまた一応、構成ファイルや使い方も少し説明。

Perspective.lua と shader.fs が、処理の本体部分を担当。

元々のスクリプトでは、Perspective.lua の中に GLSLコードも含まれていたけど、今回は GLSLコード部分を shader.fs として別ファイルに分けてみた。こちらの使ってるエディタ(xyzzy)の関係で、複数行の文字列があると、ソースのフォーマットがしづらかったので…。

conf.lua と main.lua が、デモ用スクリプト。実行すると、四角形の各頂点を、マウスを使ってドラッグすることができる。

Perspective.lua (+ shader.fs) の利用の仕方は、以下のような感じ。
  • Perspective.lua を require で読み込んで、
  • 貼り付けたい画像も読み込んでおいて、
  • 四角形の頂点群(時計回り)をテーブルで用意して、
  • 描画時に :quad() を呼ぶ。

以下の記述で分かるだろうか…。

function love.load()
  tp = require 'Perspective'
  img = love.graphics.newImage('textures/uvcheckermap01-512.png')
  vert = {{100, 100}, {400, 100}, {400, 400}, {100, 400}}
end

function love.draw()
  tp:quad(img, vert[1], vert[2], vert[3], vert[4])
end

ライセンスについて。 :

ライセンスについては、元々の Perspective.lua、Demo v8.love の作者様(xXxMoNkEyMaNxXxさん)が「MITライセンスみたいな扱いでよろしく」と書いてくれているように見える。自分は英語がダメダメなのでちょっと自信無いけど…。

一応、該当する投稿を引用しておく。

_Textured Polygons for All! - Page 14 - LoVE
Post by xXxMoNkEyMaNxXx > Mon Dec 04, 2017 3:47 am

Returned from the grave to clarify that I would like people to use this as they see fit (something like an MIT liscence), just give me credit for my math! I love what you've done with it ghurk, I hope that people will continue to make useful modifications to this as long as it is still relevant. I am shocked at how well-commented the math in my original code is. I would usually just pile it all into one line using those mathy single letter variables. Looking through this from the start, I regret arguing with Ref about modifying my code, but it looks like I also regretted it in 2013 in one of my posts back then. I won't be active in this forum, but I'll probably visit again one day!

Textured Polygons for All! - Page 14 - LOVE より


ということで、自由に使っていいんじゃないかな…。たぶん。

解説図を眺めたけどよく分からない。 :

元々の Demo v8.love を解凍して中身を確認したら、中に Work というフォルダがあって、処理内容のヒントになるのであろう数式や解説図が入っていた。

しかし、自分の頭では、それらの解説図を眺めても処理内容がよく分からず…。以下でそのまま引用(?)してみるけれど…。

_maths.txt
sin theta=sqrt(1-cos^2 theta)

pA=v1+A*((p-v1) dot A)

length(p-pA)=r*sqrt(1-dot(A,B)^2)

r^2=((p.x-pA.x)^2+(p.y-pA.y)^2)/(1-dot(A,B)^2)

perspective_0_vp.png

perspective_1_vp.png

perspective_2_vp.png

四角形の各頂点の配置には、3つの状態がありえると考えて、パターンを分けて処理をしているところまでは分かる。 _GLSLコード にもif文があったので、そこでパターンを分けているのではないかなと…。

また、図を眺めた感じでは、消失点があるものと仮定して計算してそうな気もする。

ただ、分かるのはせいぜいそのぐらいで…。

まあ、何にせよ、件のGLSLのコードで、4点を与えれば遠近を意識した変形ができるのは間違いなさそう。実際動いているわけだし。

昔のlove2d用のGLSLコードについて。 :

昔の love2d は、現在 Shader と呼んでいる機能を、PixelEffect という名前で提供していたらしいのだけど。

_PixelEffect - LOVE
_love.graphics.newPixelEffect - LOVE

現在の love2d 11.3上で、newPixelEffect() を newShader() に置換して動かした際、描画時の見た目がおかしくなってしまった。どうやら当時は、y座標だかv座標だかの上下が、今とは逆だったようで…。

もし、昔の love2d 用に書かれた PixelEffect を、今の love2d の Shader に移植(?)する時は、そのあたりを意識して修正したほうがいいのかもしれない。と、一応メモしておく。

// before

vec4 effect(vec4 colour, Image UNUSED1, vec2 UNUSED2, vec2 inverted)
{
  vec2 p = vec2(inverted.x, SIZEY - inverted.y);  //SO ANNOYING

// after

vec4 effect(vec4 colour, Image UNUSED1, vec2 UNUSED2, vec2 inverted)
{
  vec2 p = vec2(inverted.x, inverted.y);

love2dのpolygonについて。 :

四角形を変形して描画するあたりは何を使ってるのかなと思ったら、love.graphics.polygon() を使っていたので結構驚いた。polygon() って単色塗りの多角形しか描画できないのとちゃうんか…。

polygon() で描画する前に、setShader( glsl ) でシェーダーを切り替えているのがポイントらしい。シェーダーを切り替えると、各描画機能は、切り替えたそのシェーダーを使った状態で動作するようで…。

待てよ? ということは、例えば長方形を描画する rectangle() を呼ぶ前に、遠近感が付くようなシェーダーに切り替えてから描画すれば…。画面の下半分に奥行きがあるような床を描画しちゃったりできるんだろうか? そういうことができるなら、色々使い道がありそうな…。

以上、1 日分です。

過去ログ表示

Prev - 2021/09 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project