[three.js] 光の効果 (1)

three.jsを使って、光のエフェクトを作るよ。 :boy:

threejs_effect1

WebGLRendererで描画するよ。
CylinderGeometry, MeshBasicMaterial, Mesh を使ってみたよ。 :bouzu:
んでもって、ImageUtils, Texture も使ったりして。 :beer:

itoz 師匠 :hakase: のスクリプトをこっそり使わせてもらったよ。
@yoshiweb 先生 :hakase: にマテリアルのtransparent, depthTestプロパティが鍵だって教えてもらったよ。

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0">
<title>光の効果 (1) | three.js</title>
<script src="js/three.min.js"></script>
<script src="js/detector.js"></script>
<script src="js/stats.min.js"></script>
<style type="text/css">
  html { overflow:hidden; }
  body { margin:0; padding:0; }
</style>
</head>
<body style="background-color:#000000">
<script>
var scene, camera, renderer, stats;
var texture;
var container, lights;
var radius = 500;
var radian = Math.PI/180;
var center = new THREE.Object3D();

window.onload = init;

function init() {
  if (!Detector.webgl) Detector.addGetWebGLMessage();

  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 0.1, 1000);
  scene.add(camera);
  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  setup();
  //initialize();
  THREE.ImageUtils.loadTexture("assets/light.png", undefined, loaded);

  stats = new Stats();
  stats.setMode(0);
  stats.domElement.style.position = "fixed";
  stats.domElement.style.right = "0px";
  stats.domElement.style.top = "0px";
  document.body.appendChild(stats.domElement);

  //render();
  window.addEventListener("resize", resize, false);
}
function setup() {
  renderer.setClearColor(0x000000, 1);
  camera.position.z = -radius;
}
function loaded(data) {
  texture = data;

  initialize();

  render();
}
function initialize() {
  container = new THREE.Group();
  scene.add(container);

  var material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide});
  material.transparent = true;
  material.depthTest = false;
  lights = [];
  for (var n = 0; n < 3; n++) {
    var offset = 64*n;
    var geometry = new THREE.CylinderGeometry(0, 256 - offset, offset, 60, 15, true);
    var light1 = new THREE.Mesh(geometry, material);
    light1.rotation.y = 120*n*radian;
    light1.position.y = - offset/2;
    var light2 = new THREE.Mesh(geometry, material);
    light2.rotation.y = 120*n*radian;
    light2.rotation.x = 180*radian;
    light2.position.y = offset/2;
    var light3 = new THREE.Mesh(geometry, material);
    light3.rotation.y = 120*n*radian;
    light3.rotation.x = 90*radian;
    light3.position.z = - offset/2;
    container.add(light1);
    container.add(light2);
    container.add(light3);
    lights.push(light1);
    lights.push(light2);
    lights.push(light3);
  }
}
function render() {
  requestAnimationFrame(render);

  container.rotation.x += 0.1*radian;
  container.rotation.y += 0.2*radian;
  container.rotation.z += 0.15*radian;
  for (var n = 0; n < lights.length; n++) {
    var light = lights[n];
    light.rotation.y += 0.2*n*radian;
    light.material.opacity = Math.random()*0.4 + 0.6;
  }

  camera.lookAt(center.position);

  renderer.render(scene, camera);

  stats.update();
}
function resize(event) {
  camera.aspect = window.innerWidth/window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
</script>
</body>
</html>


[修正] (14/12/03 Wed 00:34)
PerspectiveCamera の fov の値を 75 から 60 に変更。
[修正] (14/12/03 Wed 13:32)
ImageUtils の読み込み処理方法を変更。
[修正] (14/12/04 Thu 02:25)
コンテナとしての Object3D を Group に変更。
[修正] (14/12/27 Sat 21:17)
HTML記述を変更。