MMDToonShader.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * MMD Toon Shader
  3. *
  4. * This shader is extended from MeshPhongMaterial, and merged algorithms with
  5. * MeshToonMaterial and MeshMetcapMaterial.
  6. * Ideas came from https://github.com/mrdoob/three.js/issues/19609
  7. *
  8. * Combining steps:
  9. * * Declare matcap uniform.
  10. * * Add gradientmap_pars_fragment.
  11. * * Use gradient irradiances instead of dotNL irradiance from MeshPhongMaterial.
  12. * (Replace lights_phong_pars_fragment with lights_mmd_toon_pars_fragment)
  13. * * Add mmd_toon_matcap_fragment.
  14. */
  15. import { UniformsUtils, ShaderLib } from 'three';
  16. const lights_mmd_toon_pars_fragment = /* glsl */`
  17. varying vec3 vViewPosition;
  18. struct BlinnPhongMaterial {
  19. vec3 diffuseColor;
  20. vec3 specularColor;
  21. float specularShininess;
  22. float specularStrength;
  23. };
  24. void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
  25. vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;
  26. reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
  27. reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;
  28. }
  29. void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
  30. reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
  31. }
  32. #define RE_Direct RE_Direct_BlinnPhong
  33. #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong
  34. `;
  35. const mmd_toon_matcap_fragment = /* glsl */`
  36. #ifdef USE_MATCAP
  37. vec3 viewDir = normalize( vViewPosition );
  38. vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );
  39. vec3 y = cross( viewDir, x );
  40. vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks
  41. vec4 matcapColor = texture2D( matcap, uv );
  42. #ifdef MATCAP_BLENDING_MULTIPLY
  43. outgoingLight *= matcapColor.rgb;
  44. #elif defined( MATCAP_BLENDING_ADD )
  45. outgoingLight += matcapColor.rgb;
  46. #endif
  47. #endif
  48. `;
  49. const MMDToonShader = {
  50. name: 'MMDToonShader',
  51. defines: {
  52. TOON: true,
  53. MATCAP: true,
  54. MATCAP_BLENDING_ADD: true,
  55. },
  56. uniforms: UniformsUtils.merge( [
  57. ShaderLib.toon.uniforms,
  58. ShaderLib.phong.uniforms,
  59. ShaderLib.matcap.uniforms,
  60. ] ),
  61. vertexShader:
  62. ShaderLib.phong.vertexShader
  63. .replace(
  64. '#include <envmap_pars_vertex>',
  65. ''
  66. )
  67. .replace(
  68. '#include <envmap_vertex>',
  69. ''
  70. ),
  71. fragmentShader:
  72. ShaderLib.phong.fragmentShader
  73. .replace(
  74. '#include <common>',
  75. `
  76. #ifdef USE_MATCAP
  77. uniform sampler2D matcap;
  78. #endif
  79. #include <common>
  80. `
  81. )
  82. .replace(
  83. '#include <envmap_common_pars_fragment>',
  84. `
  85. #include <gradientmap_pars_fragment>
  86. `
  87. )
  88. .replace(
  89. '#include <envmap_pars_fragment>',
  90. ''
  91. )
  92. .replace(
  93. '#include <lights_phong_pars_fragment>',
  94. lights_mmd_toon_pars_fragment
  95. )
  96. .replace(
  97. '#include <envmap_fragment>',
  98. `
  99. ${mmd_toon_matcap_fragment}
  100. `
  101. )
  102. };
  103. export { MMDToonShader };