p5.js WebGL入門 7 3D テキスト

本稿は「18.6: createGraphics() as WebGL Texture – WebGL and p5.js Tutorial」YouTube動画と「Getting started with WebGL in p5」ページ(「p5.jsで始めるWebGL」で訳出済)の「Text」項を参考に、再構成しています。

3Dテキスト表現

p5.js WEBGLモードのキャンバスに文字を描画する方法は2つあります。1つはWEBGLモードで使用できるtext()関数を使う方法で、もう1つは、オフスクリーンキャンバスをテクスチャとして扱う方法です。

WEBGLモードのtext()関数

p5.jsのtext()はキャンバスに文字を描画する関数で、WEBGLモードでも使用できます。リファレンスのtext()関数項には次のように書かれています。

WEBGL: OpenTypeフォントとTrueTypeフォントタイプのフォントのみサポートされる。フォントはloadFont()関数を使って読み込む必要がある(上記サンプルを参照)。現状ではWEBGLモードでstroke()を使っても効果はない。

p5.jsでのフォントについては、「6_4:フォント p5.js JavaScript」や「6_5:Webフォントの使用 p5.js JavaScript」、「6_6:カスタムフォントの使用 p5.js JavaScript」、「11:テキストと文字表現 Creative Coding p5.js」、「15:タイポグラフィ(Typography)」で述べています。

次のコードは、Google FontsのTrade Windsを使って、テキストを回転させる例です。

let angle = 0;
let TradeWindsFont;
let imgElement;

function preload() {
    // トゥルータイプフォントを読み込む
    // https://fonts.google.com/specimen/Trade+Winds
    // WEBGL: you must load and set a font before drawing text.
    TradeWindsFont = loadFont('assets/TradeWinds-Regular.ttf');
}

function setup() {
    createCanvas(400, 300, WEBGL);
    angleMode(DEGREES);
    // このプログラムで使用するフォントを指定
    textFont(TradeWindsFont);
    // フォントのサイズとアライメント
    textSize(40);
    textAlign(CENTER);
    textLeading(100);

    // 平行投影カメラ
    orthoCamera = createCamera();
    // デフォルトのfar(widthとheightの大きな方=400)では、回転するテキストが見切れるので、もっと遠くまで見られるようにする
    // => 平行投影の視錐台のfarを大きくする
    orthoCamera.ortho(-width / 2, width / 2, -height / 2, height / 2, 0, 500);
    orthoCamera.setPosition(-0, -100, 250);
    orthoCamera.lookAt(0, 0, 0);

    // キャンバス右下に<img>要素を置く
    createImg('assets/kingkong.png', 'kingkong_poster', '', (elm) => {
        elm.elt.width = 50;
        elm.position(350, 230)
    });

}

function draw() {
    background(100);
    // ライティング
    ambientLight(100);
    pointLight(255, 255, 0, -100, 0, 100);

    // フォントの色
    fill(255, 255, 255);
    // テキストと3Dジオメトリを回転
    rotateY(angle);

    // 円錐
    translate(0, 20, 0);
    rotateZ(180)
    cone(20, 150);

    // 円環
    torus(50, 2);
    torus(100, 2);
    torus(150, 2);

    // 球体
    translate(0, -200, 0);
    sphere(120);

    // テキスト
    translate(0, 200, 0);
    rotateZ(180)
    fill(255, 0, 0);
    text('an       RKO\nRadio          Picture', 0, -50);

    // ページのクリックでアクションのオン/オフを切り替え
    if (isAction) {
        angle -= 1;
    }
}

let isAction = false;

function mousePressed() {
    isAction = !isAction
}

画面のクリックで回転のオン/オフが切り替わります。

オフスクリーンキャンバスをテクスチャとして扱う

オフスクリーンキャンバスをテクスチャとして扱う方法自体は「オフスクリーンキャンバスのテクスチャマッピング」で述べています。

ここでは同様のテクニックで、オフスクリーンキャンバスにテキストを描画し、それをテクスチャとして3Dジオメトリに適用します。

次のコードはその例です。なおこの方法ではコンピュータにインストールされているシステムフォントも使用できますが、テキストが回転するプログラムのデザイン上、システムフォントでは面白くないので、前の例と同じGoogle Fontを使っています。

let angle = 0;
let TradeWindsFont;
let imgElement;

function preload() {
    /// トゥルータイプフォントを読み込む
    // https://fonts.google.com/specimen/Trade+Winds
    // WEBGL: you must load and set a font before drawing text.
    TradeWindsFont = loadFont('assets/TradeWinds-Regular.ttf');
}

function setup() {
    createCanvas(400, 300, WEBGL);
    angleMode(DEGREES);

    offScreenCanvas = createGraphics(256, 256);
    offScreenCanvas.fill(255, 0, 0);
    offScreenCanvas.textFont(TradeWindsFont);
    offScreenCanvas.textSize(25);
    offScreenCanvas.textAlign(CENTER);
    offScreenCanvas.textLeading(60);

    // 平行投影カメラ
    orthoCamera = createCamera();
    // orthoCamera.ortho();
    orthoCamera.ortho(-width / 2, width / 2, -height / 2, height / 2, 0, 500);
    orthoCamera.setPosition(-0, -100, 250);
    orthoCamera.lookAt(0, 0, 0);

    // キャンバス右下に<img>要素を置く
    createImg('assets/kingkong.png', 'kingkong_poster', '', (elm) => {
        elm.elt.width = 50;
        elm.position(350, 230)
    });
}

function draw() {
    background(100);
    //offScreenCanvas.background(0, 0, 0, 0);

    ambientLight(100);
    pointLight(255, 255, 0, -100, 0, 100)

    // テキストと3Dジオメトリを回転
    rotateY(angle);

    // 円錐
    translate(0, 20, 0);
    rotateZ(180)
    cone(20, 150);

    // 円環
    torus(50, 2);
    torus(100, 2);
    torus(150, 2);

    // 球体
    translate(0, -200, 0);
    sphere(120);

    push();
    translate(0, 90, 0);
    rotateZ(180)
    offScreenCanvas.text('an       RKO\nRadio          Picture', 130, 20);
    texture(offScreenCanvas);
    noStroke();
    plane(350, 350);
    pop();

    if (isAction) {
        angle -= 1;
    }
}

let isAction = false;

function mousePressed() {
    isAction = !isAction
}

画面のクリックで回転のオン/オフが切り替わります。

なお回転する3DテキストのRKOはアメリカの古い映画会社の名前です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA