忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

Three.dartでBufferGeometryを使う その3 色の変化

3DCGのプログラムはパフォーマンスのために初期化は最初の一回だけなことが多いですが、まれに実行時にダイナミックに変化する物体を描きたいこともあります。今回は、ダイナミックに色を変化させる方法を解説します。


コード

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>three.dart sample</title>
</head>
<body>
    <canvas id="myCanvas" width="400" height="400"></canvas>
    <script type="application/dart" src="main.dart"></script>
    <script src="packages/browser/dart.js"></script>
</body>
</html>

main.dart

import 'dart:html';
import 'package:three/three.dart';

double time = 0.0;
BufferGeometry geometry;

PerspectiveCamera camera;
Scene scene;
WebGLRenderer renderer;


void main() {
  init();
  animate(0);
}

void init() {
  CanvasElement canvas = querySelector("#myCanvas");
  
  scene = new Scene();
  _initCamera(canvas);
  _initMesh();
  renderer = new WebGLRenderer(
      canvas:canvas, 
      devicePixelRatio:window.devicePixelRatio.toDouble()
      );
}

void _initMesh() {
  geometry = _createColoredTriangleMesh();
  var material = new MeshBasicMaterial(vertexColors:VertexColors);
  var mesh = new Mesh(geometry, material);
  scene.add(mesh);
}

BufferGeometry  _createColoredTriangleMesh() {
  BufferGeometry result = new BufferGeometry()
    ..aPosition = new GeometryAttribute.float32(3 * 3, 3)
    ..aColor = new GeometryAttribute.float32(3 * 3, 3);
  
  result.aPosition.array[0 * 3 + 0] = 1.0;
  result.aPosition.array[0 * 3 + 1] = 1.0;
  result.aPosition.array[0 * 3 + 2] = 0.0;
  
  result.aPosition.array[1 * 3 + 0] = -1.0;
  result.aPosition.array[1 * 3 + 1] = 1.0;
  result.aPosition.array[1 * 3 + 2] = 0.0;
  
  result.aPosition.array[2 * 3 + 0] = 0.0;
  result.aPosition.array[2 * 3 + 1] = 0.0;
  result.aPosition.array[2 * 3 + 2] = 0.0;
  
  result.aColor.array[0 * 3 + 0] = 1.0;
  result.aColor.array[0 * 3 + 1] = 0.0;
  result.aColor.array[0 * 3 + 2] = 0.0;
  
  result.aColor.array[1 * 3 + 0] = 0.0;
  result.aColor.array[1 * 3 + 1] = 0.0;
  result.aColor.array[1 * 3 + 2] = 1.0;
  
  result.aColor.array[2 * 3 + 0] = 1.0;
  result.aColor.array[2 * 3 + 1] = 1.0;
  result.aColor.array[2 * 3 + 2] = 1.0;
  
  result.isDynamic = true;
  result.computeBoundingSphere();
  return result;
}

void _initCamera(CanvasElement canvas) {
  camera = new PerspectiveCamera(
      90.0, 
      canvas.width / canvas.height, 
      0.1, 
      1000.0
      );
  
  camera.position.z = 3.0;
  scene.add(camera);
}

void animate(num time) {
  window.requestAnimationFrame(animate);

  draw();
}

void draw() {
  time += 1 / 30;
  double color = time % 1;
  geometry.aColor.array[2 * 3 + 0] = color;
  geometry.aColor.array[2 * 3 + 1] = color;
  geometry.aColor.array[2 * 3 + 2] = color;
  
  geometry.colorsNeedUpdate = true;
  
  renderer.setClearColorHex(0x6495ED, 1.0);
  renderer.render(scene, camera);
}

実行結果

このプログラムは三角形の白い部分だけが明滅します。三角形の色を保持するバッファをダイナミックに書き換えているわけです。

拍手[0回]

PR