のぐそんブログ

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

アルファブレンディングやってみる

アルファブレンディングとはその名の通り、不透明表示のことです。 ポイントはmaterialのtransparenttrueにすることです。

GLSLでテクスチャを貼っているので、フラグメントシェーダー側で透明度を設定します。 ※GLSLでテクスチャを貼っている意味はあまりないです。

JS

const myVert = require('./../shader/sample.vert');
const myFrag = require('./../shader/sample.frag');

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.setClearColor(new THREE.Color(0x1EA0F2));
  // 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 = 1;

  // Geometry作成
  var geometry = new THREE.BoxBufferGeometry(0.25, 0.25, 0.25);

  // Material作成
  let material = new THREE.RawShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    transparent : true,
    uniforms:{
      uTex: {type:'t', value: THREE.ImageUtils.loadTexture('images/t.jpg')}
    }
  });

  // Mesh作成
  let mesh = new THREE.Mesh(geometry, material);
  let mesh2 = new THREE.Mesh(geometry, material);
  mesh2.position.set(0, 0.1, 0.1);

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

  // draw
  render();

  var r = 0;

  //描画
  function render() {
    renderer.render(scene, camera);

    r += 0.01;

    mesh.rotation.set(0, r, r);
    mesh2.rotation.set(r, r, 0);
    // animation
    requestAnimationFrame(render);
  }

};

vertexShader

attribute vec3 position;
attribute vec2 uv;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
varying vec2 vUv;

void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

fragmentShader

precision mediump float;
uniform sampler2D uTex;
varying vec2 vUv;

void main(){
   gl_FragColor =texture2D(uTex,vUv);
   gl_FragColor.a = 0.5;
}

Kobito.FgDHzP.png

blendingをつかってみる

blendingを利用すると混ぜ方を色々変えることができます。

◎THREE.NormalBlending

  let material = new THREE.RawShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    transparent : true,
    blending:THREE.NormalBlending,
    uniforms:{
      uTex: {type:'t', value: THREE.ImageUtils.loadTexture('images/t.jpg')}
    }
  });

Kobito.sGowwh.png

◎THREE.AdditiveBlending

  let material = new THREE.RawShaderMaterial({
    vertexShader: myVert,
    fragmentShader: myFrag,
    transparent : true,
    blending:THREE.AdditiveBlending,
    uniforms:{
      uTex: {type:'t', value: THREE.ImageUtils.loadTexture('images/t.jpg')}
    }
  });

Kobito.64QC8h.png

まとめ

blendingの設定によって透明効果が効かなくなったりしました。 勉強不足です。 three.js使わない場合もまとめたかったですが、次回にしようと思います。