忍者ブログ

Memeplexes

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

Three.dartでBufferGeometryを使う その4 アルファの変化

今回は実行時に三角形の透明度をダイナミックに変化させます。


コード

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();

  String vertexShader = '''

attribute vec4 color;
varying vec4 vertexColor;

void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  vertexColor = color;
}
  
''';
  
  String fragmentShader = '''

varying vec4 vertexColor;

void main() {
  gl_FragColor = vertexColor;
}
  ''';
  
  var material = new ShaderMaterial(
      vertexShader : vertexShader,
      fragmentShader : fragmentShader
      );
  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 * 4, 4);
  
  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 * 4 + 0] = 1.0;
  result.aColor.array[0 * 4 + 1] = 0.0;
  result.aColor.array[0 * 4 + 2] = 0.0;
  result.aColor.array[0 * 4 + 3] = 1.0;
  
  result.aColor.array[1 * 4 + 0] = 0.0;
  result.aColor.array[1 * 4 + 1] = 0.0;
  result.aColor.array[1 * 4 + 2] = 1.0;
  result.aColor.array[1 * 4 + 3] = 1.0;
  
  result.aColor.array[2 * 4 + 0] = 1.0;
  result.aColor.array[2 * 4 + 1] = 1.0;
  result.aColor.array[2 * 4 + 2] = 1.0;
  result.aColor.array[2 * 4 + 3] = 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 alpha = time % 1;
  geometry.aColor.array[0 * 4 + 3] = alpha;
  geometry.colorsNeedUpdate = true;
  
  renderer.setClearColorHex(0x6495ED, 1.0);
  renderer.render(scene, camera);
}

実行結果

このプログラムは画面にトリコロール色の三角形を表示し、そのうち赤の頂点の透明度を変化させます。

透明度が変化する現実の物体はあまり無いように思えるので具体的にどんなふうにこのテクニックを使えばいいのかはよくわかりませんが、面白いといえば面白いでしょう。そういえば一人称シューティングゲームHaloに出てくるエネルギーシールドは、ダメージを受けるとちょっと不透明になった気もします。全く応用がないというわけではないですね。

拍手[0回]

PR