MultUtils.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. const hashArray = [];
  2. export function serializeDefines(defines, names) {
  3. const len = names.length;
  4. for (let i = 0; i < len; i++) {
  5. const name = names[i];
  6. hashArray[i] = name + defines[name];
  7. }
  8. hashArray.length = len;
  9. return hashArray.join('');
  10. }
  11. export function serializePass(pass, excludeProperties = false) {
  12. let str = pass._programName + pass._cullMode;
  13. if (pass._blend) {
  14. str += pass._blendEq + pass._blendAlphaEq + pass._blendSrc + pass._blendDst
  15. + pass._blendSrcAlpha + pass._blendDstAlpha + pass._blendColor;
  16. }
  17. if (pass._depthTest) {
  18. str += pass._depthWrite + pass._depthFunc;
  19. }
  20. if (pass._stencilTest) {
  21. str += pass._stencilFuncFront + pass._stencilRefFront + pass._stencilMaskFront
  22. + pass._stencilFailOpFront + pass._stencilZFailOpFront + pass._stencilZPassOpFront
  23. + pass._stencilWriteMaskFront
  24. + pass._stencilFuncBack + pass._stencilRefBack + pass._stencilMaskBack
  25. + pass._stencilFailOpBack + pass._stencilZFailOpBack + pass._stencilZPassOpBack
  26. + pass._stencilWriteMaskBack;
  27. }
  28. str += serializeDefines(pass._defines, pass._defineNames);
  29. if (!excludeProperties) {
  30. str += serializeUniforms(pass._properties, pass._propertyNames);
  31. }
  32. return str;
  33. }
  34. export function serializePasses(passes, uniforms = false) {
  35. let hashData = '';
  36. for (let i = 0; i < passes.length; i++) {
  37. hashData += serializePass(passes[i], uniforms);
  38. }
  39. return hashData;
  40. }
  41. export function serializeUniforms(uniforms, names) {
  42. let index = 0;
  43. for (let i = 0, len = names.length; i < len; i++) {
  44. let param = uniforms[names[i]];
  45. let prop = param.value;
  46. if (!prop) {
  47. continue;
  48. }
  49. if (prop._id != undefined) {
  50. continue;
  51. }
  52. else {
  53. hashArray[index] = prop.toString();
  54. }
  55. index++
  56. }
  57. hashArray.length = index;
  58. return hashArray.join(';');
  59. }
  60. export function murmurhash2(str, seed) {
  61. var
  62. l = str.length,
  63. h = seed ^ l,
  64. i = 0,
  65. k;
  66. while (l >= 4) {
  67. k =
  68. ((str.charCodeAt(i) & 0xff)) |
  69. ((str.charCodeAt(++i) & 0xff) << 8) |
  70. ((str.charCodeAt(++i) & 0xff) << 16) |
  71. ((str.charCodeAt(++i) & 0xff) << 24);
  72. k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
  73. k ^= k >>> 24;
  74. k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
  75. h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
  76. l -= 4;
  77. ++i;
  78. }
  79. switch (l) {
  80. case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
  81. case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
  82. case 1: h ^= (str.charCodeAt(i) & 0xff);
  83. h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
  84. }
  85. h ^= h >>> 13;
  86. h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
  87. h ^= h >>> 15;
  88. return h >>> 0;
  89. }
  90. export function getMaterialHash(material: cc.Material) {
  91. let hash = '';
  92. //@ts-ignore
  93. // hash += serializePasses(effect.passes, false);
  94. let effect = material._effect;
  95. if (effect) {
  96. hash += serializePasses(effect.passes, false);
  97. }
  98. return murmurhash2(hash, 666);
  99. }