Rollup build setup to import glsl files and three.js examples

build-tools
rollupjs
glsl
es6
modules

#1

This is a simplified version of the build setup that I use - its a modified version of the rollup.js setup that three.js uses, that compiles ES6 with babel, reads .glsl files that can contain glslify imports and allows importing examples as modules with minimal modification to the code.

It’s just a rollup config, but it can easily be modified for use with gulp as well - if anybody is interested I can post a gulpfile.js version as well.

Node modules required

  • glslify
  • rollup
  • rollup-plugin-babel
  • babel-preset-es2015-loose-rollup ( the ‘loose’ version may sometimes be faster apparently - I haven’t tested this )

Install all of these with

npm install --save-dev glslify rollup rollup-plugin-babel babel-preset-es2015-loose-rollup

Optional npm modules

( I’ll let you figure out if you need these yourself )

  • rollup-plugin-commonjs
  • rollup-plugin-node-resolve
  • rollup-watch (allows you to watch for changes with the -w flag)

Install these as needed with

npm install --save-dev rollup-plugin-commonjs rollup-plugin-node-resolve rollup-watch 

Rollup config file

Next create a file called rollup.config.js in your project root:

Run rollup with:

rollup -c -w

(the -c flag tell it to use the config file, -w is to watch for changes if using rollup-watch)

The code above will look for an (ES6) entry point in js/src/main.js and output an ES5 compatible file suitable for inclusion in a <script> tag to js/main.js.


#2

###Basic Setup

Next, I use three.js as a node module - this isn’t neccessary, but you might have to change things a little if you are including it some other way:

npm install --save three

A simple main file will then be:

//main.js
import * as THREE from 'three';

// other imports

// rest of your code

Importing example files as modules

If we want to import an example, say OrbitControls, we will have to make some minor changes to the file. First, we will need to add

import * as THREE from 'three';

to the top of the file to make the namespace available. Unfortunately though, the imported THREE namespace is not modifiable, so the next line,

THREE.OrbitControls = function ( object, domElement ) {

will cause an error. We’ll change it to:

export default function OrbitControls ( object, domElement ) {

The full modified file is here (only two lines changed)

Now we can import OrbitControls in main.js:

//main.js
import * as THREE from 'three';

import OrbitControls from '../controls/OrbitControls.module.js';

// other imports

// setup code

const controls = new OrbitControls( camera, renderer.domElement );

// rest of your code

I’ve tested this pattern with a couple of the example files, some may need more work though.


#3

Including shader files

Next, we will add simple fragment and vertex shaders. The rollup config will compile files ending in .glsl, .vert and .frag.

If we include two files, example.vert and example.frag in js/src/shaders:

example.vert

void main() {
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
}

example.frag

void main() {
  gl_FragColor = vec4( vec3( 0.5 ), 1.0 );
}

Then we can import them into main:

//main.js
import * as THREE from 'three';
import exampleVert from './shaders/example.vert';
import exampleFrag from './shaders/example.frag';

// other imports

// setup code

const shaderMat = new THREE.ShaderMaterial( {
        vertexShader: exampleVert,
        fragmentShader: exampleFrag,
} );

// rest of your code

Importing glslify shader modules

To include glslify imports, we’ll have to install them with NPM first:

npm install --save glsl-noise

Then we can modify the fragment shader:

Note: I haven’t tested this exact code! It should work though… hopefully

example.frag

#pragma glslify: noise = require(glsl-noise/simplex/2d)

void main() {
  float colour = noise(gl_Position.xy);

  gl_FragColor = vec4( vec3( colour ), 1.0 );
}

#4

Have you got it running with Gulp? I’m trying to bundle custom .glsl files with my Gulp app without success.

I’m using this module: https://www.npmjs.com/package/gulp-glsl with the same gulpfile.js as recommended:

const gulp = require('gulp');
const glsl = require('gulp-glsl');

gulp.src('src/**/*.glsl')
  .pipe(glsl())
  .pipe(gulp.dest('build'));

but always run into compile errors:

#extension GL_OES_standard_derivatives : enable
^
ParseError: Unexpected character '#'`

Have you got custom shaders working with gulp?