MMDToonShader.js 3.1 KB

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