Skip to content

Instantly share code, notes, and snippets.

@kishalmi
Last active December 17, 2015 16:28
Show Gist options
  • Save kishalmi/5638574 to your computer and use it in GitHub Desktop.
Save kishalmi/5638574 to your computer and use it in GitHub Desktop.
three.js util - load shaders from files requires jquery for $.ajax
// object with shader paths (optinally nested, for better structure)
// the paths get replaced with the actual file content.
var shaders = {
atmoVert: 'glsl/atmo.vert.c',
car: {
vert: 'glsl/car.vert.c',
frag: 'glsl/car.frag.c'
}
};
// usage:
loadShaders( shaders,
function(progress) {
console.log(progress,'loaded');
}, function() {
console.log('done loading shaders.');
// now use like:
carMaterial.vertexShader = shaders.car.vert;
carMaterial.fragmentShader = shaders.car.frag;
atmoMaterial.vertexShader = shaders.atmoVert;
}
);
/**
* load shaders from files
* @author lmg@kishalmi.net
* @param shaders - (optinally nested) object with shader paths - to be replaced with actual file contents
* @param callbackProgress - param: (total) progress as float
* @param callbackSuccess - called once all shaders are loaded
*/
function loadShaders(shaders, callbackProgress, callbackSuccess) {
// shift back if progress cb skipped
if (!$.isFunction(callbackSuccess)) {
callbackSuccess = callbackProgress;
callbackProgress = null;
}
var loaded = 0, total = 0;
var processObj = function (obj) {
if (typeof(obj) === 'object')
for (var key in obj)
if (typeof(obj[key]) === 'string')
loadShader(obj, key);
else
processObj(obj[key]);
};
var loadShader = function (obj, key) {
total++;
$.ajax({
url: obj[key],
dataType: 'text',
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function (event) {
if (event.lengthComputable && event.loaded < event.total && callbackProgress)
callbackProgress((loaded + event.loaded / event.total) / total);
}, false);
return xhr;
},
success: function (data) {
// replace #includes in shaders, if already loaded
var match, reInclude = /^#include ['"](.*)?['"]/mg;
while (match = reInclude.exec(data)) {
if (shaders.hasOwnProperty(match[1]))
data = data.replace(match[0], shaders[match[1]]);
else
console.error('ERROR shader "' + obj[key] + '" #include "' + match[1] + '" not found!');
}
obj[key] = data;
},
complete: function () {
loaded++;
if (callbackProgress) callbackProgress(loaded / total);
if (loaded < total) return;
if (callbackSuccess) callbackSuccess();
},
error: function (jqXHR, textStatus, errorThrown) {
console.error('ERROR loading "' + obj[key] + '": ' + textStatus);
}
});
};
processObj(shaders);
}
@RubenCordeiro
Copy link

Very handy utility function. Great job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment