WGGの活動log

都内でゲーム開発だったりVRだったりをしてるかもしれないエンジニアです. WGGは「ワグ」と読みます

p5.xr を使って Oculus Quest 2 で動くVRを作ってみる

この記事は Processing Advent Calendar 2020 の 20 日目の記事です

はじめに

夏頃まで Twitter で #つぶやきProcessing とか作って楽しんでいたのですが,最近少し忙しくなって,10月頃から Processing の活動ができていないです

今回は,10月に手に入れた Oculus Quest 2 を使って,p5.js でVRコンテンツを作ってみたお話です

Oculus Quest 2

www.oculus.com

最近発売した VR ヘッドセットです

Twitter では FaceBook アカウントを連携した瞬間に BAN されたみたいな話が話題になっていた気がしますが...

自分は大学時代にサークルで Oculus Rift CV1 と HoloLens の開発をしていたことがあり,結構久しぶりのVRで楽しみにしていました

WebXR

Oculus Quest 2 では, ブラウザアプリを使って WebXR (WebVR) を体験することができます.

WebXR 対応のページを,普通にPCのブラウザで開くと,↓のように XR NOT FOUND と出て見ることができません

f:id:wgg00sh:20201219193211p:plain

それを Oculus Quest など, VR対応の環境で見ると,VRコンテンツを表示できるようになります

f:id:wgg00sh:20201219193316p:plain

p5.xr

p5xr.org

p5.js は,ブラウザで動くCGコンテンツを作ることができますが,この WebXR には対応していません

しかし,p5.xr というライブラリを使って実現することができました

サンプルコードを見るとだいたいわかりますが,普段の p5.js 開発から, 一部の使用する関数を VR 用のものに変えるだけで使用できました

// 普段の処理
function setup(){
  createCanvas(windowWidth, windowHeight,WebGL)
}

// p5.xr 用の処理 (https://editor.p5js.org/stalgiag/sketches/YsmwJUs83 より引用)
function preload() {
  createVRCanvas();
}

function setup() {
  setVRBackgroundColor(200, 0, 150);
}

このように,VR開発の経験があまりなくても簡単に作ることができました

見た感じ,コントローラなどのハンドトラッキングにはまだ対応して居なさそうだったので,そのあたりまで作ってからこの記事書こうと思ってたのですが,時間が無くて辞めました

作ったもの

ここで表示しているコンテンツは,以前自分が p5.js で作った作品で,ソースコードもほぼそのまま移植して動かすことができました

↓に OpenProcessing への埋め込みを貼っていますが,GLSL 周りで環境依存のあるコードになってしまっていたので,使用しているPCによっては正しく表示されないかもしれません

www.openprocessing.org

終わりに

今年は去年ほどアドベントカレンダーに力入れられませんでしたが, Processing や p5.js を使って,こういう事もできるんだっ知ってもらえれば嬉しいです

おまけ

来年の PCD の募集が始まってて,今年は初参加でLTをさせていただいたので,来年もなにかできると良いのですが...

リプライで p5.js のプログラムを実行する TwitterBot を Raspberry Pi で作った話

Twitter Bot を作った話

ふと,↓こんなことを思いつきました

このツイートのうち,後者の方の仕組みでちょっと TwitterBot を作ったので,その仕組とかの話です

作ったbot

f:id:wgg00sh:20200725170613p:plain https://twitter.com/p5_bot

bot の遊び方

この bot が呟いてる, #p5js と付いているツイートを探します

このツイートに, $1 $2 のように $ から始まる文字があるので,その個数分数値を入力してリプライを送ります このツイートの場合, 3つですね

すると,元のプログラムから $1 $2 ... と書かれていた部分が,リプライで送った値に置き換わってプログラムが実行されます

続きを読む

パズドラWが終わるらしいので,結構プレイした自分の攻略情報とか纏めてみる

パズドラWが終わるというツイートが,パズドラ公式から発信されました

自分としては,パズドラ本編もパズドラWも (レーダーも) 同じくらい楽しんでいたので残念です
なので自分がプレイしたパズドラWの履歴をちょっと纏めてみたり, 少し攻略に関する情報とかを書いてみたいと思います

