WebGL - is there an alternative to embedding shaders in HTML?
Following @droidballoon's hint I ended up using stack.gl which "is an open software ecosystem for WebGL, built on top of browserify and npm".
Its glslify provides a browserify transform which can be used in conjunction with gl-shader in order to load shaders. The Javascript would look something like this:
var glslify = require('glslify');
var loadShader = require('gl-shader');
var createContext = require('gl-context');
var canvas = document.createElement('canvas');
var gl = createContext(canvas);
var shader = loadShader(
gl,
glslify('./shader.vert'),
glslify('./shader.frag')
);
EDIT 2021 this answer is antiquated. You should probably look for something else.
I've been using require.js's text plugin.
Here's a snippet:
define(
/* Dependencies (I also loaded the gl-matrix library) */
["glmatrix", "text!shaders/fragment.shader", "text!shaders/vertex.shader"],
/* Callback when all has been loaded */
function(glmatrix, fragmentShaderCode, vertexShaderCode) {
....
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
....
}
);
The directory structure is as follows:
~require-gl-shaders/
|~js/
| |+lib/
| |~shaders/
| | |-fragment.shader
| | `-vertex.shader
| |-glmatrix.js - gl-matrix library
| |-shader.js
| |-text.js - require.js's text plugin
|-index.html
|-main.js
`-require.js - the require.js library
Personally, I had a little bit of learning curve with require, but it really helped me keep cleaner code.
Yup, a local server's really the only way to go if you want to use XHR. I've written a bunch of WebGL lessons, and have often considered moving away from embedding the shaders in the HTML, but have been scared off by amount of explanation about web security I'd need to write...
Fortunately it's super easy to run a server. Just open a shell then
cd path-to-files
python -m SimpleHTTPServer
Then point your browser to
http://localhost:8000
That works for simple cases like textures and GLSL. For video and audio streaming see
What is a faster alternative to Python's http.server (or SimpleHTTPServer)?
On the other hand every browser that supports WebGL supports ES6 mutli-line template literals so if you don't care about old browsers you can just put you shaders in JavaScript using backticks like this
var vertexShaderSource = `
attribute vec4 position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * position;
}
`;