Closed22

個人勉強メモ: 2023/10/24

mm

目標

  • WebGLの使い方を知る、文法も含めて
  • PhotoMoshのWebGLの動かし方を知る
  • (可能であれば) glitchとwebglを組み合わせる
  • p5.jsで読み込ませた画像にシェーダーの効果をシンプルに適用する
mm

シェーダーとは

  • .vertと.frag の2種類のファイルがある、頂点シェーダー、フラグメントシェーダー
  • p5.js ではloadShader()を使用してロードされる
  • vec3は3次元、みたいな型の意味を表す

頂点シェーダー

  • すべての頂点シェーダーには main 関数がある
  • 頂点位置を変更し、スケッチ全体に影響を及ぼすようにする
  • 最後にgl_Position に値を与える

フラグメントシェーダー

  • 最後にgl_FragColor を割り当てる
  • uniform という機能を使うと、sketch側から値を渡せる。setUniform() などを使う
mm

GL_ES

  • 定義されていればというときに使える

.xy について

  • .xyを実行すると、x位置とy位置の両方に同じ計算が行われる
mm

bing AIで出力したサンプルコード
画像の縦横比を維持したままWEBGLを使う

let img;
let shader;

function preload() {
  img = loadImage('assets/image.jpg');
  shader = loadShader('assets/shader.vert', 'assets/shader.frag');
}

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  textureMode(NORMAL);
}

function draw() {
  background(0);
  translate(-width / 2, -height / 2);
  let ratio = img.width / img.height;
  let screenRatio = width / height;
  let w, h;
  if (ratio > screenRatio) {
    w = width;
    h = w / ratio;
  } else {
    h = height;
    w = h * ratio;
  }
  translate(width / 2, height / 2);
  shader(shader);
  shader.setUniform('tex0', img);
  shader.setUniform('ratio', ratio);
  rectMode(CENTER);
  rect(0, 0, w, h);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

precision highp float;

uniform sampler2D tex0;
uniform float ratio;

varying vec4 vertTexCoord;

void main() {
    vec2 texCoord = vertTexCoord.st;
    if (ratio > 1.0) {
        texCoord.x /= ratio;
        texCoord.x += (1.0 - (1.0 / ratio)) / 2.0;
    } else {
        texCoord.y *= ratio;
        texCoord.y += (1.0 - ratio) / 2.0;
    }
    vec4 color = texture2D(tex0, texCoord);
    gl_FragColor = vec4(1.0 - color.rgb, color.a);
}

mm

シェーダーを勉強し直す

https://thebookofshaders.com/01/?lan=jp

  • シェーダーとは、描画方法を記述したプログラムのこと
  • コンピュータへの指示、それがすべてのピクセルへの指示
  • プログラムは画面上の位置を入力としてピクセルの色を返す関数として働くイメージ
  • 並列処理をやってくれるが、ほかのスレッドや前の状態がわからないという制限がある
  • GLSLはopenGL Shading Languageの略

フラグメントシェーダー

  • 予約語として確保されたグローバル変数、gl_FragColor
  • vec3, vec4というのは変数の型

ユニフォーム変数

  • CPUからそれぞれのスレッドに入力を渡すことができる

  • 英語の”uniform”には均一な、一様なという意味がある

  • u_time(シェーダーが開始してから経過した秒数)、u_resolution(シェーダーが描画する領域の大きさ)、u_mouse(描画領域の中のマウスの位置)などを渡せる

  • u_ で始めるという慣例に従ってるところがある

  • p5jsからは p5.Shader objectのsetUniform(); を使う

  • gl_FragCoordはvarying変数、uniform変数と違う

ベクトルの正規化

  • ベクトルの正規化は、ベクトルのxy成分をベクトルの長さで割ることで求められる。

xy座標の線形空間

mm

ベクトル型について

vec4 vector;
vector[0] = vector.r = vector.x = vector.s;
vector[1] = vector.g = vector.y = vector.t;
vector[2] = vector.b = vector.z = vector.p;
vector[3] = vector.a = vector.w = vector.q;

sin(u_time) で、-1.0 ~ 1.0 を行ったり来たりする動かし方ができる

mm

画像処理について

https://thebookofshaders.com/15

  • GPU で、画像はsampler2D浮動小数点ベクトルのテーブル (または行列) に似たものとして保存される
  • さらに興味深いことに、このベクトルのテーブルの値は連続的です。つまり、ピクセル間の値は低レベルで補完される
  • 画像を扱うには、CPU から GPU に画像をアップロードし、idをuniformに渡す
  • vec4 texture2D(sampler2D texture, vec2 coordinates) というテーブル変数

参考URL

mm

chatGPTにきいたテクスチャ座標と画面座標の違い

テクスチャ座標と画面座標は、異なる座標系であり、異なる役割を果たします。

  1. テクスチャ座標(UV座標):

    • テクスチャ座標は、通常は0から1の範囲で表される正規化された座標系です。各成分は通常、横軸(U軸)と縦軸(V軸)に対応しています。
    • 例えば、(0, 0) はテクスチャの左上隅を、(1, 1) は右下隅を指します。これにより、テクスチャ上の特定の位置を指定することができます。
    • シェーダー内で texture2D(u_image, uv) のように使用され、テクスチャから色をサンプリングするために利用されます。
  2. 画面座標(フラグメント座標):

    • 画面座標(またはフラグメント座標)は、ピクセルが描かれる画面上の位置を表します。これは通常、ピクセル単位で表され、左上が原点です。
    • 例えば、(0, 0) は画面の左上隅を、(width, height) は右下隅を指します。ここで、width は画面の幅、height は高さです。
    • シェーダー内で gl_FragCoord.xy のように使用され、各ピクセルの座標を取得するために利用されます。

簡単に言えば、テクスチャ座標はテクスチャ内の位置を指定するのに対して、画面座標は描画されるピクセルの位置を指定します。シェーダー内での利用目的によって、これらの座標系が使い分けられます。

このスクラップは2023/11/07にクローズされました