webpack-dev-serverを使ってみる
webpack-dev-server
開発用サーバを立てることができるモジュールです。
詳しくは公式のドキュメントを見てみてください。
手順
モジュールをインストール。
npm install --save-dev webpack-dev-server
package.jsonにscriptを追加。
"scripts": { "start": "webpack-dev-server" }
サーバーを起動する。
npm start
http://localhost:8080
でアクセスできるようになる。
サーバーの設定をする
サーバーの設定は、package.jsonにも指定できるが、webpack.config.jsに記載すると見やすい気がする。
サーバーに設定できるオプションで、私がよく使うのは下記。
オプション | 説明 |
---|---|
contentBase | サーバの起点ディレクトリを指定。未指定の場合はカレントディレクトリが起点になる。 |
port | 未指定の場合は8080が初期値になる。 |
open | サーバー起動時にブラウザを開く。true or falseで指定。 |
inline | ライブリロードを行うための設定。true or falseで指定。未指定の場合はtrue |
hot | Hot Module Replacement(HMR)を有効にします。true or falseで指定。未指定の場合はtrue。 |
※hotについては、webpack.config.jsに指定するとエラーとなるのでpackage.jsonにwebpack-dev-server --hotとして渡す必要があるようです。
webpack.config.jsに指定する場合
devServer: { contentBase: path.resolve(__dirname, 'dist'), port: 3000, open:true },
package.json指定する場合
"scripts": { "start": "webpack-dev-server client.js --inline --hot --colors --content-base dist/ --port=3000" }
live reloadを利用する
ライブリロードを行う場合は、webpack.config.jsのoutput
のpath
の設定と、devServer
のcontentBase
の設定を同じにする必要があるようです。
ただし、同じにした場合に少し問題があります。 出力先のフォルダにindex.htmlを入れることになるので、ファイル構成上変な感じがします(私だけかもしれませんが。。。)
そこで、output
のpublicPath
を設定することで、path
とcontentBase
が異なってもライブリロードを行うことができます。 publicPathはwebpack-dev-serverを利用する際は、指定したほうが良さそうです。
const path = require('path'); module.exports = { //ビルドするファイル entry: path.resolve(__dirname, './src/main.js'), //ビルドしたファイルの出力先 output: { path: path.resolve(__dirname, './dist'), filename: 'bundle.js', publicPath: '/assets' }, //開発サーバーの設定 devServer: { contentBase: path.resolve(__dirname, './src'), inline: true, open: true }, devtool: 'source-map' };
webpack-dev-serverでのビルド
webpack-dev-serverでも、webpack.config.js設定にあわせてファイルのビルドが行われます。 ただしこのビルドは、実際のnpm run build
とは異なり、ファイルはメモリ上に保存されます。
例)webpack.config.jsの設定が上記の場合はこんな感じ
. ├── node_modules ├── package-lock.json ├── package.json ├── src │ ├── index.html │ ├── main.js │ └── assets //メモリ上に存在する │ └── dist.js //メモリ上に存在する └── webpack.config.js
その他
webpack-dev-serverはipはそのままの設定ではプライベートIPでアクセスすることができません。
プライベートIPでアクセスする為、host:0.0.0.0とdisableHostCheck: trueを追加します。
devServer: { contentBase: path.resolve(__dirname, 'dist'), port: 3000, open:true, host 0.0.0.0, disableHostCheck: true },
まとめ
メモリ上にファイルが保存されるのがよくわからず、ハマりました。
THREE.jsのEffectComposerでオリジナルのポストプロセスをやってみる
前回「THREE.jsでオリジナルのポストプロセスをやってみる」と題しましてポストプロセスについての記事を書きました。
よくよく調べると、THREE.jsにはポストプロセスを行う仕組み自体が用意されており、それを利用すればオリジナルのポストプロセスも簡単に書くことができました。
やってみる
オリジナルのポストプロセスを行うには下記のファイルが必要です。
JS
ShaderPassにShaderMaterialと同じように、unfiforms、vertexShader、fragmentShaderを含んだオブジェクトを追加します。 uniformsには、通常のシーンの描画結果を入れるtDiffuse
というテクスチャ型のオブジェクトが必ず必要です。
以下の例では、ポストプロセスで通常のシーンのUV座標をずらすエフェクトをかけています。
var renderer, scene, camera, myCanvas = document.getElementById('myCanvas'); //RENDERER renderer = new THREE.WebGLRenderer({ canvas: myCanvas, antialias: true }); renderer.setClearColor(0xffffff); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); //CAMERA camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 1; //SCENE scene = new THREE.Scene(); //LIGHTS var light = new THREE.AmbientLight(0xffffff, 0.5); scene.add(light); var material = new THREE.MeshLambertMaterial(); var geometry = new THREE.SphereGeometry(0.1, 20, 20); var mesh = new THREE.Mesh(geometry, material); scene.add(mesh); //ポストプロセスの設定 //WebGLRendererをラップするためにEffectComposerに渡す //最終的にはEffectComposerのインスタンスを描画する var composer = new THREE.EffectComposer(renderer); //現在のシーンを設定 var renderPass = new THREE.RenderPass(scene, camera); composer.addPass(renderPass); //カスタムシェーダー var myEffect = { uniforms: { "tDiffuse": { value: null, type: 't' }, "amount": { value: 1.0, type:'f' } }, vertexShader: [ "varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join("\n"), fragmentShader: [ "uniform float amount;", "uniform sampler2D tDiffuse;", "varying vec2 vUv;", "void main() {", "vec4 color = texture2D( tDiffuse, vUv );", "gl_FragColor = vec4( color.rgb , color.a );", "gl_FragColor.r = texture2D( tDiffuse, vUv + vec2(0.1,0.0)).r;", "gl_FragColor.g = texture2D( tDiffuse, vUv - vec2(0.1,0.0)).g;", "}" ].join("\n") } //エフェクト結果をスクリーンに描画する var customPass = new THREE.ShaderPass(myEffect); customPass.renderToScreen = true; composer.addPass(customPass); render(); function render() { composer.render(); requestAnimationFrame(render); }
まとめ
THREE.EffectComposerを使うと、オフスクリーンレンダリング明示的にやらなくてよかったり、画面全体を覆うポリゴンを作る必要がなかったりとポストプロセスを行う上で手間がかからない印象でした。 また、ShaderMaterialを使わなくてもシェーダーを定義することができるので、ライトをつかえるなど私のような初心者にはメリットが多そうでした。
THREE.jsでオリジナルのポストプロセスをやってみる
前回オフスクリーンレンダリングについて書きました。
今回は、オフスクリーンレンダリングを利用して、ポストプロセスをやってみたいと思います。
ポストプロセスを簡単に言うと、作成済みのシーンに対して、あとから何か処理を行うことです。
今回は以下のような2つのシーンを掛け合せてみようと思います。
続きを読む