Source: stage/buffer/BufferMulti.js

  1. /**
  2. * Creates buffer and sets up shaders for an object3D
  3. * @param {Object} gl
  4. * @param {Ayce.Object3D} object3D
  5. * @param {Ayce.LightContainer} lightContainer
  6. * @class
  7. * @constructor
  8. */
  9. Ayce.BufferMulti = function (gl, object3D, lightContainer) {
  10. if (!object3D instanceof Ayce.Object3D) throw "Can't create buffers for " + object3D;
  11. var modelViewMatrix = new Ayce.Matrix4();
  12. modelViewMatrix.transposeUniform = false;
  13. //VR
  14. var leftMatrix = new Ayce.Matrix4();
  15. var rightMatrix = new Ayce.Matrix4();
  16. var leftNormalMatrix = new Ayce.Matrix3();
  17. var rightNormalMatrix = new Ayce.Matrix3();
  18. var leftPerspektive = null;
  19. var rightPerspektive = null;
  20. var VALUES_PER_POSITION = 3;
  21. var VALUES_PER_NORMAL = 3;
  22. var VALUES_PER_TEXTURE_COORD = 2;
  23. var VALUES_PER_TEXTURE_INDEX = 1;
  24. var VALUES_PER_COLOR = 4;
  25. var useLighting = Boolean(object3D.normals) && lightContainer.lightsCount > 0;
  26. var useNormals = Boolean(object3D.normals) && (useLighting || object3D.shader);
  27. var textureCount = Array.isArray(object3D.imageSrc) ? object3D.imageSrc.length : 1;
  28. var useWireframe = object3D.isWireframe;
  29. this.transparent = object3D.transparent;
  30. var isParticleSystem = Boolean(object3D.geometries && object3D.velocities && object3D.rotationAngles && object3D.lifetimes && object3D.gravities && object3D.gravityExps);
  31. //Shader Attributes
  32. //[attributeName, valueLength, array]
  33. var attributes = [];
  34. attributes.push(["aVertexPosition", VALUES_PER_POSITION, object3D.vertices]);
  35. if(object3D.textureCoords && object3D.imageSrc) attributes.push(["aTextureCoord", VALUES_PER_TEXTURE_COORD, object3D.textureCoords]);
  36. if(object3D.textureCoords && object3D.imageSrc && object3D.textureIndices && textureCount > 1) attributes.push(["aTextureIndex", VALUES_PER_TEXTURE_INDEX, object3D.textureIndices]);
  37. if(object3D.colors)attributes.push(["aVertexColor", VALUES_PER_COLOR, object3D.colors]);
  38. if(useNormals)attributes.push(["aVertexNormal", VALUES_PER_NORMAL, object3D.normals]);
  39. if(object3D.shaderAttributes)Array.prototype.push.apply(attributes, object3D.shaderAttributes);
  40. //Shader Uniforms
  41. var pMatrixUniform = {
  42. transposeUniform: false,
  43. data: []
  44. };
  45. var timeObject = {
  46. time: 0,
  47. startTime: Date.now()
  48. };
  49. var uniformValues = {
  50. useTexture: Boolean(object3D.textureCoords && object3D.imageSrc),
  51. useLighting: useLighting,
  52. useMultiTex: Boolean(object3D.textureIndices),
  53. normalMatrix: new Ayce.Matrix3(),
  54. useSpecularMap: Boolean(object3D.specularMap),
  55. useNormalMap: Boolean(object3D.normalMap)
  56. };
  57. var uniforms = [];
  58. //[uniformName, uniformType, valueObject, uniformArguments]
  59. uniforms.push(["uPMatrix", "uniformMatrix4fv", pMatrixUniform, ["transposeUniform", "data"]]);
  60. uniforms.push(["uMVMatrix", "uniformMatrix4fv", modelViewMatrix, ["transposeUniform", "data"]]);
  61. if(useNormals){
  62. uniformValues.normalMatrix.transposeUniform = false;
  63. uniforms.push(["uNMatrix", "uniformMatrix3fv", uniformValues.normalMatrix, ["transposeUniform", "data"]]);
  64. }
  65. if(useLighting){
  66. uniforms.push(["uAmbientColor", "uniform3f", lightContainer.ambientLight, ["red", "green", "blue"]]);
  67. uniforms.push(["uLightIndex", "uniform1f", lightContainer, ["lightsCount"]]);
  68. uniforms.push(["uPointLightingLocations", "uniform3fv", lightContainer, ["locationsArray"]]);
  69. uniforms.push(["uPointLightingColors", "uniform3fv", lightContainer, ["colorsArray"]]);
  70. uniforms.push(["uSpecularColors", "uniform3fv", lightContainer, ["specColorsArray"]]);
  71. uniforms.push(["uShininess", "uniform1f", object3D, ["shininess"]]);
  72. }
  73. if(isParticleSystem){
  74. uniforms.push(["uTime", "uniform1f", timeObject, ["time"]]);
  75. }
  76. if(object3D.shaderUniforms)Array.prototype.push.apply(uniforms, object3D.shaderUniforms);
  77. //Load Shader
  78. var shaderVert = null;
  79. var shaderFrag = null;
  80. var shaderID = "";
  81. if(object3D.shader){
  82. // console.log("Loading Shader File: " + object3D.shader);
  83. shaderVert = Ayce.XMLLoader.getSourceSynch(object3D.shader + ".vert");
  84. shaderFrag = Ayce.XMLLoader.getSourceSynch(object3D.shader + ".frag");
  85. shaderID = "A"+object3D.shader;
  86. if(object3D.logVertexShader) console.log(shaderVert);
  87. if(object3D.logFragmentShader) console.log(shaderFrag);
  88. }else{
  89. var shaderGenerator = new Ayce.ShaderGenerator();
  90. if(useLighting){
  91. shaderGenerator.useVertexLighting = Boolean(object3D.normals && !object3D.useFragmentLighting);
  92. shaderGenerator.lightsCount = lightContainer.lightsCount;
  93. shaderGenerator.useFragmentLighting = Boolean(object3D.normals && object3D.useFragmentLighting);
  94. shaderGenerator.useSpecularLighting = object3D.useSpecularLighting;
  95. }
  96. shaderGenerator.useNormals = useNormals;
  97. shaderGenerator.useColor = Boolean(object3D.colors);
  98. shaderGenerator.texturesCount = Array.isArray(object3D.imageSrc) ? object3D.imageSrc.length : 1;
  99. shaderGenerator.useTexture = Boolean(object3D.imageSrc && object3D.textureCoords);
  100. shaderGenerator.useSpecularMap = Boolean(object3D.specularMap && object3D.useSpecularLighting);
  101. shaderGenerator.useNormalMap = Boolean(object3D.normalMap);
  102. shaderGenerator.isParticleSystem = isParticleSystem;
  103. shaderGenerator.init();
  104. shaderVert = shaderGenerator.vertexShader;
  105. shaderFrag = shaderGenerator.fragmentShader;
  106. shaderID = "B"+shaderGenerator.useNormals+shaderGenerator.lightsCount+shaderGenerator.texturesCount+
  107. shaderGenerator.useVertexLighting+shaderGenerator.useFragmentLighting+
  108. shaderGenerator.useTexture+shaderGenerator.useColor+shaderGenerator.useSpecularMap+
  109. shaderGenerator.useNormalMap+shaderGenerator.isParticleSystem;
  110. if(object3D.logVertexShader) console.log(shaderVert.replace(/;/g, ";\n").replace(/{/g, "{\n").replace(/}/g, "}\n"));
  111. if(object3D.logFragmentShader) console.log(shaderFrag.replace(/;/g, ";\n").replace(/{/g, "{\n").replace(/}/g, "}\n"));
  112. }
  113. var shader = null;
  114. if(gl.shaders[shaderID]){
  115. shader = gl.shaders[shaderID];
  116. }
  117. else{
  118. shader = new Ayce.Shader(gl, shaderVert, shaderFrag);
  119. gl.shaders[shaderID] = shader;
  120. }
  121. //Create Buffer
  122. var drawMode = useWireframe ? gl.LINES : undefined;
  123. var buffer = new Ayce.Buffer(gl, object3D, shader, attributes, uniforms, drawMode);
  124. if(object3D.twoFaceTransparency) {
  125. var indices = object3D.indices;
  126. indices = indices.slice().reverse().concat(indices);
  127. buffer.indices = new Uint16Array(indices);
  128. }
  129. else{
  130. buffer.indices = new Uint16Array(object3D.indices);
  131. }
  132. buffer.useTexture = Boolean(object3D.textureCoords && object3D.imageSrc);
  133. buffer.useSpecularMap = Boolean(object3D.textureCoords && object3D.specularMap);
  134. buffer.useNormalMap = Boolean(object3D.textureCoords && object3D.normalMap);
  135. buffer.useTransparency = object3D.transparent;
  136. buffer.texturesO3D = (Array.isArray(object3D.imageSrc)) ? object3D.imageSrc : [object3D.imageSrc];
  137. buffer.isSkybox = Boolean(object3D.isSkybox);
  138. buffer.init();
  139. /*********************************************
  140. *
  141. * Render function
  142. *
  143. *********************************************/
  144. var copyMatrix = new Ayce.Matrix4();
  145. /**
  146. * Updates perspective Matrix
  147. * @param {Ayce.Camera} camera
  148. */
  149. this.update = function (camera) {
  150. //Create ModelViewMatrix
  151. Ayce.Matrix4.prototype.copyToMatrix(object3D.modelMatrix, modelViewMatrix);
  152. modelViewMatrix.apply(camera.getViewMatrix());
  153. Ayce.Matrix4.prototype.copyToMatrix(modelViewMatrix, copyMatrix);
  154. copyMatrix.invert();
  155. copyMatrix.transpose();
  156. copyMatrix.getMatrix3(uniformValues.normalMatrix);
  157. pMatrixUniform.data = camera.getPerspectiveMatrix().data;
  158. timeObject = Date.now()-timeObject.startTime;
  159. buffer.update();
  160. };
  161. /**
  162. * Renders buffer
  163. */
  164. this.render = function(){
  165. if(!object3D.visible)return;
  166. buffer.render();
  167. };
  168. /**
  169. * Updates VR perspective Matrices
  170. * @param {Ayce.Camera} camera
  171. */
  172. this.updateVR = function(camera){
  173. //Create ModelViewMatrix Left eye
  174. Ayce.Matrix4.prototype.copyToMatrix(object3D.modelMatrix, leftMatrix);
  175. leftMatrix.apply(camera.getViewMatrix("left"));
  176. Ayce.Matrix4.prototype.copyToMatrix(leftMatrix, copyMatrix);
  177. copyMatrix.invert();
  178. copyMatrix.transpose();
  179. copyMatrix.getMatrix3(leftNormalMatrix);
  180. //Create ModelViewMatrix Right eye
  181. Ayce.Matrix4.prototype.copyToMatrix(object3D.modelMatrix, rightMatrix);
  182. rightMatrix.apply(camera.getViewMatrix("right"));
  183. Ayce.Matrix4.prototype.copyToMatrix(rightMatrix, copyMatrix);
  184. copyMatrix.invert();
  185. copyMatrix.transpose();
  186. copyMatrix.getMatrix3(rightNormalMatrix);
  187. //Set Perspektive Matrix
  188. leftPerspektive = camera.getPerspectiveMatrix("left");
  189. rightPerspektive = camera.getPerspectiveMatrix("right");
  190. //Update Buffer
  191. buffer.update();
  192. };
  193. /**
  194. * Renders VR buffers
  195. * @param {String} eye
  196. */
  197. this.renderVR = function(eye){
  198. if(!object3D.visible)return;
  199. if(eye === "left"){
  200. modelViewMatrix.data = leftMatrix.data;
  201. uniformValues.normalMatrix.data = leftNormalMatrix.data;
  202. pMatrixUniform.data = leftPerspektive.data;
  203. lightContainer.locationsArray = lightContainer.locationsArrayLeftEye;
  204. }
  205. else if(eye === "right"){
  206. modelViewMatrix.data = rightMatrix.data;
  207. uniformValues.normalMatrix.data = rightNormalMatrix.data;
  208. pMatrixUniform.data = rightPerspektive.data;
  209. lightContainer.locationsArray = lightContainer.locationsArrayRightEye;
  210. }
  211. buffer.render();
  212. };
  213. this.dispose = function(){
  214. buffer.dispose();
  215. };
  216. };
  217. Ayce.BufferMulti.prototype = {
  218. };