サイトに3Dモデルを表示する試み④
今は遠い昔、パソコンが世に出る前の頃、筆者は漫画家を目指してGペン・ケント紙を使ってせっせと描いては投稿していたことがあります。
いかんせん画力がない、根気がない、描きたい物語もたいしてないということで、パソコンが普及し始めるとそっちの方に興味が向き、漫画描きから遠ざかりました。
それでもつい最近までは「パソコンを漫画の下描きに活かせないか」という観点から、2D/3Dのグラフィックソフトの練習を続けてきました。
輪郭線抽出のテストもその試みの一つです。
three.jsとGIMPで輪郭線抽出、テストモデルを準備
まずはテスト用のモデルです。ある色と別の色との境目をエッジとして認識するフィルターをテストするため、色数を多くしています。
three.jsのSobelOperatorShader.jsを適用
※ポストプロセシングに必要なモジュールは<body>の中で読み込ませています。
<canvas id="myCanvas1" style="width:100%;"></canvas>
<script type="module">
import { WebGLRenderer } from '/js/build/three.module.js';
import { Scene } from '/js/build/three.module.js';
import { Color } from '/js/build/three.module.js';
import { DirectionalLight } from '/js/build/three.module.js';
import { AmbientLight } from '/js/build/three.module.js';
import { PerspectiveCamera } from '/js/build/three.module.js';
import { OrbitControls } from '/js/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from "/js/examples/jsm/loaders/GLTFLoader.js";
import { EffectComposer } from '/js/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from '/js/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from '/js/examples/jsm/postprocessing/ShaderPass.js';
import { SobelOperatorShader } from '/js/examples/jsm/shaders/SobelOperatorShader.js';
// ページの読み込みを待つ
window.addEventListener('load', main);
function main() {
const canvas = document.querySelector('#myCanvas1');
const renderer = new WebGLRenderer({canvas, antialias: true});
renderer.setPixelRatio(2);
const fov = 50; // Field of View
const aspect = 2; // デフォルト
const near = 0.1;
const far = 1000;
const camera = new PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 3;
camera.position.y = 0.5;
// カメラコントロール
const controls = new OrbitControls(camera, canvas);
// シーンを作成
const scene = new Scene();
scene.background = new Color( 'dimgray' );
//glTFの読み込み
const loader = new GLTFLoader();
loader.load('/asset/2019/07-10/test.glb',function(data){
const gltf = data;
const obj = gltf.scene;
scene.add(obj);
});
// 環境光源を追加
const light = new AmbientLight(0xFFFFFF, 1.0);
scene.add(light);
// postprocessing
const composer = new EffectComposer( renderer );
const sampleRatio = 2;
//composer.setSize(1024, 768);
const renderPass = new RenderPass( scene, camera );
composer.addPass( renderPass );
// Sobel operator
const effectSobel = new ShaderPass( SobelOperatorShader );
effectSobel.uniforms[ 'resolution' ].value.x = window.innerWidth * window.devicePixelRatio * 0.8;
effectSobel.uniforms[ 'resolution' ].value.y = window.innerHeight * window.devicePixelRatio * 0.8;
composer.addPass( effectSobel );
tick();
// 毎フレーム時に実行されるループイベント
function tick() {
// レンダリング
composer.render(scene, camera);
requestAnimationFrame(tick);
}
}
</script>
GIMP:普通表示のモデルの絵をスクリーンキャプチャで取り込む
フィルター → 輪郭抽出 → ソーベル
SobelOperatorShader, GIMPソーベルフィルタの絵を階調反転して比べる
線画ができたらInkscapeの自動トレース機能でベクター画像が作成できます。