見出し画像

‪🐯今更聞けない3D入門 SVGタイガーの謎にも迫るヨ

SVGのデモもあったな、SVGといえばSVGタイガー

画像1

ガオー

p5に移植するのもかなり手慣れたものになった

画像2

余裕が出てきたのでようやっとソース読む

必須ではないようだが、moduleタグの中で必要なサンプル(という名のほぼライブラリ)を読み込んでいく。大抵こういう形をしている。

		<script type="module">
			import * as THREE from 'https://unpkg.com/three/build/three.module.js';
			import Stats from 'https://unpkg.com/three/examples/jsm/libs/stats.module.js';
			import { GUI } from 'https://unpkg.com/three/examples/jsm/libs/dat.gui.module.js';
			import { OrbitControls } from 'https://unpkg.com/three/examples/jsm/controls/OrbitControls.js';
			import { SVGLoader } from 'https://unpkg.com/three/examples/jsm/loaders/SVGLoader.js';
			let renderer, stats, scene, camera, gui, guiData;

threeのサンプルではここが相対pathになってたり、npmとかもやもやしていたが、本家をみるとCDNがあってそれが使えたのが一つの発見だった。

Render/scene/cameraなどの概念もglTFのチートシートで一般的な常識をみにつけられた。

その後呼び出されるのはinitiとanimate関数だが、animateの中ではrequestAnimationFrameという関数が呼び出されている。そしてこれはthree.jsでもなんでもない。ただのループ用のコールバック関数だ。

window.requestAnimationFrame() メソッドは、ブラウザにアニメーションを行いたいことを知らせ、指定した関数を呼び出して次の再描画の前にアニメーションを更新することを要求します。このメソッドは、再描画の前に呼び出されるコールバック 1 個を引数として取ります。

このコールバックの回数は、たいてい毎秒 60 回ですが、一般的に多くのブラウザーでは W3C の勧告に従って、ディスプレイのリフレッシュレートに合わせて行われます。ただし、コールバックの確率は、バックグラウンドのタブや隠れた <iframe> では、パフォーマンス向上やバッテリー消費を減らすために低くなるでしょう。

p5のdrawとそんなに違いない。

function animate() {
	requestAnimationFrame( animate );
	renderer.render( scene, camera );
}
animate();

Threeではこの構文をレンダラまたはアニメーションループと呼んでいるようだ。なぜ使うかの解説もあった。

これは、画面が更新されるたびに(一般的な画面では、これは1秒間に60回を意味します)レンダラーがシーンを描画するループを作成します。ブラウザでゲームを書くのが初めての人は、「setIntervalを作ればいいんじゃないの?」と思うかもしれません。しかし、requestAnimationFrameには多くの利点があります。おそらく最も重要なのは、ユーザーが別のブラウザタブに移動したときに一時停止することです。それによって、貴重な処理能力とバッテリーの寿命を無駄にしません。

逆にとめたくないときは使うなということだが、バッテリーとの兼ね合いがあるんだな。

ロードする

その後ローダーと呼ばれるものを使い、多彩な3D(今回は2D)オブジェクトを読み込む。3D系だと似たような書き方が多い気がするが、ロードの関数に戻り値はなくて、ロード関数のなかで読み込んだデータをsceneにぶちこんでいるのようだ。

			function loadSVG( url ) {
				//
				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0xb0b0b0 );
				//
				const helper = new THREE.GridHelper( 160, 10 );
				helper.rotation.x = Math.PI / 2;
				scene.add( helper );
				//
				const loader = new SVGLoader();
				loader.load( url, function ( data ) {
					const paths = data.paths;

非同期の理由なのか3Dの世界観なのか、別の描き方もできる気がするからサンプル作った人の趣味だろうか。

								const mesh = new THREE.Mesh( geometry, material );

今回はSVGなのでgeometryがSVGのシェープ materialが色ということみたいだった。


					scene.add( group );

今回はmeshをグループというまとまりにして、シーンにaddしているglTFではノードと呼んでいる概念に違いない。

カメラ、ちょっとだけかじっちゃおうか

動きの部分はthreeのorbit jsmがやってくれているので、細かいカメラ移動や処理の事は分からないが、リサイズで出てくる処理があるので、少しだけ調べてみる。

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

aspectはアスペクト比に違いない。

これらのプロパティのほとんどを変更した後は、変更を有効にするために .updateProjectionMatrix を呼び出す必要があることに注意してください。

プロジェクションとは「投影」を意味することで、これは普通のカメラと違うところかもしれない。

写経、写経、写経して、一晩寝かせたあたりでコード読む

経験上、概念とサンプルコード読むだけだと、理解がうまくいかないことがある。そのため、動くコードが欲しいのだが、動かすまでに結構手数が必要だったりするものも多い。しかし万難排して、まず自分のテリトリー内で動くコードをつかめれば、翌日はコード読む気になっていることは多い。コードが読めればリファレンスに手が届くようになって、リファレンスに手が届くと周辺仕様を読む気になって、そのあたりで概念に戻ると、合点がいくようになる。他の類似製品やライブラリ、オーサリングツール、ちょっと次元をずらしたもの(今回の場合はSVG)などで比較検討するのも、個人的にはおすすめしたいところ。

で、やりたいことは毛筆だったんだが。

この素材を読み込ましたい。

画像3


なんじゃパッピーって、、

画像4

SVGは25MB以下ならばgithubさんからrawデータで送り込ませていただけることもわかった。このあたりまだ不安もあるが使えるうちは使っちゃおう。

なんか、うまく動かないがSVG編はこれでやめる、なんとなくだが、メッシュンところがうまくいってない気がする。

おまけSVGタイガーの謎

彼の名はゴーストスクリプトタイガー、どうもサンプルように作られたらしい 出自はeps


gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -dGraphicsAlphaBits=4 \
-sOutputFile=tiger.png tiger.eps

tiger.eps
A dramatic colored picture of a tiger's head.

お願い致します