WebGL シェーダをどこに置くか?

stringとして置く

Three.jsだとjavascriptの中にstringとしておいています

var VSHADER_SOURCE =
         " attribute vec3 a_Position;\n" +
            " void main(void) {\n" +
            " gl_Position = vec4(a_Position, 1.0);\n" +
            " }\n";

シェーダのコード1つ1つが短い場合はこれでもいいかもしれないけど、
この方式はあとで修正したりが面倒だし、正しくシンタックスハイライトしないので見づらいという欠点があります。

バックスラッシュを使って改行する

var VSHADER_SOURCE = "attribute vec3 a_Position;\
             void main(void) {\
             gl_Position = vec4(a_Position, 1.0);\
             }";

こういうやり方でも動いた。
]\n" +」の代わりに「\」です。
打ち込む文字が1行ごとに3文字減りますね!

もっと減らせる。。!テンプレート文字列を使う方法

シェーダコードをバックティック文字`で囲みます。

var v =`attribute vec3 a_Position;
  void main(void) {
  gl_Position = vec4(a_Position, 1.0);
  }`;

これはもう完璧heredocですね!
テンプレート文字列とは?

<script>タグ内に書く方法

<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 a_Position;
             void main(void) {
             gl_Position = vec4(a_Position, 1.0);
             }
</script>

そしてjavascript側で取り出すとき
 var vertsrc =  document.getElementById("shader-vs").innerHTML;

あるいは
 var vertsrc =  document.getElementById("shader-vs").textContent;

<script>タグ内でシェーダコードをかけば、ページにシェーダコードは表示されません。
もしページにシェーダコードを表示したかったら<pre>タグを使えばok.
改行した状態で表示されます。

シェーダコードを外部ファイルから読み込む

外部といっても同じドメインのファイルです。
もしシェーダコードが何千行と膨大になってしまった場合は、シェーダコードを別のファイルにしたい。
そんな時はHttpRequestです[3]]
下のコードではためしに頂点シェーダだけ外部テキストで読み込んでます。

function main() {
     canvas = document.getElementById("webgl");
    var gl = getWebGLContext(canvas);//cuon-utils.jsより
    var shaderurl ="http://miffysora.wdfiles.com/local--files/webgl-where-to-put-shader/simplestvs.js";
    var request = new XMLHttpRequest();
    request.open('GET', shaderurl , true);
    request.onreadystatechange = function () {
        if (request.readyState == 4 &&request.status == 200) {
               var v=request.responseText;
               var fragmentsrc =document.getElementById("shader-fs").textContent;
               initShaders(gl, v, fragmentsrc);
              var n =  initGeometry(gl);
              display(gl,n);
            } else {
                console.log("Failed");
            }
    };
    request.send(null);
}

頂点シェーダとフラグメントシェーダと2つ外部テキストとして読み込むには。。?未調査です。
が、StackOverfrow[3]に英語で詳しく書いてあります。

demo

サポートサイト Wikidot.com