glTFShaders.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * @author Tony Parisi / http://www.tonyparisi.com/
  3. */
  4. THREE.glTFShaders = ( function () {
  5. var shaders = [];
  6. return {
  7. add : function(shader) {
  8. shaders.push(shader);
  9. },
  10. remove: function(shader) {
  11. var i = shaders.indexOf(shader);
  12. if ( i !== -1 ) {
  13. shaders.splice( i, 1 );
  14. }
  15. },
  16. removeAll: function(shader) {
  17. // probably want to clean up the shaders, too, but not for now
  18. shaders = [];
  19. },
  20. bindShaderParameters: function(scene) {
  21. for (i = 0; i < shaders.length; i++)
  22. {
  23. shaders[i].bindParameters(scene);
  24. }
  25. },
  26. update : function(scene, camera) {
  27. for (i = 0; i < shaders.length; i++)
  28. {
  29. shaders[i].update(scene, camera);
  30. }
  31. },
  32. };
  33. })();
  34. // Construction/initialization
  35. THREE.glTFShader = function(material, params, object, scene) {
  36. this.material = material;
  37. this.parameters = params.technique.parameters;
  38. this.uniforms = params.technique.uniforms;
  39. this.joints = params.joints;
  40. this.object = object;
  41. this.semantics = {};
  42. this.m4 = new THREE.Matrix4;
  43. }
  44. // bindParameters - connect the uniform values to their source parameters
  45. THREE.glTFShader.prototype.bindParameters = function(scene) {
  46. function findObject(o, p) {
  47. if (o.glTFID == param.node) {
  48. p.sourceObject = o;
  49. }
  50. }
  51. for (var uniform in this.uniforms) {
  52. var pname = this.uniforms[uniform];
  53. var param = this.parameters[pname];
  54. if (param.semantic) {
  55. var p = {
  56. semantic : param.semantic,
  57. uniform: this.material.uniforms[uniform]
  58. };
  59. if (param.node) {
  60. scene.traverse(function(o) { findObject(o, p)});
  61. }
  62. else {
  63. p.sourceObject = this.object;
  64. }
  65. this.semantics[pname] = p;
  66. }
  67. }
  68. }
  69. // Update - update all the uniform values
  70. THREE.glTFShader.prototype.update = function(scene, camera) {
  71. // update scene graph
  72. scene.updateMatrixWorld();
  73. // update camera matrices and frustum
  74. camera.updateMatrixWorld();
  75. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  76. for (var sname in this.semantics) {
  77. var semantic = this.semantics[sname];
  78. if (semantic) {
  79. switch (semantic.semantic) {
  80. case "MODELVIEW" :
  81. var m4 = semantic.uniform.value;
  82. m4.multiplyMatrices(camera.matrixWorldInverse,
  83. semantic.sourceObject.matrixWorld);
  84. break;
  85. case "MODELVIEWINVERSETRANSPOSE" :
  86. var m3 = semantic.uniform.value;
  87. this.m4.multiplyMatrices(camera.matrixWorldInverse,
  88. semantic.sourceObject.matrixWorld);
  89. m3.getNormalMatrix(this.m4);
  90. break;
  91. case "PROJECTION" :
  92. var m4 = semantic.uniform.value;
  93. m4.copy(camera.projectionMatrix);
  94. break;
  95. case "JOINTMATRIX" :
  96. var m4v = semantic.uniform.value;
  97. for (var mi = 0; mi < m4v.length; mi++) {
  98. // So it goes like this:
  99. // SkinnedMesh world matrix is already baked into MODELVIEW;
  100. // ransform joints to local space,
  101. // then transform using joint's inverse
  102. m4v[mi].getInverse(semantic.sourceObject.matrixWorld).
  103. multiply(this.joints[mi].matrixWorld).
  104. multiply(this.object.skeleton.boneInverses[mi]);
  105. }
  106. //console.log("Joint:", semantic)
  107. break;
  108. default :
  109. throw new Error("Unhandled shader semantic" + semantic);
  110. break;
  111. }
  112. }
  113. }
  114. }