WebGLShaderCache.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. let _id = 0;
  2. class WebGLShaderCache {
  3. constructor() {
  4. this.shaderCache = new Map();
  5. this.materialCache = new Map();
  6. }
  7. update( material ) {
  8. const vertexShader = material.vertexShader;
  9. const fragmentShader = material.fragmentShader;
  10. const vertexShaderStage = this._getShaderStage( vertexShader );
  11. const fragmentShaderStage = this._getShaderStage( fragmentShader );
  12. const materialShaders = this._getShaderCacheForMaterial( material );
  13. if ( materialShaders.has( vertexShaderStage ) === false ) {
  14. materialShaders.add( vertexShaderStage );
  15. vertexShaderStage.usedTimes ++;
  16. }
  17. if ( materialShaders.has( fragmentShaderStage ) === false ) {
  18. materialShaders.add( fragmentShaderStage );
  19. fragmentShaderStage.usedTimes ++;
  20. }
  21. return this;
  22. }
  23. remove( material ) {
  24. const materialShaders = this.materialCache.get( material );
  25. for ( const shaderStage of materialShaders ) {
  26. shaderStage.usedTimes --;
  27. if ( shaderStage.usedTimes === 0 ) this.shaderCache.delete( shaderStage.code );
  28. }
  29. this.materialCache.delete( material );
  30. return this;
  31. }
  32. getVertexShaderID( material ) {
  33. return this._getShaderStage( material.vertexShader ).id;
  34. }
  35. getFragmentShaderID( material ) {
  36. return this._getShaderStage( material.fragmentShader ).id;
  37. }
  38. dispose() {
  39. this.shaderCache.clear();
  40. this.materialCache.clear();
  41. }
  42. _getShaderCacheForMaterial( material ) {
  43. const cache = this.materialCache;
  44. let set = cache.get( material );
  45. if ( set === undefined ) {
  46. set = new Set();
  47. cache.set( material, set );
  48. }
  49. return set;
  50. }
  51. _getShaderStage( code ) {
  52. const cache = this.shaderCache;
  53. let stage = cache.get( code );
  54. if ( stage === undefined ) {
  55. stage = new WebGLShaderStage( code );
  56. cache.set( code, stage );
  57. }
  58. return stage;
  59. }
  60. }
  61. class WebGLShaderStage {
  62. constructor( code ) {
  63. this.id = _id ++;
  64. this.code = code;
  65. this.usedTimes = 0;
  66. }
  67. }
  68. export { WebGLShaderCache };
粤ICP备19079148号