GLSLでテクスチャにエフェクトを加える方法

デモシーン

はじめに  -今回やることとエディタなどの紹介-

最近VSCodeエディタでglslファイルからデモシーン制作を続けてますが、今日はテクスチャ(簡単に絵ば画像)を取り入れる方法を学んでいきます。

逆に過去記事のデモシーン動画は3dモデリングや画像は一切使わずにコードだけで作成してます…!!(これがデモシーンの魅力と思ってます)

でも世の中にある様々な画像に自分の思い通りのエフェクトを加えたりできたら、もっと楽しいのでは!と言うことで学習成果の記録も兼ねて記していきます。

これは今回使用するテクスチャ(画像)ですね。

こんな感じでVSCode(エディタ)でglslファイルのコードを色々いじって、テクスチャにエフェクトを加えていきます。(上画像は見にくいですが画像にノイズを入れています。)

作業環境について本当に簡単に説明します。
僕はVSCodeというエディタ(コードを書く。プログラミングのコードを書くのに特化したメモ帳・テキストエディタのような感じ)を使用してます。VSCodeは拡張機能が豊富なので非常に便利です。
上の画像も左側はglslファイルの中身ですが、右側はShaderToyという画面拡張機能を使用してます(下写真)。これを使うとほぼリアルタイムでコードの変更が画面に適応され、すぐにどのような画像になるのかを確認できるので、はっきり言ってめちゃくちゃ便利です。必須です。

プレビュー機能のある拡張機能は他にもありますが、僕は詳しくないし現状これで非常に満足しているので割愛します。

ではやってることの紹介に移ります。

テクスチャ(画像)を表示する

上画像が完成例です。

まず準備として読み込んだフォルダ内に画像ファイル(今回は上写真の左に見える『SampleCloud.jpg』)を入れておきます。

#iChannel0 "SampleCloud.jpg"

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);

    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)
    fragColor = texture1;
}

このようなコードを書けばいいです。
シェーダーコーディングの基礎はここでは割愛します。
テクスチャの肝となるコードはここですね。
・#iChannel0 “SampleCloud.jpg”
・vec4 texture1 = texture(iChannel0, texture1_UV);
textureメソッドは、指定した座標に基づいてサンプラー(テクスチャ)から色を取得するGLSL関数です。
https://zenn.dev/takoyaki_megane/books/68a890146fccfc/viewer/a18961
このリンクに画像付きの分かりやすい説明があったので参考にしてください。

ではいくつか今回学んだエフェクトを紹介していきます。

モザイク

#iChannel0 "SampleCloud.jpg"

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);

    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)

    //モザイク
    float mosaic_size = 0.07;
    vec2 mosaic = vec2(mosaic_size);
    vec2 uv_mosaic = floor(texture1_UV / mosaic) * mosaic;
    texture1 = texture(iChannel0, uv_mosaic);


    fragColor = texture1;
}

(左)mosaic_size = 0.07

           (右)mosaic_size = 0.02

ノイズ

#iChannel0 "SampleCloud.jpg"

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);

    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)

    //ノイズ
    float noise = fract(sin(dot(texture1_UV, vec2(12.9898, 78.233))) * 43758.5453);
    texture1.rgb += vec3(noise) * 0.5;


    fragColor = texture1;
}

(左)texture1.rgb += vec3(noise) * 0.1;

   (右)texture1.rgb += vec3(noise) * 0.5;

グレースケール

#iChannel0 "SampleCloud.jpg"

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);

    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)

    //グレースケール
    float gray = dot(texture1.rgb, vec3(0.299, 0.587, 0.114));
    fragColor = vec4(vec3(gray), 1.0);
}

チャンネルシフト

RとBのUV座標を左右に少しずらすと色収差みたいなエフェクトができます。

#iChannel0 "SampleCloud.jpg"

varying vec2 vUv;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);
    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)

    //チャンネルシフト
    //RとBのUV座標を左右に少しずらすと色収差みたいなエフェクトができます。
    float uPercent = 1.0; //0-100
    vec2 shift = vec2(0.01, 0.01);
    shift *= uPercent;
    texture1_UV.x += shift.x;
    texture1_UV.y += shift.y;
    vec4 texture2 = texture(iChannel0, texture1_UV);
    fragColor = vec4(texture2.r, texture1.g, texture2.b, 1.0);
}

歪ませる

texture2D()に渡すUV座標をsin(), cos()でオフセットすることで、テクスチャを歪ませます。

#iChannel0 "SampleCloud.jpg"

varying vec2 vUv;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;  
    vec2 texture1_UV = uv;
    texture1_UV = texture1_UV * 0.5 + 0.5;
    vec4 texture1 = texture(iChannel0, texture1_UV);

    //テクスチャのインポートとアスペクト比・UVの調整(UV -1~1 に対応させた)

    //歪ませる
    //texture2D()に渡すUV座標をsin(), cos()でオフセットすることで、テクスチャを歪ませることができる
    vec2 uv_distort = texture1_UV + vec2(0.1 * sin(uv.y * 20. + iTime), 0.1 * cos(uv.x * 10. - iTime)) * .1;
    vec4 texture2 = texture(iChannel0, uv_distort);

    fragColor = texture2;
}

おわりに

今回は基礎的なエフェクトを中心に試しました。

次はレイマーチングで作成したモデルにテクスチャを適応したりと、デモシーンにどのように取り込めるかを試していきます。

では。

Please follow and like us:

Follow me!

コメント

Social Share Buttons and Icons powered by Ultimatelysocial
YouTube
YouTube
Instagram
Copy link
URL has been copied successfully!
PAGE TOP