立方体にテクスチャを貼る

四角形は平面上にある図形なので、板状のものが表示されました。今回は立方体を表示しています。そのため立体感が出ています。 ...

上のものにテクスチャを立方体に貼ってみました。

私が作ったロゴをテクスチャとして使いました。

これが面ごとに貼られているのがわかります。背景がグレーなのは見やすさのためです。テクスチャが貼れるようになるといろいろなことができるようになります。CGのプログラミングではこの後は応用という感じだと思います。

テクスチャを貼るのは難しくないですが、ロードに関して問題が起きました。1つはPC上で単純にはテクスチャにアクセスできないことでした。もう1つはロードがすぐに終わらないために起こる問題です。

今回は問題が起こったので予想以上に難しかったです。

オリジン間リソース共有の対処

PC上にファイルを置いてブラウザで実行すると、オリジン間リソース共有(Cross-Origin Resource Sharing)によるバグが起こりました。ChromeのConsoleには次のようなエラーが出ました。

Uncaught DOMException: Failed to execute ‘texImage2D’ on ‘WebGLRenderingContext’: The cross-origin image at file:///C:/webgl/draw_cube_texture_animation/logo-icon.png may not be loaded.

というものです。

これをそのままサーバーにおいて実行すれば問題なく動くのですが、それだと作っているときに確認するのが大変になります。

私はローカルのPC上でサーバー(MAMP)を動かし、その上でWebGLのHTMLを実行しました。そうすると同じドメインにいると判定されているみたいでうまく動きました。(XAMPPとかでも良いはずです。たまたまMAMPが入っているのでそれを使っただけです。)

localhost:8888/webgl/draw_cube_texture_animation/canvas.html

のようにしてアクセスしました。

テクスチャのロード

Imageクラスを使って画像を読み込んでいます。

var image = new Image();

image.src = ‘パス’;

とすれば良いのですが、image.srcにパスをセットしたときからロードが始まります。そしてそれはすぐに終わるわけではありません。いつ終わるかわからないため、image.onloadにロード終了時に行う処理を入れておきます。完了してからテクスチャを作ることで正しくデータを読み込むことができます。

ただこのようにするとonloadが呼ばれる――ロードが完了するまでテクスチャが作れません。なので、ロードが終わる前にもテクスチャが使えるよう適当なデータ(ここでは1×1の青いピクセル)を使ってテクスチャにロードします。

テクスチャにデータをとりあえず入れておき、ロード完了時に正しいデータで差し替えるということで常にテクスチャを使うことができます。

このコードだと読み込み完了まではテクスチャを使ってはいけない(読み込み完了のタイミングは取れないが……グローバル変数とか使えばいけるかも。)

修正されたコードでは読み込み完了までは青いテクスチャとして表示される

表示されているサンプルは一瞬だけ青くなっていることがあります。それは1×1の青いテクスチャになっている間が存在するためです。

参考

MDN Web docsの『WebGL でのテクスチャの使用』を参考にしています。