試行錯誤プログラマの
メモランダム

トライ&エラーと対策方法の技術まとめ

【p5.js】react-p5で高フレームレート時のpush,popがおかしい

問題発生の経緯

draw()の最初にbackground()を呼び出して、描画をリセットするっていうのはp5(processing)の基本的な処理の一つだと思います。

今回は下記のような処理を書いたときに、予想と違う描画をされました。

  const draw = (p: p5Types) => {
    p.push();
    p.background("#ff9800");
    p.blendMode("screen");

  // ~描画処理~

    p.pop();
  };

ざっくりと処理の内容を説明すると

  • push()で初期の描画設定を保存(blendModeはデフォルトのnormal)
  • background()で色を指定して描画
  • 続くメインの描画処理のため、blendModeをscreenに変更
  • ~描画処理を行う~
  • 最後にpop()して描画設定を戻す(blendModeがnormalに戻る)

っていう流れになってます。

毎フレームpush,popで初期の状態に戻してbackground()しているので、指定した色(#ff9800)で描画されるはずなのですが、なぜか違う色でbackgroundされていました。。。

しかも、これ必ず起こるわけではなく、表示する端末によっては発生しやすかったり、全く発生しなかったりしました。。。

問題が発生する条件

で、試行錯誤した結果、なんでそうなるのかは不明ですが問題のある動作は発覚。

高フレームレートの際に、push,popが上手く動作しなくなる

つまり、デフォルトのnormalのblendModeにリセットされず、screenのモードのままbackground()していた動作となり、色が予想と違うことになってしまっていた ということです。

端末によって再現率が違ったのも、環境により出せるフレームレートが変わっていたからですね。

問題が発生する条件はわかったので、対応としてはこんな感じになりました。

  const draw = (p: p5Types) => {
    // ~初期化処理~
    p.blendMode("normal");

    p.background("#ff9800");
    p.blendMode("screen");

  // ~描画処理~
  };

素直に初期化処理は、push,popを使わずにするようにしました。blendModeをnormalに戻す処理を記載。そうすると予想通りの色で表示されるようになりました。

push,popはdraw処理内でリセットする必要がある際に使うもので、次フレーム以降のために初期化に使うものではないのかもしれませんね。。。

Kiyama
Kiyama

p5を使いこなせるよう頑張ります!