手持ち

f:id:wgg00sh:20200528202416p:plain
f:id:wgg00sh:20200528202428p:plain
f:id:wgg00sh:20200528202439p:plain

続きを読む

#つぶやきProcessing で限界までコードを圧縮する方法 (p5.js 編)

先日 (5/16), Processing Community Hangout Japan #01 というオンラインイベントがありました
その中で,#つぶやきProcessing についての話をしている方が居て,みんな1ツイートに収めるための文字数制限に苦労しているように感じたので,自分がやっているコード圧縮の手法をまとめて説明してみようと思います

www.youtube.com

#つぶやきProcessing について

以前書いた記事でも紹介したのですが, Twitter の1ツイートに収まる Processing のプログラムを書いて,実行結果と一緒にツイートする企画です
自分が以前作った作品を少し載せておきます


Processingでも, p5.js でも, Processing Python Mode でもどれでも大丈夫で (有利不利差はありそう), 最近は派生して #つぶやきGLSL なんてものもできてるらしいです


以前自分が書いた,つぶやきProcessing用の環境構築はこちら ↓

wgg.hatenablog.jp

プログラムを圧縮するために

ここから,圧縮技術について説明していきます.
今回,題材として 以前作ってみた以下の作品を圧縮する工程を紹介してみます

こちらのプログラムは 222文字で収まっています
Twitterでは, 半角文字だけで書けば280文字, #つぶやきProcessing のタグを付ければ 260文字ぐらい入ります
実際に書いてみればわかるのですが,文字数制限は非常に厳しく,中々満足に作ることができないです
その中で少しでも自分の表現を増やすために,あらゆる手段を使って文字数を減らしていきます

t=0,draw=e=>{t++||(createCanvas(w=900,w),w/=2,blendMode(DIFFERENCE),m=translate),clear(),m(w,w),f=e=>{if(e--<1)return;let r=3;for(;r-- >0;)push(),rotate(TAU/3*r+t/800),m(4e4/t+t*t/2e3,0),circle(0,0,t+200),f(e),pop()},f(3)}

圧縮前のソースコードは以下のようになります (507文字)
(ただし,以下のコードは元々書いたものを圧縮して↑のコードにしたわけではなく,この記事を書くために圧縮していない想定のコードを書き直しています)


function recursiveDraw(recursiveCount) {
  recursiveCount--
  if(recursiveCount<=-1){
    return
  }

  for(let i=0;i<3;i++){
    push()
    rotate(PI*2/3*i+frameCount/800)
    translate(40000/frameCount+frameCount*frameCount/2000,0)
    ellipse(0,0,frameCount+200,frameCount+200)
    recursiveDraw(recursiveCount)
    pop()
  }
}

function setup() {
  createCanvas(900,900)
}

function draw() {
  blendMode(BLEND)
  background(0)
  blendMode(DIFFERENCE)
  translate(width/2,height/2)

  recursiveDraw(3)
}

minify してみる

まずはソースコードを短くするには minifyツールを使って短縮してみるのが一番楽だと思います
以下のようなサイトやツールを利用して,ソースコードを意味をそのままで文字数を減らすことができます

javascript-minifier.com
www.npmjs.com

自分は以前書いた記事で紹介しているように,プログラムを保存するたびに minify を実行して圧縮後の文字数を表示するようにしています

function recursiveDraw(e){if(!(--e<=-1))for(let r=0;r<3;r++)push(),rotate(2*PI/3*r+frameCo
unt/800),translate(4e4/frameCount+frameCount*frameCount/2e3,0),ellipse(0,0,frameCount+200,fram
eCount+200),recursiveDraw(e),pop()}function setup(){createCanvas(900,900)}function draw(){blen
dMode(BLEND),background(0),blendMode(DIFFERENCE),translate(width/2,height/2),recursiveDraw(3)}

結構短くなったはずですが,まだ372文字あり,1ツイートに収めるには遠いです
しかしながら,このminify で圧縮してくれる要素は意識せずに書くことができるので,活用していきます

minify で圧縮された要素

minifier がいい感じにやってくれた内容を,一応確認してみます

