WebGLRenderer.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /**
  2. * @author supereggbert / http://www.paulbrunt.co.uk/
  3. * @author mrdoob / http://mrdoob.com/
  4. */
  5. THREE.WebGLRenderer = function () {
  6. var _canvas = document.createElement( 'canvas' ), _gl, _program,
  7. viewMatrix = new THREE.Matrix4(), normalMatrix;
  8. this.domElement = _canvas;
  9. this.autoClear = true;
  10. initGL();
  11. initProgram();
  12. this.setSize = function ( width, height ) {
  13. _canvas.width = width;
  14. _canvas.height = height;
  15. _gl.viewport( 0, 0, _canvas.width, _canvas.height );
  16. };
  17. this.clear = function () {
  18. _gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );
  19. };
  20. this.render = function ( scene, camera ) {
  21. var face, faceColor, object, material, normal, lightColor, lightPosition, light,
  22. vertexArray, faceArray, colorArray, normalArray, vertexIndex,
  23. o, ol, f, fl, m, ml, i, v1, v2, v3, v4,
  24. l, ll;
  25. if ( this.autoClear ) {
  26. this.clear();
  27. }
  28. //lighting
  29. _gl.uniform1i( _program.enableLighting, scene.lights.length );
  30. for ( l = 0, ll = scene.lights.length; l < ll; l++ ) {
  31. light = scene.lights[ l ];
  32. if ( light instanceof THREE.AmbientLight ) {
  33. lightColor = light.color;
  34. _gl.uniform3f( _program.ambientColor, lightColor.r, lightColor.g, lightColor.b );
  35. } else if( light instanceof THREE.DirectionalLight ) {
  36. lightColor = light.color;
  37. lightPosition = light.position;
  38. _gl.uniform3f( _program.lightingDirection, lightPosition.x, lightPosition.y, lightPosition.z );
  39. _gl.uniform3f( _program.directionalColor, lightColor.r, lightColor.g, lightColor.b );
  40. }
  41. }
  42. for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {
  43. object = scene.objects[ o ];
  44. if ( object instanceof THREE.Mesh ) {
  45. if ( !object.__webGLVertexBuffer ) {
  46. vertexArray = [];
  47. faceArray = [];
  48. colorArray = [];
  49. normalArray = [];
  50. vertexIndex = 0;
  51. for ( f = 0, fl = object.geometry.faces.length; f < fl; f++ ) {
  52. face = object.geometry.faces[ f ];
  53. faceColor = face.color;
  54. normal = face.normal;
  55. if ( face instanceof THREE.Face3 ) {
  56. v1 = object.geometry.vertices[ face.a ].position;
  57. v2 = object.geometry.vertices[ face.b ].position;
  58. v3 = object.geometry.vertices[ face.c ].position;
  59. vertexArray.push( v1.x, v1.y, v1.z );
  60. vertexArray.push( v2.x, v2.y, v2.z );
  61. vertexArray.push( v3.x, v3.y, v3.z );
  62. normalArray.push( normal.x, normal.y, normal.z );
  63. normalArray.push( normal.x, normal.y, normal.z );
  64. normalArray.push( normal.x, normal.y, normal.z );
  65. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  66. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  67. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  68. faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
  69. vertexIndex += 3;
  70. } else if ( face instanceof THREE.Face4 ) {
  71. v1 = object.geometry.vertices[ face.a ].position;
  72. v2 = object.geometry.vertices[ face.b ].position;
  73. v3 = object.geometry.vertices[ face.c ].position;
  74. v4 = object.geometry.vertices[ face.d ].position;
  75. vertexArray.push( v1.x, v1.y, v1.z );
  76. vertexArray.push( v2.x, v2.y, v2.z );
  77. vertexArray.push( v3.x, v3.y, v3.z );
  78. vertexArray.push( v4.x, v4.y, v4.z );
  79. normalArray.push( normal.x, normal.y, normal.z );
  80. normalArray.push( normal.x, normal.y, normal.z );
  81. normalArray.push( normal.x, normal.y, normal.z );
  82. normalArray.push( normal.x, normal.y, normal.z );
  83. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  84. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  85. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  86. colorArray.push( faceColor.r, faceColor.g, faceColor.b, faceColor.a );
  87. faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
  88. faceArray.push( vertexIndex, vertexIndex + 2, vertexIndex + 3 );
  89. vertexIndex += 4;
  90. }
  91. }
  92. if ( !vertexArray.length ) {
  93. continue;
  94. }
  95. object.__webGLVertexBuffer = _gl.createBuffer();
  96. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
  97. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );
  98. object.__webGLNormalBuffer = _gl.createBuffer();
  99. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
  100. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );
  101. object.__webGLColorBuffer = _gl.createBuffer();
  102. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLColorBuffer );
  103. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( colorArray ), _gl.STATIC_DRAW );
  104. object.__webGLFaceBuffer = _gl.createBuffer();
  105. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, object.__webGLFaceBuffer );
  106. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );
  107. object.__webGLFaceCount = faceArray.length;
  108. }
  109. viewMatrix.multiply( camera.matrix, object.matrix );
  110. _program.viewMatrixArray = new Float32Array( viewMatrix.flatten() );
  111. _program.projectionMatrixArray = new Float32Array( camera.projectionMatrix.flatten() );
  112. normalMatrix = THREE.Matrix4.makeInvert(viewMatrix).transpose();
  113. _program.normalMatrixArray = new Float32Array( normalMatrix.flatten() );
  114. _gl.uniformMatrix4fv( _program.viewMatrix, false, _program.viewMatrixArray );
  115. _gl.uniformMatrix4fv( _program.projectionMatrix, false, _program.projectionMatrixArray );
  116. _gl.uniformMatrix4fv( _program.normalMatrix, false, _program.normalMatrixArray );
  117. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
  118. _gl.vertexAttribPointer( _program.position, 3, _gl.FLOAT, false, 0, 0 );
  119. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
  120. _gl.vertexAttribPointer( _program.normal, 3, _gl.FLOAT, false, 0, 0 );
  121. for ( m = 0, ml = object.material.length; m < ml; m++ ) {
  122. material = object.material[ m ];
  123. if ( material instanceof THREE.MeshColorFillMaterial ) {
  124. if ( !material.__webGLColorBuffer ) {
  125. colorArray = [];
  126. for ( i = 0; i < object.__webGLFaceCount; i ++ ) {
  127. colorArray.push( material.color.r, material.color.g, material.color.b, material.color.a );
  128. }
  129. material.__webGLColorBuffer = _gl.createBuffer();
  130. _gl.bindBuffer( _gl.ARRAY_BUFFER, material.__webGLColorBuffer );
  131. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( colorArray ), _gl.STATIC_DRAW );
  132. }
  133. _gl.bindBuffer( _gl.ARRAY_BUFFER, material.__webGLColorBuffer );
  134. _gl.vertexAttribPointer( _program.color, 4, _gl.FLOAT, false, 0, 0 );
  135. } else if ( material instanceof THREE.MeshFaceColorFillMaterial ) {
  136. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLColorBuffer );
  137. _gl.enableVertexAttribArray( _program.color );
  138. _gl.vertexAttribPointer( _program.color, 4, _gl.FLOAT, false, 0, 0 );
  139. }
  140. }
  141. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, object.__webGLFaceBuffer );
  142. _gl.drawElements( _gl.TRIANGLES, object.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
  143. }
  144. }
  145. };
  146. function initGL() {
  147. try {
  148. _gl = _canvas.getContext( 'experimental-webgl' );
  149. } catch(e) { }
  150. if (!_gl) {
  151. alert("WebGL not supported");
  152. throw "cannot create webgl context";
  153. }
  154. _gl.clearColor( 0, 0, 0, 1 );
  155. _gl.clearDepth( 1 );
  156. _gl.enable( _gl.DEPTH_TEST );
  157. _gl.depthFunc( _gl.LEQUAL );
  158. _gl.enable( _gl.BLEND );
  159. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
  160. // _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); // cool!
  161. _gl.clearColor( 0, 0, 0, 0 );
  162. }
  163. function initProgram() {
  164. _program = _gl.createProgram();
  165. _gl.attachShader( _program, getShader( "fragment", [
  166. "#ifdef GL_ES",
  167. "precision highp float;",
  168. "#endif",
  169. "varying vec4 vcolor;",
  170. "varying vec3 lightWeighting;",
  171. "void main(){",
  172. "gl_FragColor = vec4(vcolor.rgb * lightWeighting, vcolor.a);",
  173. "}"
  174. ].join("\n") ) );
  175. _gl.attachShader( _program, getShader( "vertex", [
  176. "attribute vec3 position;",
  177. "attribute vec3 normal;",
  178. "attribute vec4 color;",
  179. "uniform bool enableLighting;",
  180. "uniform vec3 ambientColor;",
  181. "uniform vec3 directionalColor;",
  182. "uniform vec3 lightingDirection;",
  183. "uniform mat4 viewMatrix;",
  184. "uniform mat4 projectionMatrix;",
  185. "uniform mat4 normalMatrix;",
  186. "varying vec4 vcolor;",
  187. "varying vec3 lightWeighting;",
  188. "void main(void) {",
  189. "if(!enableLighting) {",
  190. "lightWeighting = vec3(1.0, 1.0, 1.0);",
  191. "} else {",
  192. "vec4 transformedNormal = normalMatrix * vec4(normal, 1.0);",
  193. "float directionalLightWeighting = max(dot(transformedNormal.xyz, lightingDirection), 0.0);",
  194. "lightWeighting = ambientColor + directionalColor * directionalLightWeighting;",
  195. "}",
  196. "vcolor = color;",
  197. "gl_Position = projectionMatrix * viewMatrix * vec4( position, 1.0 );",
  198. "}"].join("\n") ) );
  199. _gl.linkProgram( _program );
  200. if ( !_gl.getProgramParameter( _program, _gl.LINK_STATUS ) ) {
  201. alert( "Could not initialise shaders" );
  202. }
  203. _gl.useProgram( _program );
  204. _program.viewMatrix = _gl.getUniformLocation( _program, "viewMatrix" );
  205. _program.projectionMatrix = _gl.getUniformLocation( _program, "projectionMatrix" );
  206. _program.normalMatrix = _gl.getUniformLocation( _program, "normalMatrix" );
  207. _program.enableLighting = _gl.getUniformLocation(_program, 'enableLighting');
  208. _program.ambientColor = _gl.getUniformLocation(_program, 'ambientColor');
  209. _program.directionalColor = _gl.getUniformLocation(_program, 'directionalColor');
  210. _program.lightingDirection = _gl.getUniformLocation(_program, 'lightingDirection');
  211. _program.color = _gl.getAttribLocation( _program, "color" );
  212. _gl.enableVertexAttribArray( _program.color );
  213. _program.position = _gl.getAttribLocation( _program, "position" );
  214. _gl.enableVertexAttribArray( _program.position );
  215. _program.normal = _gl.getAttribLocation( _program, "normal" );
  216. _gl.enableVertexAttribArray( _program.normal );
  217. _program.viewMatrixArray = new Float32Array(16);
  218. _program.projectionMatrixArray = new Float32Array(16);
  219. }
  220. function getShader( type, string ) {
  221. var shader;
  222. if ( type == "fragment" ) {
  223. shader = _gl.createShader( _gl.FRAGMENT_SHADER );
  224. } else if ( type == "vertex" ) {
  225. shader = _gl.createShader( _gl.VERTEX_SHADER );
  226. }
  227. _gl.shaderSource( shader, string );
  228. _gl.compileShader( shader );
  229. if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
  230. alert( _gl.getShaderInfoLog( shader ) );
  231. return null;
  232. }
  233. return shader;
  234. }
  235. };