SQLの窓 イラストAC フリー素材

2013年02月28日

Three.js の点線表示の詳細( 特に Windows で WebGL では線の太さは実装なし )

このコードは、WebGL と Canvas とを同じコードで同時に表示する為のものです。ですから、Chrome と Firefox では以下のように表示されますが、WebGL が動作しないブラウザでは、右側だけが表示されます



LineDashedMaterial と LineBasicMaterial

前者が新しいマテリアルですが、大きく違うのは geometry の computeLineDistances メソッドで、これを実行しないと点線になりません。何故そのような仕様なのかは解りませんが、実装されたばかりの仕様であるせいかもしれません。

参考

Drawing the coordinate axes | soledad penadés

また、Canvas か WebGL かでも結果は大きく違い、LineDashedMaterial において以下のようなデフォルト値になっているにもかかわらず、WebGL では(少し大きめに描画?)正確では無いようです。
this.dashSize = 3;
this.gapSize = 1;
linewidth が WebGL で無視される これは、LineDashedMaterial よりかなり前の LineBasicMaterial からの仕様のようで、そもそも Windows では動作しないという事が言われています。 参考 LineBasicMaterial.linewidth is ignored when using WebGLRenderer ・ Issue #269 ・ mrdoob/three.js ・ GitHub javascript - Thickness of lines using THREE.LineBasicMaterial - Stack Overflow 現状では、他の方法で表現するしか無いとは思いますが Canvas では動作するので、グラフ表示等では Canvas を使うのがもともと現実的かと思います。 clearColor と clearAlpha について これらは、WebGL で利用できるものですが、実行画像を見てもらえれば一目瞭然です。clearColor は背景色で、clearAlpha はその背景色をどの程度透過するかのパラメータです。( 1 で不透過 ) Line オブジェクトのデフォルトは THREE.LineStrip ここでは、THREE.LinePieces が使用されていますが、THREE.LineStrip で点座標を連続してつないで線が描画(ひとふでがき)されます。しかし、THREE.LinePieces では、2つづつのペアで線が引かれるので、座標が並んでいるとしたら点線になります。
<style type="text/css">
body {
  background: url(https://lh4.googleusercontent.com/-qGsOjUoCvyw/T-VZ62iPMSI/AAAAAAAAG5Y/O0NhvMUvm9U/s200/_img.png);
  font-size: 30px;
}

span {
    color: #ffffff;
    font-weight:bold;
}
</style>
<div id="container"></div>

<script type="text/javascript" src="http://homepage2.nifty.com/lightbox/three/three.min56.js"></script>
<script type="text/javascript">
var webgl_flg = true;
if( !( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )() ) {
    webgl_flg = false;
}


var scene, camera;
var object;

// WebGLRenderer
var renderer

// CanvasRenderer
var renderer2;


var WIDTH = 250,
    HEIGHT = 250;

init();
animate();

function init() {
    
    camera = new THREE.PerspectiveCamera( 60, WIDTH / HEIGHT, 1, 200 );
    camera.position.z = 150;
    
    scene = new THREE.Scene();
    
    var geometryCube = cube( 50 );

    // LineDashedMaterial で必要
    geometryCube.computeLineDistances();
    
    object = new THREE.Line( geometryCube, new THREE.LineDashedMaterial( { color: 0xffaa00, dashSize: 3, gapSize: 1, linewidth: 5  } ), THREE.LinePieces );
    
    scene.add( object );

    if ( webgl_flg ) {    
	    renderer = new THREE.WebGLRenderer( { clearColor: 0x111111, clearAlpha: 0.8, antialias: true } );
	    renderer.setSize( WIDTH, HEIGHT );
    }

    renderer2 = new THREE.CanvasRenderer( );
    renderer2.setSize( WIDTH, HEIGHT );
    
    var container = document.getElementById( 'container' );
    if ( webgl_flg ) {    
        container.appendChild( renderer.domElement );
    }
    container.appendChild( renderer2.domElement );
    
    
}

function cube( size ) {
    
    var h = size * 0.5;
    
    var geometry = new THREE.Geometry();
    
    geometry.vertices.push( new THREE.Vector3( -h, -h, -h ) );
    geometry.vertices.push( new THREE.Vector3( -h, h, -h ) );
    
    geometry.vertices.push( new THREE.Vector3( -h, h, -h ) );
    geometry.vertices.push( new THREE.Vector3( h, h, -h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, h, -h ) );
    geometry.vertices.push( new THREE.Vector3( h, -h, -h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, -h, -h ) );
    geometry.vertices.push( new THREE.Vector3( -h, -h, -h ) );
    
    
    geometry.vertices.push( new THREE.Vector3( -h, -h, h ) );
    geometry.vertices.push( new THREE.Vector3( -h, h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( -h, h, h ) );
    geometry.vertices.push( new THREE.Vector3( h, h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, h, h ) );
    geometry.vertices.push( new THREE.Vector3( h, -h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, -h, h ) );
    geometry.vertices.push( new THREE.Vector3( -h, -h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( -h, -h, -h ) );
    geometry.vertices.push( new THREE.Vector3( -h, -h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( -h, h, -h ) );
    geometry.vertices.push( new THREE.Vector3( -h, h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, h, -h ) );
    geometry.vertices.push( new THREE.Vector3( h, h, h ) );
    
    geometry.vertices.push( new THREE.Vector3( h, -h, -h ) );
    geometry.vertices.push( new THREE.Vector3( h, -h, h ) );
    
    return geometry;
    
}


function animate() {
    
    requestAnimationFrame( animate );
    
    render();
    
}

function render() {
    
    var time = Date.now() * 0.001;
    
    object.rotation.x = 0.25 * time;
    object.rotation.y = 0.25 * time;
    
    if ( webgl_flg ) {    
        renderer.render( scene, camera );
    }
    renderer2.render( scene, camera );
    
}</script>
Three.js リファレンス

http://mrdoob.github.com/three.js/docs

関連する記事

Three.js(r53) で追加された LineDashedMaterial のサンプルを簡素化して解りやすくしました



【Three.jsの最新記事】
posted by at 2013-02-28 10:00 | Three.js | このブログの読者になる | 更新情報をチェックする