(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "three"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports, require("three"));
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports, global.three);
    global.MMDToonShader = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.MMDToonShader = void 0;

  /**
   * MMD Toon Shader
   *
   * This shader is extended from MeshPhongMaterial, and merged algorithms with
   * MeshToonMaterial and MeshMetcapMaterial.
   * Ideas came from https://github.com/mrdoob/three.js/issues/19609
   *
   * Combining steps:
   *  * Declare matcap uniform.
   *  * Add gradientmap_pars_fragment.
   *  * Use gradient irradiances instead of dotNL irradiance from MeshPhongMaterial.
   *    (Replace lights_phong_pars_fragment with lights_mmd_toon_pars_fragment)
   *  * Add mmd_toon_matcap_fragment.
   */
  var lights_mmd_toon_pars_fragment = "\nvarying vec3 vViewPosition;\n\nstruct BlinnPhongMaterial {\n\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n\n};\n\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\n\n}\n\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\n}\n\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n\n#define Material_LightProbeLOD( material )\t(0)\n";
  var mmd_toon_matcap_fragment = "\n#ifdef USE_MATCAP\n\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\tvec4 matcapColor = texture2D( matcap, uv );\n\tmatcapColor = matcapTexelToLinear( matcapColor );\n\n\t#ifdef MATCAP_BLENDING_MULTIPLY\n\n\t\toutgoingLight *= matcapColor.rgb;\n\n\t#elif defined( MATCAP_BLENDING_ADD )\n\n\t\toutgoingLight += matcapColor.rgb;\n\n\t#endif\n\n#endif\n";
  var MMDToonShader = {
    defines: {
      TOON: true,
      MATCAP: true,
      MATCAP_BLENDING_ADD: true
    },
    uniforms: _three.UniformsUtils.merge([_three.ShaderLib.toon.uniforms, _three.ShaderLib.phong.uniforms, _three.ShaderLib.matcap.uniforms]),
    vertexShader: _three.ShaderLib.phong.vertexShader,
    fragmentShader: _three.ShaderLib.phong.fragmentShader.replace('#include <common>', "\n\t\t\t\t\t#ifdef USE_MATCAP\n\t\t\t\t\t\tuniform sampler2D matcap;\n\t\t\t\t\t#endif\n\n\t\t\t\t\t#include <common>\n\t\t\t\t").replace('#include <envmap_common_pars_fragment>', "\n\t\t\t\t\t#include <gradientmap_pars_fragment>\n\t\t\t\t\t#include <envmap_common_pars_fragment>\n\t\t\t\t").replace('#include <lights_phong_pars_fragment>', lights_mmd_toon_pars_fragment).replace('#include <envmap_fragment>', "\n\t\t\t\t\t#include <envmap_fragment>\n\t\t\t\t\t".concat(mmd_toon_matcap_fragment, "\n\t\t\t\t"))
  };
  _exports.MMDToonShader = MMDToonShader;
});