test of ThreeJS + Webpack + HMR
MIT License
Hot module replacement with ThreeJS + Webpack, reloading shaders without destroying application state.
Click below to see a video demo.
This is experimental and a proof of concept. It only exists for reference and to hash out ideas for how it can all work in practice. If you want to help, feel free to discuss ideas/etc in the issue tracker.
Shader materials intended to be hot-replaced must be defined in their own file with top-level vertexShader
and fragmentShader
strings. Typically this module will export a RawShaderMaterial
, although ShaderMaterial
should also work.
Currently, the module.hot
boilerplate is manually defined. See the following:
In a future version, this will be instrumented by a Babel transform, so that your "hot-shader" modules can just look like this:
// my-shader.js
const vertexShader = '...'
const fragmentShader = '...'
export default function () {
return new THREE.RawShaderMaterial({
vertexShader, fragmentShader
})
}
This approach works with regular inline strings (like ES2015 template strings), but we can also take advantage of glslify for a more advanced/powerful workflow.
This allows our GLSL to be separated into files, so that it receives its own syntax highlighting and auto-completion. It also supports source transforms like hex colors and import statements to pull in GLSL components from npm.
precision mediump float;
// shader components from npm
import noise from 'glsl-noise/simplex/3d';
varying vec2 vUv;
void main () {
float n = noise(vec3(vUv.xy * 10.0, 1.0));
n = smoothstep(0.0, 0.1, n);
// hex colors for convenience
vec3 color = mix(vec3(#03A9F4), vec3(#3F51B5), n);
gl_FragColor = vec4(color, 1.0);
}
ify-loader
The webpack config is using ify-loader. This is not strictly necessary, but solves some glslify
issues for us:
"browserify"
and "glslify"
configuration in our local package.json
glslify(file, { ... })
syntax without relying on Webpack require
overloadsClone, install and run:
git clone https://github.com/mattdesl/webpack-three-hmr-test.git
# setup
cd webpack-three-hmr-test
npm install
# start dev server
npm start
Now open localhost:9966
.
Make changes to client.js and the browser will trigger a hard-refresh. Make changes to materials/inline.js or the GLSL in materials/shaders and they will be updated with Hot Module Replacement, to avoid destroying application state.
Since I am new to webpack and authoring babel plugins, it will probably be a while before this is all realized properly. Some things to focus on, and areas I could use help with:
glslify
, e.g. a missing import? See react-transform errors for example.browserify-hmr
leaves a lot to be desired.MIT, see LICENSE.md for details.