Hatena::Groupjavascript

JavaScriptで遊ぶよ

 | 

2011-10-01

WebGL の getUniformLocation/getAttributeLocation が面倒

19:23

WebGL のシェーダーを弄ってると、変数を増やしたり変えるたびに getAttributeLocation やら getUniformLocation をしないといけないので面倒。

こんなふうに↓

        shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
        gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

        shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
        gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);

        shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
        gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

        shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
        shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
        shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
        shaderProgram.colorMapSamplerUniform = gl.getUniformLocation(shaderProgram, "uColorMapSampler");
        shaderProgram.specularMapSamplerUniform = gl.getUniformLocation(shaderProgram, "uSpecularMapSampler");
        shaderProgram.useColorMapUniform = gl.getUniformLocation(shaderProgram, "uUseColorMap");
        shaderProgram.useSpecularMapUniform = gl.getUniformLocation(shaderProgram, "uUseSpecularMap");
        shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
        shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
        shaderProgram.pointLightingLocationUniform = gl.getUniformLocation(shaderProgram, "uPointLightingLocation");
        shaderProgram.pointLightingSpecularColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingSpecularColor");
        shaderProgram.pointLightingDiffuseColorUniform = gl.getUniformLocation(shaderProgram, "uPointLightingDiffuseColor");
lesson15/index.html at master from gpjt/webgl-lessons - GitHub

面倒なのでシェーダーのソースから変数を抜き出して getUniformLocation まで自動でやってもらう。

gl.useProgram(program);

var attributes = [];
var uniforms = [];
[vshaderSrc, fshaderSrc].forEach(function getVariables(src) {
  src.
    replace(/\/\*[\s\S]*?\*\//g, '').
    replace(/\/\/[^\n]*/g, '').
    split(';').
    forEach(function(line) {
      var m = line.match(/^\s*(uniform|attribute)\s+/);
      if (m) {
        var name = line.match(/(\w+)\s*$/)[1];
        switch (m[1]) {
           case 'attribute': attributes.push(name); break;
           case 'uniform': uniforms.push(name); break;
        }
      }
    });
});

attributes.forEach(function(name) {
  program[name] = gl.getAttribLocation(program, name);
  gl.enableVertexAttribArray(program[name]);
});

uniforms.forEach(function(name) {
  program[name] = gl.getUniformLocation(program, name);
});

変数の位置は program (シェーダープログラムオブジェクト)にでも入れておけば便利。あとでこんなふうに使えるから。

gl.uniformMatrix4fv(program.mvMatrix, false, mvMatrix);

JavaScript 側の変数名も合わせておけば覚えやすくて尚良し。


シェーダーを弄ることがなくなったら attributes.forEach とかのところを変数名の羅列にしとけばいい。

トラックバック - http://javascript.g.hatena.ne.jp/edvakf/20111001
 |