WebGLRenderLists.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. function painterSortStable( a, b ) {
  5. if ( a.renderOrder !== b.renderOrder ) {
  6. return a.renderOrder - b.renderOrder;
  7. } else if ( a.program && b.program && a.program !== b.program ) {
  8. return a.program.id - b.program.id;
  9. } else if ( a.material.id !== b.material.id ) {
  10. return a.material.id - b.material.id;
  11. } else if ( a.z !== b.z ) {
  12. return a.z - b.z;
  13. } else {
  14. return a.id - b.id;
  15. }
  16. }
  17. function reversePainterSortStable( a, b ) {
  18. if ( a.renderOrder !== b.renderOrder ) {
  19. return a.renderOrder - b.renderOrder;
  20. } if ( a.z !== b.z ) {
  21. return b.z - a.z;
  22. } else {
  23. return a.id - b.id;
  24. }
  25. }
  26. function WebGLRenderList() {
  27. var opaque = [];
  28. var opaqueLastIndex = - 1;
  29. var transparent = [];
  30. var transparentLastIndex = - 1;
  31. function init() {
  32. opaqueLastIndex = - 1;
  33. transparentLastIndex = - 1;
  34. }
  35. function push( object, geometry, material, z, group ) {
  36. var array, index;
  37. // allocate the next position in the appropriate array
  38. if ( material.transparent ) {
  39. array = transparent;
  40. index = ++ transparentLastIndex;
  41. } else {
  42. array = opaque;
  43. index = ++ opaqueLastIndex;
  44. }
  45. // recycle existing render item or grow the array
  46. var renderItem = array[ index ];
  47. if ( renderItem ) {
  48. renderItem.id = object.id;
  49. renderItem.object = object;
  50. renderItem.geometry = geometry;
  51. renderItem.material = material;
  52. renderItem.program = material.program;
  53. renderItem.renderOrder = object.renderOrder;
  54. renderItem.z = z;
  55. renderItem.group = group;
  56. } else {
  57. renderItem = {
  58. id: object.id,
  59. object: object,
  60. geometry: geometry,
  61. material: material,
  62. program: material.program,
  63. renderOrder: object.renderOrder,
  64. z: z,
  65. group: group
  66. };
  67. // assert( index === array.length );
  68. array.push( renderItem );
  69. }
  70. }
  71. function finish() {
  72. opaque.length = opaqueLastIndex + 1;
  73. transparent.length = transparentLastIndex + 1;
  74. }
  75. function sort() {
  76. opaque.sort( painterSortStable );
  77. transparent.sort( reversePainterSortStable );
  78. }
  79. return {
  80. opaque: opaque,
  81. transparent: transparent,
  82. init: init,
  83. push: push,
  84. finish: finish,
  85. sort: sort
  86. };
  87. }
  88. function WebGLRenderLists() {
  89. var lists = {};
  90. function get( scene, camera ) {
  91. var hash = scene.id + ',' + camera.id;
  92. var list = lists[ hash ];
  93. if ( list === undefined ) {
  94. // console.log( 'THREE.WebGLRenderLists:', hash );
  95. list = new WebGLRenderList();
  96. lists[ hash ] = list;
  97. }
  98. return list;
  99. }
  100. function dispose() {
  101. lists = {};
  102. }
  103. return {
  104. get: get,
  105. dispose: dispose
  106. };
  107. }
  108. export { WebGLRenderLists };