のぐそんブログ

暗いおじさんがシコシコ書くブログです。

THREE.jsでフラグメントシェーダを使ってみるの基礎基礎メモ1

フラグメントシェーダを使って色を変更してみたいと思います。

基礎の復習

ベースとなるコードです。

js
window.onload = () => {
  let windowWidth = window.innerWidth;
  let windowHeight = window.innerHeight;

  // rendererの作成
  let renderer = new THREE.WebGLRenderer();
  
  // canvasをbodyに追加
  document.body.appendChild(renderer.domElement);

  // canvasをリサイズ
  renderer.setSize(windowWidth, windowHeight);

  // scene作成
  let scene = new THREE.Scene();
  
  // camera作成
  let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000);
  camera.position.z = 100;

  // Geometry作成
  let geometry = new THREE.PlaneBufferGeometry(100, 100);
  
  // Material作成
  let material = new THREE.ShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    uniforms:{
      uColor: {type: "c", value: new THREE.Color(0xFF0000)}
    }
  });
  
  // Mesh作成
  let mesh = new THREE.Mesh(geometry,material);

  // Meshをシーンに追加
  scene.add(mesh);

  // draw
  renderer.render(scene, camera);
};
vert(頂点シェーダー)
void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
frag(フラグメントシェーダー)
precision mediump float;

 uniform vec3 uColor;

void main(){    
  gl_FragColor =vec4(uColor, 1.0);
}
結果

Kobito.yP7wXn.png

マウス座標で色を変えてみる

マウス座標を取得して色を変更してみたいと思います。 requestAnimationFrameでuniformsを更新していきます。

js
window.onload = () => {
  let windowWidth = window.innerWidth;
  let windowHeight = window.innerHeight;
  let mouse = new THREE.Vector2(0.0, 0.0);

  // rendererの作成
  let renderer = new THREE.WebGLRenderer();
  
  // canvasをbodyに追加
  document.body.appendChild(renderer.domElement);

  // canvasをリサイズ
  renderer.setSize(windowWidth, windowHeight);

  // scene作成
  let scene = new THREE.Scene();
  // camera作成
  let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000);
  camera.position.z = 100;

  // Geometry作成
  let geometry = new THREE.PlaneBufferGeometry(100, 100);
  
  // Material作成
  let material = new THREE.ShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    uniforms: {
        uMouse: {
        type: "v2",
        value: mouse
      },
    }
  });
  
  // Mesh作成
  let mesh = new THREE.Mesh(geometry, material);

  // Meshをシーンに追加
  scene.add(mesh);

  //マウス座標を取得
  renderer.domElement.addEventListener('mousemove', function (e) {
    mouse = new THREE.Vector2(
      e.clientX / windowWidth,
      e.clientY / windowHeight);
  }, false);

  // draw
  render();

  //描画
  function render() {
    renderer.render(scene, camera);
    
    material.uniforms.uMouse.value = mouse;

    // animation
    requestAnimationFrame(render);
  }

};
frag(フラグメントシェーダー)
precision mediump float;

 uniform vec2 uMouse;

void main(){
  // テクスチャ座標をカラーに出力
  gl_FragColor =vec4(uMouse.x,uMouse.y,0.0, 1.0);
}
結果

マウスを動かすと色が変わります。

See the Pen vJqRqb by nogson (@satofaction) on CodePen.

経過時間で色を変えてみる

window.onload = () => {
  let windowWidth = window.innerWidth;
  let windowHeight = window.innerHeight;
  let clock = new THREE.Clock();
  let time = 0.0;

  // rendererの作成
  let renderer = new THREE.WebGLRenderer();
  
  // canvasをbodyに追加
  document.body.appendChild(renderer.domElement);

  // canvasをリサイズ
  renderer.setSize(windowWidth, windowHeight);

  // scene作成
  let scene = new THREE.Scene();
  // camera作成
  let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000);
  camera.position.z = 100;

  // Geometry作成
  let geometry = new THREE.PlaneBufferGeometry(100, 100);
  
  // Material作成
  let material = new THREE.ShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    uniforms: {
        uTime: {
        type: "f",
        value: time
      },
    }
  });
  
  // Mesh作成
  let mesh = new THREE.Mesh(geometry, material);

  // Meshをシーンに追加
  scene.add(mesh);

  //マウス座標を取得
  renderer.domElement.addEventListener('mousemove', function (e) {
    mouse = new THREE.Vector2(
      e.clientX / windowWidth,
      e.clientY / windowHeight);
  }, false);

  // draw
  render();

  //描画
  function render() {
    renderer.render(scene, camera);
    
    //経過時間を取得
    time  = clock.getElapsedTime();
    material.uniforms.uTime.value = time;

    // animation
    requestAnimationFrame(render);
  }

};
frag(フラグメントシェーダー)
precision mediump float;
 uniform float uTime;

void main(){
  float t = abs(cos(uTime));
  gl_FragColor =vec4(t,t,t, 1.0);
}
結果

See the Pen YxovGW by nogson (@satofaction) on CodePen.

まとめ

すごい基礎的な部分なのですが、なかなか上手くいきません。 とにかく色々やってみるしかありません。

THREE.GPUParticleSystemを使ってみる

パーティクルを作成する際に、new THREE.ParticleSystemクラスを使おうとすると、下記の警告がでました。

THREE.ParticleSystem has been renamed to THREE.Points.

パーティクルを作成する場合はTHREE.Pointsクラスを使う必要があるみたいです。 しかし、最近気がついたのですがTHREE.GPUParticleSystemクラスがあるようです。

続きを読む

TouchDesigner基礎基礎メモ1

TouchDesignerとは

TouchDesignerは、オペレーターと呼ばれるプログラムのモジュールをつなげることで、コードを書かなくてもビジュアルプログラミングができる開発環境です。

表現自体は色々できるみたいなのですが、リアルタイムで操作する映像表現などによく使われるみたいです。

Live@HPL Media Street Event in Russia (β ver.) from Intercity-express on Vimeo.

今回はTouchDesignerの基礎の中の基礎を少し学んだので自分用のメモにしました。

続きを読む

THREE.BufferGeometryの使い方を調べる

THREE.BufferGeometryの使い方の基礎的な部分をまとめたいと思います。

THREE.BufferGeometryとは

var geometry = new THREE.BufferGeometry();

BufferGeometryはピュアなWebGLAPIを扱うようにGeometryを作成できます。 BufferGeometryは作成時は何も情報を持たない為、頂点データ(attributeやindex)を定義する必要があります。

続きを読む