LoginSignup
54
43

More than 5 years have passed since last update.

こぴぺするだけ簡単 WebGL + GLSL テンプレート

Last updated at Posted at 2015-03-22

コピペするだけ

かんたん!

ソース

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <!-- フラグメントシェーダのソースコード -->
    <script id="fs" type="xs/fs">
      // フラグメントシェーダには時間の経過がtimeに秒単位で、
      // スクリーン解像度がresolutionにピクセル単位で入ってくる
      precision mediump float;
      uniform float time;
      uniform vec2  resolution;

      // HSV色空間を使うための関数
      vec3 hsv(float h, float s, float v){
        vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        vec3 p = abs(fract(vec3(h) + t.xyz) * 6.0 - vec3(t.w));
        return v * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), s);
      }

      // ジュリア集合を描くためのフラグメントシェーダ
      void main(void){
        vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / max(resolution.x, resolution.y);
        int j = 0;
        vec2 x = vec2(-0.345, 0.654);     // この辺変えると……
        vec2 y = vec2(time * 0.005, 0.0); // いろいろ変わるかも
        vec2 z = p;
        for(int i = 0; i < 360; i++){
          j++;
          if(length(z) > 2.0){break;}
          z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + x + y;
        }
        float h = abs(mod(time * 15.0 - float(j), 360.0) / 360.0);
        gl_FragColor = vec4(hsv(h, 1.0, 1.0), 1.0);
      }
    </script>
    <!-- 頂点シェーダのソースコード -->
    <script id="vs" type="xs/vs">
      // 頂点シェーダには一切手入れする必要なし
      attribute vec3 position;
      void main(void){
        gl_Position = vec4(position, 1.0);
      }
    </script>
    <script>
      // オンロードイベントがエントリポイント
      window.onload = function(){
        // 変数宣言
        var a, b, c, d, e, f, g, h, p, t, u, v, w, x, y, z;

        // document.getElementByIdをローカル変数に
        b = function(s){return document.getElementById(s)};

        // ウィンドウオブジェクト
        w = window;

        // ESCキーで描画を止めるためのイベントハンドラ
        w.addEventListener('keydown', k, true);

        // HTMLドキュメント内のcanvasへの参照
        c = b('c');

        // WebGLコンテキストの取得
        g = c.getContext('webgl');

        // プログラムオブジェクトの生成
        p = g.createProgram();

        // シェーダ生成関数
        h = function(i, j){
          // シェーダオブジェクト生成
          k = g.createShader(g.VERTEX_SHADER - i);

          // ソースの割り当て
          g.shaderSource(k, j);

          // シェーダのコンパイル
          g.compileShader(k);

          // シェーダのアタッチ
          g.attachShader(p, k);

          // ログをリターン
          return g.getShaderInfoLog(k);
        }

        // シェーダのコンパイルとリンク
        if(!h(0, b('vs').text) && !h(1, b('fs').text)){g.linkProgram(p);}

        // シェーダのリンクステータスをチェック
        e = g.getProgramParameter(p, g.LINK_STATUS);

        // プログラムオブジェクトの有効化
        g.useProgram(p);

        // uniformLocation格納用にオブジェクトを定義
        u = {};

        // uniform変数timeのロケーション取得
        u.time = g.getUniformLocation(p, 'time');

        // uniform変数resolutionのロケーション取得
        u.resolution = g.getUniformLocation(p, 'resolution');

        // VBO用のバッファオブジェクトを生成
        g.bindBuffer(g.ARRAY_BUFFER, g.createBuffer());

        // VBOに頂点データを登録
        g.bufferData(g.ARRAY_BUFFER, new Float32Array([-1,1,0,-1,-1,0,1,1,0,1,-1,0]), g.STATIC_DRAW);

        // attributeロケーション取得
        a = g.getAttribLocation(p, 'position');

        // attribute有効化
        g.enableVertexAttribArray(a);
        g.vertexAttribPointer(a, 3, g.FLOAT, false, 0, 0);

        // 初期化時の色を黒に指定
        g.clearColor(0, 0, 0, 1);

        // 動作開始時間を取得(時間の経過を調べるため)
        z = new Date().getTime();

        // 無名関数でメインルーチンを実行
        (function(){
          // シェーダのリンクに失敗していたら実行しない
          if(!e){return;}

          // ビューポートを動的に指定する
          c.width = x = w.innerWidth;
          c.height = y = w.innerHeight;
          g.viewport(0, 0, x, y);

          // 時間の経過を調べる
          d = (new Date().getTime() - z) * 0.001;

          // フレームバッファをクリア
          g.clear(g.COLOR_BUFFER_BIT);

          // uniform変数をプッシュ
          g.uniform1f(u.time, d);
          g.uniform2fv(u.resolution, [x, y]);

          // プリミティブのレンダリング
          g.drawArrays(g.TRIANGLE_STRIP, 0, 4);
          g.flush();

          // 再起
          requestAnimationFrame(arguments.callee);
        })();

        // keydownに登録する関数
        function k(h){e = (h.keyCode !== 27);}
      };
    </script>
    <style>
      /* ウィンドウ全体にcanvasをぴったり配置するためのStyle */
      * {
        margin:0;
        padding:0;
        overflow:hidden;
      }
      html,body{
        height:100%;
      }
    </style>
    <title>your demo title</title>
  </head>
  <body>
    <canvas id="c"></canvas>
  </body>
</html>

ブラウザで表示

たのしい!!

スクリーンショット 2015-03-22 10.02.55.png

54
43
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
43