Last active
December 17, 2015 16:28
-
-
Save kishalmi/5638574 to your computer and use it in GitHub Desktop.
three.js util - load shaders from files
requires jquery for $.ajax
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 [email protected] | |
* @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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very handy utility function. Great job.