不要なスペースの削除

多くの場合プログラムを書くときにインデントを付けて構造を見やすくするのですが,minifier ではそれを全部消してくれます
(自分でインデント崩した状態でコーディングするのは辛いので,これを自動で任せられるのは助かる)

変数名の簡略化

recursiveCounte に省略されてたりと,基本的に全ての変数を1文字で書いてくれます
これを利用すれば,自分でコーディングする際には意味がわからない命名をせずに書き,最後に minify で1文字に圧縮する事ができます

数値の表記変更

元のコードには 400002000 といった数値を使用していましたが minify 後は 4e4, 2e3 と指数表記にしてくれます
他にも,今回のコードでは使用していませんが,絶対値1未満の少数を書く場合, 0.54 などの 0 を省略して .54 のように書くことができますが,これも自動で行ってくれます

minifier でやってくれない圧縮を自力でする

ここまでは minifier が自動でやってくれるので,自分は意識して書く必要がないです
ここからは, minifier に頼らず 多少コードの意味が変わったとしても文字数を減らす工夫を行っていきます

function の省略
function setup() {
  createCanvas(900,900)
}

これは,↓のように書き直せます

setup=_=>{
  createCanvas(900,900)
}

引数がある場合は,

function recursiveDraw(recursiveCount){
f=i=>{

のように書きます

複数回使用した関数名の省略

元のコードでは translate を2回使用していますが,同じ関数を2回以上使用する場合は,短縮できる可能性があります

translate(40000/frameCount+frameCount*frameCount/2000,0)
translate(width/2,height/2)

m=translate
m(40000/frameCount+frameCount*frameCount/2000,0)
m(width/2,height/2)

のようにすると,少し文字数を減らせます
名前の長い関数を2回以上使う場合に特に有効です

p5 組み込み変数の省略と, setup の排除

processing (p5.js) には,mouseX, frameCount, width, height など,予め使える変数がいくつかあります
この中で,自分はframeCount, width, height をいい感じに省略できる方法を用意しました

t=0
draw=_=>{
  if(!t++){
    createCanvas(w=900,w)
  }
}


この書き方をすると, width, height は全て w で表わすことができ,
frameCount は tで表せます
更に, function setup(){} が不要になるのでかなりの短縮になります

ellipseを使わない, circle を使う

p5.js では円を描く際には ellipse() を使用することが多いですが,最新の p5.js 1.0 からは楕円ではなく真円を描く場合に circle() 関数が使えるようになりました.
これは, ellipse() に引数を3つ指定した場合と同じ挙動なので1文字の短縮になります

同様に, rect() も square() という正方形に限定して描画する関数がありますが,こちらは逆に名前が長くなるので使ってないです

translate の活用

絵を画面の中心に描きたい場合は結構多いと思います
その際には,各描画命令で座標を画面の真ん中にするのではなく, 初めに translate(w/2,w/2) とすると,その後の描画命令の引数が簡潔になる場合があります.
width を頻繁に使用する場合は, setup() 内で w/=2 を実行しておくのも良さそうです

ループ処理を圧縮する
for(i=0;i<3;i++){
}

a
for 文はこの用に書くのが一般的だとは思いますが,以下のように書くと少し短縮できます(ただしカウンタがずれるので他の箇所で処理が変わってくる可能性があります)

for(i=0;i--<3;){
}
background(0) ではなく clear() を使う

動画ものの作品を作る場合に, draw の中で描画内容を初期化するために background(0)などを使うことは多いと思います
しかし, 背景色をcss で設定しておくと,clear() で代用することができます
(つぶやきProcessing として若干レギュレーション違反な気がしなくもないですが)

ただし,background(0,5) などを使った残像表現をする場合は clear() では完全に消えてしまうのでおそらくできないです

PI*2 を TAU にする

角度を使う場合, PI*2 で360度を表すことは多いですが, TAU という定数が用意されているのでそちらを使うと1文字減ります

終わりに

こんな感じに,自分が使ってるテクニックを色々上げてみました
他にもまだまだ工夫できると思うので,もっと情報共有してつぶやきProcessingの表現力を増やしていきたいです