見出し画像

第5回 クリエイティブ・コード・スケッチ テーマ 画像と映像

クリエイティブ・コード・スケッチ・クラブという活動を5-6名で社内でやってます。週1回お題に沿ってJavaScriptや3Dソフトなどでデモを作り、作ったものを発表してます。

10月から活動を開始し、11/25で5回目になりました。デモレベルの作品を定期的にアウトプットして、知見を共有するのが目的です。

第1回 - 第4回は今後共有するとして、今回は第5回のデモについてざっくり説明します。

デモ

画像5

コード

デモはthree.jsを使用して実装して、WebGL上で実行しています。

取得した映像の色データを白黒データとしてグリッドで取得し、白黒の値からフォントを0-8の9つの値として表示しています。

three.jsを使用した映像の全画面表示


three.jsは名前に3(three)が入ってる通りWebGL上で3Dを簡単に実装するためのライブラリです。

three.jsの「WebGL上で3Dを簡単に実装する」という仕組みを理解すれば、2Dの全画面表示は簡単にできます。(WebGLは3DをレンダリングするためのAPIではないので、2D描画でthree.jsを使用すると少し無駄な行列計算をしています。最適化したいときはWebGL APIを直接書くことをおすすめします。)

遠近法のないカメラであるorthographicカメラを使用します。

画像2

カメラのスケールを画面サイズに設定して、表示領域を把握しやすくします。

var width = window.innerWidth;
var height = window.innerHeight;

this.camera = new THREE.OrthographicCamera(
	width / -2,
	width / 2,
	height / 2,
	height / -2,
	1,
	100
);		   


画像3

1x1の平面planeをgeometryにしたmeshを作成し、画面サイズに応じていい感じにフィットすようにリサイズします。

var plane = new THREE.PlaneGeometry(1, 1);
var material = // 略
var mesh = new THREE.Mesh(plane, material);

var width = window.innerWidth; // 横画面サイズ
var height = window.innerHeight; // 縦画面サイズ

let meshWidth, meshHeight; // meshのスケール

// メッシュのスケールを計算する
if ((videoHeight / videoWidth) * width > height) {
	meshWidth = width;
	meshHeight = (videoHeight / videoWidth) * videoWidth;
} else {
	meshHeight = height;
	meshWidth = (videoWidth / videoHeight) * videoHeight;
}


mesh.scale.set(meshWidth, meshHeight, 1); 


デモで使用しているフラグメントシェーダー

フラグメントシェーダーとして以下のファイルを使用しています。

precision highp float;

uniform sampler2D uTexture;
uniform sampler2D uFontTexture; 
uniform vec2 uWindowSize;
uniform float uGridSize;
uniform float uProgress;
uniform float uProcess;

varying vec2 vUv;


void main(){
   // プロセス1
   vec2 windowSize = vUv * uWindowSize;
   vec2 gridIndex = floor(windowSize/uGridSize);
   vec2 customUv = (gridIndex * uGridSize)/uWindowSize;
   vec4 textureColor = texture2D(uTexture, customUv);
   float blackWhite = (textureColor.r + textureColor.g + textureColor.b )/3.;

   if(uProcess == 1.0){
       // プロセス2
       vec2 gridUv = (windowSize - gridIndex * uGridSize) / uGridSize;
       gridUv.x = 1.0 - gridUv.x;
       float rate = floor(mix(6., blackWhite * 9., uProgress));
       float col = mod(rate, 3.);
       float row = floor(rate / 3.);

       vec2 outputUv = vec2(gridUv.x / 3. + 0.333 * col, gridUv.y/3. + 0.333  * row);

       vec4 outColor = texture2D(uFontTexture, outputUv);//vec4(gridUv, 0.0, 1.0);

       gl_FragColor = outColor;
   }else{
       // プロセス2を表示
       gl_FragColor = vec4(blackWhite, blackWhite, blackWhite, 1.0);
   }
   
}

プロセスとしては2つだけです。

プロセス1 グリッドサイズをベースに 白黒の値を取得する

画像5

プロセス2  グリッドサイズの白黒の値をベースにフォントを適用する

画像5



この記事が気に入ったらサポートをしてみませんか?