839 lines
174 KiB
JavaScript
839 lines
174 KiB
JavaScript
|
|
/*!
|
||
|
|
* @pixiv/three-vrm-materials-mtoon v3.4.1
|
||
|
|
* MToon (toon material) module for @pixiv/three-vrm
|
||
|
|
*
|
||
|
|
* Copyright (c) 2019-2025 pixiv Inc.
|
||
|
|
* @pixiv/three-vrm-materials-mtoon is distributed under MIT License
|
||
|
|
* https://github.com/pixiv/three-vrm/blob/release/LICENSE
|
||
|
|
*/
|
||
|
|
var __defProp = Object.defineProperty;
|
||
|
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
||
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
|
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
||
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||
|
|
var __spreadValues = (a, b) => {
|
||
|
|
for (var prop in b || (b = {}))
|
||
|
|
if (__hasOwnProp.call(b, prop))
|
||
|
|
__defNormalProp(a, prop, b[prop]);
|
||
|
|
if (__getOwnPropSymbols)
|
||
|
|
for (var prop of __getOwnPropSymbols(b)) {
|
||
|
|
if (__propIsEnum.call(b, prop))
|
||
|
|
__defNormalProp(a, prop, b[prop]);
|
||
|
|
}
|
||
|
|
return a;
|
||
|
|
};
|
||
|
|
var __async = (__this, __arguments, generator) => {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
var fulfilled = (value) => {
|
||
|
|
try {
|
||
|
|
step(generator.next(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var rejected = (value) => {
|
||
|
|
try {
|
||
|
|
step(generator.throw(value));
|
||
|
|
} catch (e) {
|
||
|
|
reject(e);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
||
|
|
step((generator = generator.apply(__this, __arguments)).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/MToonMaterialLoaderPlugin.ts
|
||
|
|
import * as THREE5 from "three";
|
||
|
|
|
||
|
|
// src/GLTFMToonMaterialParamsAssignHelper.ts
|
||
|
|
import * as THREE2 from "three";
|
||
|
|
|
||
|
|
// src/utils/setTextureColorSpace.ts
|
||
|
|
import * as THREE from "three";
|
||
|
|
var colorSpaceEncodingMap = {
|
||
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||
|
|
"": 3e3,
|
||
|
|
srgb: 3001
|
||
|
|
};
|
||
|
|
function setTextureColorSpace(texture, colorSpace) {
|
||
|
|
if (parseInt(THREE.REVISION, 10) >= 152) {
|
||
|
|
texture.colorSpace = colorSpace;
|
||
|
|
} else {
|
||
|
|
texture.encoding = colorSpaceEncodingMap[colorSpace];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/GLTFMToonMaterialParamsAssignHelper.ts
|
||
|
|
var GLTFMToonMaterialParamsAssignHelper = class {
|
||
|
|
get pending() {
|
||
|
|
return Promise.all(this._pendings);
|
||
|
|
}
|
||
|
|
constructor(parser, materialParams) {
|
||
|
|
this._parser = parser;
|
||
|
|
this._materialParams = materialParams;
|
||
|
|
this._pendings = [];
|
||
|
|
}
|
||
|
|
assignPrimitive(key, value) {
|
||
|
|
if (value != null) {
|
||
|
|
this._materialParams[key] = value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assignColor(key, value, convertSRGBToLinear) {
|
||
|
|
if (value != null) {
|
||
|
|
this._materialParams[key] = new THREE2.Color().fromArray(value);
|
||
|
|
if (convertSRGBToLinear) {
|
||
|
|
this._materialParams[key].convertSRGBToLinear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assignTexture(key, texture, isColorTexture) {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
const promise = (() => __async(this, null, function* () {
|
||
|
|
if (texture != null) {
|
||
|
|
yield this._parser.assignTexture(this._materialParams, key, texture);
|
||
|
|
if (isColorTexture) {
|
||
|
|
setTextureColorSpace(this._materialParams[key], "srgb");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}))();
|
||
|
|
this._pendings.push(promise);
|
||
|
|
return promise;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
assignTextureByIndex(key, textureIndex, isColorTexture) {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
return this.assignTexture(key, textureIndex != null ? { index: textureIndex } : void 0, isColorTexture);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/MToonMaterial.ts
|
||
|
|
import * as THREE4 from "three";
|
||
|
|
|
||
|
|
// src/shaders/mtoon.vert
|
||
|
|
var mtoon_default = "// #define PHONG\n\nvarying vec3 vViewPosition;\n\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n\n#include <common>\n\n// #include <uv_pars_vertex>\n#ifdef MTOON_USE_UV\n varying vec2 vUv;\n\n // COMPAT: pre-r151 uses a common uvTransform\n #if THREE_VRM_THREE_REVISION < 151\n uniform mat3 uvTransform;\n #endif\n#endif\n\n// #include <uv2_pars_vertex>\n// COMAPT: pre-r151 uses uv2 for lightMap and aoMap\n#if THREE_VRM_THREE_REVISION < 151\n #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n attribute vec2 uv2;\n varying vec2 vUv2;\n uniform mat3 uv2Transform;\n #endif\n#endif\n\n// #include <displacementmap_pars_vertex>\n// #include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_OUTLINEWIDTHMULTIPLYTEXTURE\n uniform sampler2D outlineWidthMultiplyTexture;\n uniform mat3 outlineWidthMultiplyTextureUvTransform;\n#endif\n\nuniform float outlineWidthFactor;\n\nvoid main() {\n\n // #include <uv_vertex>\n #ifdef MTOON_USE_UV\n // COMPAT: pre-r151 uses a common uvTransform\n #if THREE_VRM_THREE_REVISION >= 151\n vUv = uv;\n #else\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n #endif\n #endif\n\n // #include <uv2_vertex>\n // COMAPT: pre-r151 uses uv2 for lightMap and aoMap\n #if THREE_VRM_THREE_REVISION < 151\n #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n #endif\n #endif\n\n #include <color_vertex>\n\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n\n // we need this to compute the outline properly\n objectNormal = normalize( objectNormal );\n\n #include <defaultnormal_vertex>\n\n #ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED\n vNormal = normalize( transformedNormal );\n #endif\n\n #include <begin_vertex>\n\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n // #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n\n vViewPosition = - mvPosition.xyz;\n\n #ifdef OUTLINE\n float worldNormalLength = length( transformedNormal );\n vec3 outlineOffset = outlineWidthFactor * worldNormalLength * objectNormal;\n\n #ifdef USE_OUTLINEWIDTHMULTIPLYTEXTURE\n vec2 outlineWidthMultiplyTextureUv = ( outlineWidthMultiplyTextureUvTransform * vec3( vUv, 1 ) ).xy;\n float outlineTex = texture2D( outlineWidthMultiplyTexture, outlineWidthMultiplyTextureUv ).g;\n outlineOffset *= outlineTex;\n #endif\n\n #ifdef OUTLINE_WIDTH_SCREEN\n outlineOffset *= vViewPosition.z / projectionMatrix[ 1 ].y;\n #endif\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4( outlineOffset + transformed, 1.0 );\n\n gl_Position.z += 1E-6 * gl_Position.w; // anti-artifact magic\n #endif\n\n #include <worldpos_vertex>\n // #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n\n}";
|
||
|
|
|
||
|
|
// src/shaders/mtoon.frag
|
||
|
|
var mtoon_default2 = "// #define PHONG\n\nuniform vec3 litFactor;\n\nuniform float opacity;\n\nuniform vec3 shadeColorFactor;\n#ifdef USE_SHADEMULTIPLYTEXTURE\n uniform sampler2D shadeMultiplyTexture;\n uniform mat3 shadeMultiplyTextureUvTransform;\n#endif\n\nuniform float shadingShiftFactor;\nuniform float shadingToonyFactor;\n\n#ifdef USE_SHADINGSHIFTTEXTURE\n uniform sampler2D shadingShiftTexture;\n uniform mat3 shadingShiftTextureUvTransform;\n uniform float shadingShiftTextureScale;\n#endif\n\nuniform float giEqualizationFactor;\n\nuniform vec3 parametricRimColorFactor;\n#ifdef USE_RIMMULTIPLYTEXTURE\n uniform sampler2D rimMultiplyTexture;\n uniform mat3 rimMultiplyTextureUvTransform;\n#endif\nuniform float rimLightingMixFactor;\nuniform float parametricRimFresnelPowerFactor;\nuniform float parametricRimLiftFactor;\n\n#ifdef USE_MATCAPTEXTURE\n uniform vec3 matcapFactor;\n uniform sampler2D matcapTexture;\n uniform mat3 matcapTextureUvTransform;\n#endif\n\nuniform vec3 emissive;\nuniform float emissiveIntensity;\n\nuniform vec3 outlineColorFactor;\nuniform float outlineLightingMixFactor;\n\n#ifdef USE_UVANIMATIONMASKTEXTURE\n uniform sampler2D uvAnimationMaskTexture;\n uniform mat3 uvAnimationMaskTextureUvTransform;\n#endif\n\nuniform float uvAnimationScrollXOffset;\nuniform float uvAnimationScrollYOffset;\nuniform float uvAnimationRotationPhase;\n\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n\n// #include <uv_pars_fragment>\n#if ( defined( MTOON_USE_UV ) && !defined( MTOON_UVS_VERTEX_ONLY ) )\n varying vec2 vUv;\n#endif\n\n// #include <uv2_pars_fragment>\n// COMAPT: pre-r151 uses uv2 for lightMap and aoMap\n#if THREE_VRM_THREE_REVISION < 151\n #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n varying vec2 vUv2;\n #endif\n#endif\n\n#include <map_pars_fragment>\n\n#ifdef USE_MAP\n uniform mat3 mapUvTransform;\n#endif\n\n// #include <alphamap_pars_fragment>\n\n#include <alphatest_pars_fragment>\n\n#include <aomap_pars_fragment>\n// #include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n\n#ifdef USE_EMISSIVEMAP\n uniform mat3 emissiveMapUvTransform;\n#endif\n\n// #include <envmap_common_pars_fragment>\n// #include <envmap_pars_fragment>\n// #include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n\n// #include <bsdfs>\n// COMPAT: pre-r151 doesn't have BRDF_Lambert in <common>\n#if THREE_VRM_THREE_REVISION < 151\n vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n return RECIPROCAL_PI * diffuseColor;\n }\n#endif\n\n#include <lights_pars_begin>\n\n#include <normal_pars_fragment>\n\n// #include <lights_phong_pars_fragment>\nvarying vec3 vViewPosition;\n\nstruct MToonMaterial {\n vec3 diffuseColor;\n vec3 shadeColor;\n float shadingShift;\n};\n\nfloat linearstep( float a, float b, float t ) {\n return clamp( ( t - a ) / ( b - a ), 0.0, 1.0 );\n}\n\n/**\n * Convert NdotL into toon shading factor using shadingShift and shadingToony\n */\nfloat getShading(\n const in float dotNL,\n const in float shadow,\n const in float shadingShift\n) {\n float shading = dotNL;\n shading = shading + shadingShift;\n shading = linearstep( -1.0 + shadingToonyFactor, 1.0 - shadingToonyFactor, shading );\n shading *= shadow;\n return shading;\n}\n\n/**\n * Mix diffuseColor and shadeColor using shading factor and light color\n */\nvec3 getDiffuse(\n const in MToonMaterial material,\n const in float shading,\n in vec3 lightColor\n) {\n #ifdef DEBUG_LITSHADERATE\n return vec3( BRDF_Lambert( shading * lightColor ) );\n #endif\n\n vec3 col = lightColor * BRDF_Lambert( mix( material.shadeColor, material.diffuseColor, shading ) );\n\n // The \"comment out if you want to PBR absolutely\" line\n #ifdef V0_COMPAT_SHADE\n col = min( col, material.diffuseColor );\n #endif\n\n return col;\n}\n\n// COMPAT: pre-r156 uses a struct GeometricContext\n#if THREE_VRM_THREE_REVISION >= 157\n void RE_Direct_MToon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const
|
||
|
|
|
||
|
|
// src/MToonMaterialDebugMode.ts
|
||
|
|
var MToonMaterialDebugMode = {
|
||
|
|
/**
|
||
|
|
* Render normally.
|
||
|
|
*/
|
||
|
|
None: "none",
|
||
|
|
/**
|
||
|
|
* Visualize normals of the surface.
|
||
|
|
*/
|
||
|
|
Normal: "normal",
|
||
|
|
/**
|
||
|
|
* Visualize lit/shade of the surface.
|
||
|
|
*/
|
||
|
|
LitShadeRate: "litShadeRate",
|
||
|
|
/**
|
||
|
|
* Visualize UV of the surface.
|
||
|
|
*/
|
||
|
|
UV: "uv"
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/MToonMaterialOutlineWidthMode.ts
|
||
|
|
var MToonMaterialOutlineWidthMode = {
|
||
|
|
None: "none",
|
||
|
|
WorldCoordinates: "worldCoordinates",
|
||
|
|
ScreenCoordinates: "screenCoordinates"
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/utils/getTextureColorSpace.ts
|
||
|
|
import * as THREE3 from "three";
|
||
|
|
var encodingColorSpaceMap = {
|
||
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||
|
|
3e3: "",
|
||
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||
|
|
3001: "srgb"
|
||
|
|
};
|
||
|
|
function getTextureColorSpace(texture) {
|
||
|
|
if (parseInt(THREE3.REVISION, 10) >= 152) {
|
||
|
|
return texture.colorSpace;
|
||
|
|
} else {
|
||
|
|
return encodingColorSpaceMap[texture.encoding];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/MToonMaterial.ts
|
||
|
|
var MToonMaterial = class extends THREE4.ShaderMaterial {
|
||
|
|
constructor(parameters = {}) {
|
||
|
|
var _a;
|
||
|
|
super({ vertexShader: mtoon_default, fragmentShader: mtoon_default2 });
|
||
|
|
this.uvAnimationScrollXSpeedFactor = 0;
|
||
|
|
this.uvAnimationScrollYSpeedFactor = 0;
|
||
|
|
this.uvAnimationRotationSpeedFactor = 0;
|
||
|
|
/**
|
||
|
|
* Whether the material is affected by fog.
|
||
|
|
* `true` by default.
|
||
|
|
*/
|
||
|
|
this.fog = true;
|
||
|
|
/**
|
||
|
|
* Will be read in WebGLPrograms
|
||
|
|
*
|
||
|
|
* See: https://github.com/mrdoob/three.js/blob/4f5236ac3d6f41d904aa58401b40554e8fbdcb15/src/renderers/webgl/WebGLPrograms.js#L190-L191
|
||
|
|
*/
|
||
|
|
this.normalMapType = THREE4.TangentSpaceNormalMap;
|
||
|
|
/**
|
||
|
|
* When this is `true`, vertex colors will be ignored.
|
||
|
|
* `true` by default.
|
||
|
|
*/
|
||
|
|
this._ignoreVertexColor = true;
|
||
|
|
this._v0CompatShade = false;
|
||
|
|
this._debugMode = MToonMaterialDebugMode.None;
|
||
|
|
this._outlineWidthMode = MToonMaterialOutlineWidthMode.None;
|
||
|
|
this._isOutline = false;
|
||
|
|
if (parameters.transparentWithZWrite) {
|
||
|
|
parameters.depthWrite = true;
|
||
|
|
}
|
||
|
|
delete parameters.transparentWithZWrite;
|
||
|
|
parameters.fog = true;
|
||
|
|
parameters.lights = true;
|
||
|
|
parameters.clipping = true;
|
||
|
|
this.uniforms = THREE4.UniformsUtils.merge([
|
||
|
|
THREE4.UniformsLib.common,
|
||
|
|
// map
|
||
|
|
THREE4.UniformsLib.normalmap,
|
||
|
|
// normalMap
|
||
|
|
THREE4.UniformsLib.emissivemap,
|
||
|
|
// emissiveMap
|
||
|
|
THREE4.UniformsLib.fog,
|
||
|
|
THREE4.UniformsLib.lights,
|
||
|
|
{
|
||
|
|
litFactor: { value: new THREE4.Color(1, 1, 1) },
|
||
|
|
mapUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
colorAlpha: { value: 1 },
|
||
|
|
normalMapUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
shadeColorFactor: { value: new THREE4.Color(0, 0, 0) },
|
||
|
|
shadeMultiplyTexture: { value: null },
|
||
|
|
shadeMultiplyTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
shadingShiftFactor: { value: 0 },
|
||
|
|
shadingShiftTexture: { value: null },
|
||
|
|
shadingShiftTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
shadingShiftTextureScale: { value: 1 },
|
||
|
|
shadingToonyFactor: { value: 0.9 },
|
||
|
|
giEqualizationFactor: { value: 0.9 },
|
||
|
|
matcapFactor: { value: new THREE4.Color(1, 1, 1) },
|
||
|
|
matcapTexture: { value: null },
|
||
|
|
matcapTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
parametricRimColorFactor: { value: new THREE4.Color(0, 0, 0) },
|
||
|
|
rimMultiplyTexture: { value: null },
|
||
|
|
rimMultiplyTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
rimLightingMixFactor: { value: 1 },
|
||
|
|
parametricRimFresnelPowerFactor: { value: 5 },
|
||
|
|
parametricRimLiftFactor: { value: 0 },
|
||
|
|
emissive: { value: new THREE4.Color(0, 0, 0) },
|
||
|
|
emissiveIntensity: { value: 1 },
|
||
|
|
emissiveMapUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
outlineWidthMultiplyTexture: { value: null },
|
||
|
|
outlineWidthMultiplyTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
outlineWidthFactor: { value: 0 },
|
||
|
|
outlineColorFactor: { value: new THREE4.Color(0, 0, 0) },
|
||
|
|
outlineLightingMixFactor: { value: 1 },
|
||
|
|
uvAnimationMaskTexture: { value: null },
|
||
|
|
uvAnimationMaskTextureUvTransform: { value: new THREE4.Matrix3() },
|
||
|
|
uvAnimationScrollXOffset: { value: 0 },
|
||
|
|
uvAnimationScrollYOffset: { value: 0 },
|
||
|
|
uvAnimationRotationPhase: { value: 0 }
|
||
|
|
},
|
||
|
|
(_a = parameters.uniforms) != null ? _a : {}
|
||
|
|
]);
|
||
|
|
this.setValues(parameters);
|
||
|
|
this._uploadUniformsWorkaround();
|
||
|
|
this.customProgramCacheKey = () => [
|
||
|
|
...Object.entries(this._generateDefines()).map(([token, macro]) => `${token}:${macro}`),
|
||
|
|
this.matcapTexture ? `matcapTextureColorSpace:${getTextureColorSpace(this.matcapTexture)}` : "",
|
||
|
|
this.shadeMultiplyTexture ? `shadeMultiplyTextureColorSpace:${getTextureColorSpace(this.shadeMultiplyTexture)}` : "",
|
||
|
|
this.rimMultiplyTexture ? `rimMultiplyTextureColorSpace:${getTextureColorSpace(this.rimMultiplyTexture)}` : ""
|
||
|
|
].join(",");
|
||
|
|
this.onBeforeCompile = (shader) => {
|
||
|
|
const threeRevision = parseInt(THREE4.REVISION, 10);
|
||
|
|
const defines = Object.entries(__spreadValues(__spreadValues({}, this._generateDefines()), this.defines)).filter(([token, macro]) => !!macro).map(([token, macro]) => `#define ${token} ${macro}`).join("\n") + "\n";
|
||
|
|
shader.vertexShader = defines + shader.vertexShader;
|
||
|
|
shader.fragmentShader = defines + shader.fragmentShader;
|
||
|
|
if (threeRevision < 154) {
|
||
|
|
shader.fragmentShader = shader.fragmentShader.replace(
|
||
|
|
"#include <colorspace_fragment>",
|
||
|
|
"#include <encodings_fragment>"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
get color() {
|
||
|
|
return this.uniforms.litFactor.value;
|
||
|
|
}
|
||
|
|
set color(value) {
|
||
|
|
this.uniforms.litFactor.value = value;
|
||
|
|
}
|
||
|
|
get map() {
|
||
|
|
return this.uniforms.map.value;
|
||
|
|
}
|
||
|
|
set map(value) {
|
||
|
|
this.uniforms.map.value = value;
|
||
|
|
}
|
||
|
|
get normalMap() {
|
||
|
|
return this.uniforms.normalMap.value;
|
||
|
|
}
|
||
|
|
set normalMap(value) {
|
||
|
|
this.uniforms.normalMap.value = value;
|
||
|
|
}
|
||
|
|
get normalScale() {
|
||
|
|
return this.uniforms.normalScale.value;
|
||
|
|
}
|
||
|
|
set normalScale(value) {
|
||
|
|
this.uniforms.normalScale.value = value;
|
||
|
|
}
|
||
|
|
get emissive() {
|
||
|
|
return this.uniforms.emissive.value;
|
||
|
|
}
|
||
|
|
set emissive(value) {
|
||
|
|
this.uniforms.emissive.value = value;
|
||
|
|
}
|
||
|
|
get emissiveIntensity() {
|
||
|
|
return this.uniforms.emissiveIntensity.value;
|
||
|
|
}
|
||
|
|
set emissiveIntensity(value) {
|
||
|
|
this.uniforms.emissiveIntensity.value = value;
|
||
|
|
}
|
||
|
|
get emissiveMap() {
|
||
|
|
return this.uniforms.emissiveMap.value;
|
||
|
|
}
|
||
|
|
set emissiveMap(value) {
|
||
|
|
this.uniforms.emissiveMap.value = value;
|
||
|
|
}
|
||
|
|
get shadeColorFactor() {
|
||
|
|
return this.uniforms.shadeColorFactor.value;
|
||
|
|
}
|
||
|
|
set shadeColorFactor(value) {
|
||
|
|
this.uniforms.shadeColorFactor.value = value;
|
||
|
|
}
|
||
|
|
get shadeMultiplyTexture() {
|
||
|
|
return this.uniforms.shadeMultiplyTexture.value;
|
||
|
|
}
|
||
|
|
set shadeMultiplyTexture(value) {
|
||
|
|
this.uniforms.shadeMultiplyTexture.value = value;
|
||
|
|
}
|
||
|
|
get shadingShiftFactor() {
|
||
|
|
return this.uniforms.shadingShiftFactor.value;
|
||
|
|
}
|
||
|
|
set shadingShiftFactor(value) {
|
||
|
|
this.uniforms.shadingShiftFactor.value = value;
|
||
|
|
}
|
||
|
|
get shadingShiftTexture() {
|
||
|
|
return this.uniforms.shadingShiftTexture.value;
|
||
|
|
}
|
||
|
|
set shadingShiftTexture(value) {
|
||
|
|
this.uniforms.shadingShiftTexture.value = value;
|
||
|
|
}
|
||
|
|
get shadingShiftTextureScale() {
|
||
|
|
return this.uniforms.shadingShiftTextureScale.value;
|
||
|
|
}
|
||
|
|
set shadingShiftTextureScale(value) {
|
||
|
|
this.uniforms.shadingShiftTextureScale.value = value;
|
||
|
|
}
|
||
|
|
get shadingToonyFactor() {
|
||
|
|
return this.uniforms.shadingToonyFactor.value;
|
||
|
|
}
|
||
|
|
set shadingToonyFactor(value) {
|
||
|
|
this.uniforms.shadingToonyFactor.value = value;
|
||
|
|
}
|
||
|
|
get giEqualizationFactor() {
|
||
|
|
return this.uniforms.giEqualizationFactor.value;
|
||
|
|
}
|
||
|
|
set giEqualizationFactor(value) {
|
||
|
|
this.uniforms.giEqualizationFactor.value = value;
|
||
|
|
}
|
||
|
|
get matcapFactor() {
|
||
|
|
return this.uniforms.matcapFactor.value;
|
||
|
|
}
|
||
|
|
set matcapFactor(value) {
|
||
|
|
this.uniforms.matcapFactor.value = value;
|
||
|
|
}
|
||
|
|
get matcapTexture() {
|
||
|
|
return this.uniforms.matcapTexture.value;
|
||
|
|
}
|
||
|
|
set matcapTexture(value) {
|
||
|
|
this.uniforms.matcapTexture.value = value;
|
||
|
|
}
|
||
|
|
get parametricRimColorFactor() {
|
||
|
|
return this.uniforms.parametricRimColorFactor.value;
|
||
|
|
}
|
||
|
|
set parametricRimColorFactor(value) {
|
||
|
|
this.uniforms.parametricRimColorFactor.value = value;
|
||
|
|
}
|
||
|
|
get rimMultiplyTexture() {
|
||
|
|
return this.uniforms.rimMultiplyTexture.value;
|
||
|
|
}
|
||
|
|
set rimMultiplyTexture(value) {
|
||
|
|
this.uniforms.rimMultiplyTexture.value = value;
|
||
|
|
}
|
||
|
|
get rimLightingMixFactor() {
|
||
|
|
return this.uniforms.rimLightingMixFactor.value;
|
||
|
|
}
|
||
|
|
set rimLightingMixFactor(value) {
|
||
|
|
this.uniforms.rimLightingMixFactor.value = value;
|
||
|
|
}
|
||
|
|
get parametricRimFresnelPowerFactor() {
|
||
|
|
return this.uniforms.parametricRimFresnelPowerFactor.value;
|
||
|
|
}
|
||
|
|
set parametricRimFresnelPowerFactor(value) {
|
||
|
|
this.uniforms.parametricRimFresnelPowerFactor.value = value;
|
||
|
|
}
|
||
|
|
get parametricRimLiftFactor() {
|
||
|
|
return this.uniforms.parametricRimLiftFactor.value;
|
||
|
|
}
|
||
|
|
set parametricRimLiftFactor(value) {
|
||
|
|
this.uniforms.parametricRimLiftFactor.value = value;
|
||
|
|
}
|
||
|
|
get outlineWidthMultiplyTexture() {
|
||
|
|
return this.uniforms.outlineWidthMultiplyTexture.value;
|
||
|
|
}
|
||
|
|
set outlineWidthMultiplyTexture(value) {
|
||
|
|
this.uniforms.outlineWidthMultiplyTexture.value = value;
|
||
|
|
}
|
||
|
|
get outlineWidthFactor() {
|
||
|
|
return this.uniforms.outlineWidthFactor.value;
|
||
|
|
}
|
||
|
|
set outlineWidthFactor(value) {
|
||
|
|
this.uniforms.outlineWidthFactor.value = value;
|
||
|
|
}
|
||
|
|
get outlineColorFactor() {
|
||
|
|
return this.uniforms.outlineColorFactor.value;
|
||
|
|
}
|
||
|
|
set outlineColorFactor(value) {
|
||
|
|
this.uniforms.outlineColorFactor.value = value;
|
||
|
|
}
|
||
|
|
get outlineLightingMixFactor() {
|
||
|
|
return this.uniforms.outlineLightingMixFactor.value;
|
||
|
|
}
|
||
|
|
set outlineLightingMixFactor(value) {
|
||
|
|
this.uniforms.outlineLightingMixFactor.value = value;
|
||
|
|
}
|
||
|
|
get uvAnimationMaskTexture() {
|
||
|
|
return this.uniforms.uvAnimationMaskTexture.value;
|
||
|
|
}
|
||
|
|
set uvAnimationMaskTexture(value) {
|
||
|
|
this.uniforms.uvAnimationMaskTexture.value = value;
|
||
|
|
}
|
||
|
|
get uvAnimationScrollXOffset() {
|
||
|
|
return this.uniforms.uvAnimationScrollXOffset.value;
|
||
|
|
}
|
||
|
|
set uvAnimationScrollXOffset(value) {
|
||
|
|
this.uniforms.uvAnimationScrollXOffset.value = value;
|
||
|
|
}
|
||
|
|
get uvAnimationScrollYOffset() {
|
||
|
|
return this.uniforms.uvAnimationScrollYOffset.value;
|
||
|
|
}
|
||
|
|
set uvAnimationScrollYOffset(value) {
|
||
|
|
this.uniforms.uvAnimationScrollYOffset.value = value;
|
||
|
|
}
|
||
|
|
get uvAnimationRotationPhase() {
|
||
|
|
return this.uniforms.uvAnimationRotationPhase.value;
|
||
|
|
}
|
||
|
|
set uvAnimationRotationPhase(value) {
|
||
|
|
this.uniforms.uvAnimationRotationPhase.value = value;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* When this is `true`, vertex colors will be ignored.
|
||
|
|
* `true` by default.
|
||
|
|
*/
|
||
|
|
get ignoreVertexColor() {
|
||
|
|
return this._ignoreVertexColor;
|
||
|
|
}
|
||
|
|
set ignoreVertexColor(value) {
|
||
|
|
this._ignoreVertexColor = value;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* There is a line of the shader called "comment out if you want to PBR absolutely" in VRM0.0 MToon.
|
||
|
|
* When this is true, the material enables the line to make it compatible with the legacy rendering of VRM.
|
||
|
|
* Usually not recommended to turn this on.
|
||
|
|
* `false` by default.
|
||
|
|
*/
|
||
|
|
get v0CompatShade() {
|
||
|
|
return this._v0CompatShade;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* There is a line of the shader called "comment out if you want to PBR absolutely" in VRM0.0 MToon.
|
||
|
|
* When this is true, the material enables the line to make it compatible with the legacy rendering of VRM.
|
||
|
|
* Usually not recommended to turn this on.
|
||
|
|
* `false` by default.
|
||
|
|
*/
|
||
|
|
set v0CompatShade(v) {
|
||
|
|
this._v0CompatShade = v;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Debug mode for the material.
|
||
|
|
* You can visualize several components for diagnosis using debug mode.
|
||
|
|
*
|
||
|
|
* See: {@link MToonMaterialDebugMode}
|
||
|
|
*/
|
||
|
|
get debugMode() {
|
||
|
|
return this._debugMode;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Debug mode for the material.
|
||
|
|
* You can visualize several components for diagnosis using debug mode.
|
||
|
|
*
|
||
|
|
* See: {@link MToonMaterialDebugMode}
|
||
|
|
*/
|
||
|
|
set debugMode(m) {
|
||
|
|
this._debugMode = m;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
}
|
||
|
|
get outlineWidthMode() {
|
||
|
|
return this._outlineWidthMode;
|
||
|
|
}
|
||
|
|
set outlineWidthMode(m) {
|
||
|
|
this._outlineWidthMode = m;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
}
|
||
|
|
get isOutline() {
|
||
|
|
return this._isOutline;
|
||
|
|
}
|
||
|
|
set isOutline(b) {
|
||
|
|
this._isOutline = b;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Readonly boolean that indicates this is a {@link MToonMaterial}.
|
||
|
|
*/
|
||
|
|
get isMToonMaterial() {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Update this material.
|
||
|
|
*
|
||
|
|
* @param delta deltaTime since last update
|
||
|
|
*/
|
||
|
|
update(delta) {
|
||
|
|
this._uploadUniformsWorkaround();
|
||
|
|
this._updateUVAnimation(delta);
|
||
|
|
}
|
||
|
|
copy(source) {
|
||
|
|
super.copy(source);
|
||
|
|
this.map = source.map;
|
||
|
|
this.normalMap = source.normalMap;
|
||
|
|
this.emissiveMap = source.emissiveMap;
|
||
|
|
this.shadeMultiplyTexture = source.shadeMultiplyTexture;
|
||
|
|
this.shadingShiftTexture = source.shadingShiftTexture;
|
||
|
|
this.matcapTexture = source.matcapTexture;
|
||
|
|
this.rimMultiplyTexture = source.rimMultiplyTexture;
|
||
|
|
this.outlineWidthMultiplyTexture = source.outlineWidthMultiplyTexture;
|
||
|
|
this.uvAnimationMaskTexture = source.uvAnimationMaskTexture;
|
||
|
|
this.normalMapType = source.normalMapType;
|
||
|
|
this.uvAnimationScrollXSpeedFactor = source.uvAnimationScrollXSpeedFactor;
|
||
|
|
this.uvAnimationScrollYSpeedFactor = source.uvAnimationScrollYSpeedFactor;
|
||
|
|
this.uvAnimationRotationSpeedFactor = source.uvAnimationRotationSpeedFactor;
|
||
|
|
this.ignoreVertexColor = source.ignoreVertexColor;
|
||
|
|
this.v0CompatShade = source.v0CompatShade;
|
||
|
|
this.debugMode = source.debugMode;
|
||
|
|
this.outlineWidthMode = source.outlineWidthMode;
|
||
|
|
this.isOutline = source.isOutline;
|
||
|
|
this.needsUpdate = true;
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Update UV animation state.
|
||
|
|
* Intended to be called via {@link update}.
|
||
|
|
* @param delta deltaTime
|
||
|
|
*/
|
||
|
|
_updateUVAnimation(delta) {
|
||
|
|
this.uniforms.uvAnimationScrollXOffset.value += delta * this.uvAnimationScrollXSpeedFactor;
|
||
|
|
this.uniforms.uvAnimationScrollYOffset.value += delta * this.uvAnimationScrollYSpeedFactor;
|
||
|
|
this.uniforms.uvAnimationRotationPhase.value += delta * this.uvAnimationRotationSpeedFactor;
|
||
|
|
this.uniforms.alphaTest.value = this.alphaTest;
|
||
|
|
this.uniformsNeedUpdate = true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Upload uniforms that need to upload but doesn't automatically because of reasons.
|
||
|
|
* Intended to be called via {@link constructor} and {@link update}.
|
||
|
|
*/
|
||
|
|
_uploadUniformsWorkaround() {
|
||
|
|
this.uniforms.opacity.value = this.opacity;
|
||
|
|
this._updateTextureMatrix(this.uniforms.map, this.uniforms.mapUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.normalMap, this.uniforms.normalMapUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.emissiveMap, this.uniforms.emissiveMapUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.shadeMultiplyTexture, this.uniforms.shadeMultiplyTextureUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.shadingShiftTexture, this.uniforms.shadingShiftTextureUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.matcapTexture, this.uniforms.matcapTextureUvTransform);
|
||
|
|
this._updateTextureMatrix(this.uniforms.rimMultiplyTexture, this.uniforms.rimMultiplyTextureUvTransform);
|
||
|
|
this._updateTextureMatrix(
|
||
|
|
this.uniforms.outlineWidthMultiplyTexture,
|
||
|
|
this.uniforms.outlineWidthMultiplyTextureUvTransform
|
||
|
|
);
|
||
|
|
this._updateTextureMatrix(this.uniforms.uvAnimationMaskTexture, this.uniforms.uvAnimationMaskTextureUvTransform);
|
||
|
|
this.uniformsNeedUpdate = true;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Returns a map object of preprocessor token and macro of the shader program.
|
||
|
|
*/
|
||
|
|
_generateDefines() {
|
||
|
|
const threeRevision = parseInt(THREE4.REVISION, 10);
|
||
|
|
const useUvInVert = this.outlineWidthMultiplyTexture !== null;
|
||
|
|
const useUvInFrag = this.map !== null || this.normalMap !== null || this.emissiveMap !== null || this.shadeMultiplyTexture !== null || this.shadingShiftTexture !== null || this.rimMultiplyTexture !== null || this.uvAnimationMaskTexture !== null;
|
||
|
|
return {
|
||
|
|
// Temporary compat against shader change @ Three.js r126
|
||
|
|
// See: #21205, #21307, #21299
|
||
|
|
THREE_VRM_THREE_REVISION: threeRevision,
|
||
|
|
OUTLINE: this._isOutline,
|
||
|
|
MTOON_USE_UV: useUvInVert || useUvInFrag,
|
||
|
|
// we can't use `USE_UV` , it will be redefined in WebGLProgram.js
|
||
|
|
MTOON_UVS_VERTEX_ONLY: useUvInVert && !useUvInFrag,
|
||
|
|
V0_COMPAT_SHADE: this._v0CompatShade,
|
||
|
|
USE_SHADEMULTIPLYTEXTURE: this.shadeMultiplyTexture !== null,
|
||
|
|
USE_SHADINGSHIFTTEXTURE: this.shadingShiftTexture !== null,
|
||
|
|
USE_MATCAPTEXTURE: this.matcapTexture !== null,
|
||
|
|
USE_RIMMULTIPLYTEXTURE: this.rimMultiplyTexture !== null,
|
||
|
|
USE_OUTLINEWIDTHMULTIPLYTEXTURE: this._isOutline && this.outlineWidthMultiplyTexture !== null,
|
||
|
|
USE_UVANIMATIONMASKTEXTURE: this.uvAnimationMaskTexture !== null,
|
||
|
|
IGNORE_VERTEX_COLOR: this._ignoreVertexColor === true,
|
||
|
|
DEBUG_NORMAL: this._debugMode === "normal",
|
||
|
|
DEBUG_LITSHADERATE: this._debugMode === "litShadeRate",
|
||
|
|
DEBUG_UV: this._debugMode === "uv",
|
||
|
|
OUTLINE_WIDTH_SCREEN: this._isOutline && this._outlineWidthMode === MToonMaterialOutlineWidthMode.ScreenCoordinates
|
||
|
|
};
|
||
|
|
}
|
||
|
|
_updateTextureMatrix(src, dst) {
|
||
|
|
if (src.value) {
|
||
|
|
if (src.value.matrixAutoUpdate) {
|
||
|
|
src.value.updateMatrix();
|
||
|
|
}
|
||
|
|
dst.value.copy(src.value.matrix);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/MToonMaterialLoaderPlugin.ts
|
||
|
|
var POSSIBLE_SPEC_VERSIONS = /* @__PURE__ */ new Set(["1.0", "1.0-beta"]);
|
||
|
|
var _MToonMaterialLoaderPlugin = class _MToonMaterialLoaderPlugin {
|
||
|
|
get name() {
|
||
|
|
return _MToonMaterialLoaderPlugin.EXTENSION_NAME;
|
||
|
|
}
|
||
|
|
constructor(parser, options = {}) {
|
||
|
|
var _a, _b, _c, _d;
|
||
|
|
this.parser = parser;
|
||
|
|
this.materialType = (_a = options.materialType) != null ? _a : MToonMaterial;
|
||
|
|
this.renderOrderOffset = (_b = options.renderOrderOffset) != null ? _b : 0;
|
||
|
|
this.v0CompatShade = (_c = options.v0CompatShade) != null ? _c : false;
|
||
|
|
this.debugMode = (_d = options.debugMode) != null ? _d : "none";
|
||
|
|
this._mToonMaterialSet = /* @__PURE__ */ new Set();
|
||
|
|
}
|
||
|
|
beforeRoot() {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
this._removeUnlitExtensionIfMToonExists();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
afterRoot(gltf) {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
gltf.userData.vrmMToonMaterials = Array.from(this._mToonMaterialSet);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
getMaterialType(materialIndex) {
|
||
|
|
const v1Extension = this._getMToonExtension(materialIndex);
|
||
|
|
if (v1Extension) {
|
||
|
|
return this.materialType;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
extendMaterialParams(materialIndex, materialParams) {
|
||
|
|
const extension = this._getMToonExtension(materialIndex);
|
||
|
|
if (extension) {
|
||
|
|
return this._extendMaterialParams(extension, materialParams);
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
loadMesh(meshIndex) {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
var _a;
|
||
|
|
const parser = this.parser;
|
||
|
|
const json = parser.json;
|
||
|
|
const meshDef = (_a = json.meshes) == null ? void 0 : _a[meshIndex];
|
||
|
|
if (meshDef == null) {
|
||
|
|
throw new Error(
|
||
|
|
`MToonMaterialLoaderPlugin: Attempt to use meshes[${meshIndex}] of glTF but the mesh doesn't exist`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
const primitivesDef = meshDef.primitives;
|
||
|
|
const meshOrGroup = yield parser.loadMesh(meshIndex);
|
||
|
|
if (primitivesDef.length === 1) {
|
||
|
|
const mesh = meshOrGroup;
|
||
|
|
const materialIndex = primitivesDef[0].material;
|
||
|
|
if (materialIndex != null) {
|
||
|
|
this._setupPrimitive(mesh, materialIndex);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
const group = meshOrGroup;
|
||
|
|
for (let i = 0; i < primitivesDef.length; i++) {
|
||
|
|
const mesh = group.children[i];
|
||
|
|
const materialIndex = primitivesDef[i].material;
|
||
|
|
if (materialIndex != null) {
|
||
|
|
this._setupPrimitive(mesh, materialIndex);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return meshOrGroup;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Delete use of `KHR_materials_unlit` from its `materials` if the material is using MToon.
|
||
|
|
*
|
||
|
|
* Since GLTFLoader have so many hardcoded procedure related to `KHR_materials_unlit`
|
||
|
|
* we have to delete the extension before we start to parse the glTF.
|
||
|
|
*/
|
||
|
|
_removeUnlitExtensionIfMToonExists() {
|
||
|
|
const parser = this.parser;
|
||
|
|
const json = parser.json;
|
||
|
|
const materialDefs = json.materials;
|
||
|
|
materialDefs == null ? void 0 : materialDefs.map((materialDef, iMaterial) => {
|
||
|
|
var _a;
|
||
|
|
const extension = this._getMToonExtension(iMaterial);
|
||
|
|
if (extension && ((_a = materialDef.extensions) == null ? void 0 : _a["KHR_materials_unlit"])) {
|
||
|
|
delete materialDef.extensions["KHR_materials_unlit"];
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
_getMToonExtension(materialIndex) {
|
||
|
|
var _a, _b;
|
||
|
|
const parser = this.parser;
|
||
|
|
const json = parser.json;
|
||
|
|
const materialDef = (_a = json.materials) == null ? void 0 : _a[materialIndex];
|
||
|
|
if (materialDef == null) {
|
||
|
|
console.warn(
|
||
|
|
`MToonMaterialLoaderPlugin: Attempt to use materials[${materialIndex}] of glTF but the material doesn't exist`
|
||
|
|
);
|
||
|
|
return void 0;
|
||
|
|
}
|
||
|
|
const extension = (_b = materialDef.extensions) == null ? void 0 : _b[_MToonMaterialLoaderPlugin.EXTENSION_NAME];
|
||
|
|
if (extension == null) {
|
||
|
|
return void 0;
|
||
|
|
}
|
||
|
|
const specVersion = extension.specVersion;
|
||
|
|
if (!POSSIBLE_SPEC_VERSIONS.has(specVersion)) {
|
||
|
|
console.warn(
|
||
|
|
`MToonMaterialLoaderPlugin: Unknown ${_MToonMaterialLoaderPlugin.EXTENSION_NAME} specVersion "${specVersion}"`
|
||
|
|
);
|
||
|
|
return void 0;
|
||
|
|
}
|
||
|
|
return extension;
|
||
|
|
}
|
||
|
|
_extendMaterialParams(extension, materialParams) {
|
||
|
|
return __async(this, null, function* () {
|
||
|
|
var _a;
|
||
|
|
delete materialParams.metalness;
|
||
|
|
delete materialParams.roughness;
|
||
|
|
const assignHelper = new GLTFMToonMaterialParamsAssignHelper(this.parser, materialParams);
|
||
|
|
assignHelper.assignPrimitive("transparentWithZWrite", extension.transparentWithZWrite);
|
||
|
|
assignHelper.assignColor("shadeColorFactor", extension.shadeColorFactor);
|
||
|
|
assignHelper.assignTexture("shadeMultiplyTexture", extension.shadeMultiplyTexture, true);
|
||
|
|
assignHelper.assignPrimitive("shadingShiftFactor", extension.shadingShiftFactor);
|
||
|
|
assignHelper.assignTexture("shadingShiftTexture", extension.shadingShiftTexture, true);
|
||
|
|
assignHelper.assignPrimitive("shadingShiftTextureScale", (_a = extension.shadingShiftTexture) == null ? void 0 : _a.scale);
|
||
|
|
assignHelper.assignPrimitive("shadingToonyFactor", extension.shadingToonyFactor);
|
||
|
|
assignHelper.assignPrimitive("giEqualizationFactor", extension.giEqualizationFactor);
|
||
|
|
assignHelper.assignColor("matcapFactor", extension.matcapFactor);
|
||
|
|
assignHelper.assignTexture("matcapTexture", extension.matcapTexture, true);
|
||
|
|
assignHelper.assignColor("parametricRimColorFactor", extension.parametricRimColorFactor);
|
||
|
|
assignHelper.assignTexture("rimMultiplyTexture", extension.rimMultiplyTexture, true);
|
||
|
|
assignHelper.assignPrimitive("rimLightingMixFactor", extension.rimLightingMixFactor);
|
||
|
|
assignHelper.assignPrimitive("parametricRimFresnelPowerFactor", extension.parametricRimFresnelPowerFactor);
|
||
|
|
assignHelper.assignPrimitive("parametricRimLiftFactor", extension.parametricRimLiftFactor);
|
||
|
|
assignHelper.assignPrimitive("outlineWidthMode", extension.outlineWidthMode);
|
||
|
|
assignHelper.assignPrimitive("outlineWidthFactor", extension.outlineWidthFactor);
|
||
|
|
assignHelper.assignTexture("outlineWidthMultiplyTexture", extension.outlineWidthMultiplyTexture, false);
|
||
|
|
assignHelper.assignColor("outlineColorFactor", extension.outlineColorFactor);
|
||
|
|
assignHelper.assignPrimitive("outlineLightingMixFactor", extension.outlineLightingMixFactor);
|
||
|
|
assignHelper.assignTexture("uvAnimationMaskTexture", extension.uvAnimationMaskTexture, false);
|
||
|
|
assignHelper.assignPrimitive("uvAnimationScrollXSpeedFactor", extension.uvAnimationScrollXSpeedFactor);
|
||
|
|
assignHelper.assignPrimitive("uvAnimationScrollYSpeedFactor", extension.uvAnimationScrollYSpeedFactor);
|
||
|
|
assignHelper.assignPrimitive("uvAnimationRotationSpeedFactor", extension.uvAnimationRotationSpeedFactor);
|
||
|
|
assignHelper.assignPrimitive("v0CompatShade", this.v0CompatShade);
|
||
|
|
assignHelper.assignPrimitive("debugMode", this.debugMode);
|
||
|
|
yield assignHelper.pending;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* This will do two processes that is required to render MToon properly.
|
||
|
|
*
|
||
|
|
* - Set render order
|
||
|
|
* - Generate outline
|
||
|
|
*
|
||
|
|
* @param mesh A target GLTF primitive
|
||
|
|
* @param materialIndex The material index of the primitive
|
||
|
|
*/
|
||
|
|
_setupPrimitive(mesh, materialIndex) {
|
||
|
|
const extension = this._getMToonExtension(materialIndex);
|
||
|
|
if (extension) {
|
||
|
|
const renderOrder = this._parseRenderOrder(extension);
|
||
|
|
mesh.renderOrder = renderOrder + this.renderOrderOffset;
|
||
|
|
this._generateOutline(mesh);
|
||
|
|
this._addToMaterialSet(mesh);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check whether the material should generate outline or not.
|
||
|
|
* @param surfaceMaterial The material to check
|
||
|
|
* @returns True if the material should generate outline
|
||
|
|
*/
|
||
|
|
_shouldGenerateOutline(surfaceMaterial) {
|
||
|
|
return typeof surfaceMaterial.outlineWidthMode === "string" && surfaceMaterial.outlineWidthMode !== "none" && typeof surfaceMaterial.outlineWidthFactor === "number" && surfaceMaterial.outlineWidthFactor > 0;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Generate outline for the given mesh, if it needs.
|
||
|
|
*
|
||
|
|
* @param mesh The target mesh
|
||
|
|
*/
|
||
|
|
_generateOutline(mesh) {
|
||
|
|
const surfaceMaterial = mesh.material;
|
||
|
|
if (!(surfaceMaterial instanceof THREE5.Material)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (!this._shouldGenerateOutline(surfaceMaterial)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
mesh.material = [surfaceMaterial];
|
||
|
|
const outlineMaterial = surfaceMaterial.clone();
|
||
|
|
outlineMaterial.name += " (Outline)";
|
||
|
|
outlineMaterial.isOutline = true;
|
||
|
|
outlineMaterial.side = THREE5.BackSide;
|
||
|
|
mesh.material.push(outlineMaterial);
|
||
|
|
const geometry = mesh.geometry;
|
||
|
|
const primitiveVertices = geometry.index ? geometry.index.count : geometry.attributes.position.count / 3;
|
||
|
|
geometry.addGroup(0, primitiveVertices, 0);
|
||
|
|
geometry.addGroup(0, primitiveVertices, 1);
|
||
|
|
}
|
||
|
|
_addToMaterialSet(mesh) {
|
||
|
|
const materialOrMaterials = mesh.material;
|
||
|
|
const materialSet = /* @__PURE__ */ new Set();
|
||
|
|
if (Array.isArray(materialOrMaterials)) {
|
||
|
|
materialOrMaterials.forEach((material) => materialSet.add(material));
|
||
|
|
} else {
|
||
|
|
materialSet.add(materialOrMaterials);
|
||
|
|
}
|
||
|
|
for (const material of materialSet) {
|
||
|
|
this._mToonMaterialSet.add(material);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
_parseRenderOrder(extension) {
|
||
|
|
var _a;
|
||
|
|
const enabledZWrite = extension.transparentWithZWrite;
|
||
|
|
return (enabledZWrite ? 0 : 19) + ((_a = extension.renderQueueOffsetNumber) != null ? _a : 0);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
_MToonMaterialLoaderPlugin.EXTENSION_NAME = "VRMC_materials_mtoon";
|
||
|
|
var MToonMaterialLoaderPlugin = _MToonMaterialLoaderPlugin;
|
||
|
|
export {
|
||
|
|
MToonMaterial,
|
||
|
|
MToonMaterialDebugMode,
|
||
|
|
MToonMaterialLoaderPlugin,
|
||
|
|
MToonMaterialOutlineWidthMode
|
||
|
|
};
|
||
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL01Ub29uTWF0ZXJpYWxMb2FkZXJQbHVnaW4udHMiLCAiLi4vc3JjL0dMVEZNVG9vbk1hdGVyaWFsUGFyYW1zQXNzaWduSGVscGVyLnRzIiwgIi4uL3NyYy91dGlscy9zZXRUZXh0dXJlQ29sb3JTcGFjZS50cyIsICIuLi9zcmMvTVRvb25NYXRlcmlhbC50cyIsICIuLi9zcmMvc2hhZGVycy9tdG9vbi52ZXJ0IiwgIi4uL3NyYy9zaGFkZXJzL210b29uLmZyYWciLCAiLi4vc3JjL01Ub29uTWF0ZXJpYWxEZWJ1Z01vZGUudHMiLCAiLi4vc3JjL01Ub29uTWF0ZXJpYWxPdXRsaW5lV2lkdGhNb2RlLnRzIiwgIi4uL3NyYy91dGlscy9nZXRUZXh0dXJlQ29sb3JTcGFjZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0ICogYXMgVEhSRUUgZnJvbSAndGhyZWUnO1xuaW1wb3J0ICogYXMgVjFNVG9vblNjaGVtYSBmcm9tICdAcGl4aXYvdHlwZXMtdnJtYy1tYXRlcmlhbHMtbXRvb24tMS4wJztcbmltcG9ydCB0eXBlIHsgR0xURiwgR0xURkxvYWRlciwgR0xURkxvYWRlclBsdWdpbiwgR0xURlBhcnNlciB9IGZyb20gJ3RocmVlL2V4YW1wbGVzL2pzbS9sb2FkZXJzL0dMVEZMb2FkZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBNVG9vbk1hdGVyaWFsUGFyYW1ldGVycyB9IGZyb20gJy4vTVRvb25NYXRlcmlhbFBhcmFtZXRlcnMnO1xuaW1wb3J0IHR5cGUgeyBNVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZSB9IGZyb20gJy4vTVRvb25NYXRlcmlhbE91dGxpbmVXaWR0aE1vZGUnO1xuaW1wb3J0IHsgR0xURk1Ub29uTWF0ZXJpYWxQYXJhbXNBc3NpZ25IZWxwZXIgfSBmcm9tICcuL0dMVEZNVG9vbk1hdGVyaWFsUGFyYW1zQXNzaWduSGVscGVyJztcbmltcG9ydCB0eXBlIHsgTVRvb25NYXRlcmlhbExvYWRlclBsdWdpbk9wdGlvbnMgfSBmcm9tICcuL01Ub29uTWF0ZXJpYWxMb2FkZXJQbHVnaW5PcHRpb25zJztcbmltcG9ydCB0eXBlIHsgTVRvb25NYXRlcmlhbERlYnVnTW9kZSB9IGZyb20gJy4vTVRvb25NYXRlcmlhbERlYnVnTW9kZSc7XG5pbXBvcnQgeyBHTFRGIGFzIEdMVEZTY2hlbWEgfSBmcm9tICdAZ2x0Zi10cmFuc2Zvcm0vY29yZSc7XG5pbXBvcnQgeyBNVG9vbk1hdGVyaWFsIH0gZnJvbSAnLi9NVG9vbk1hdGVyaWFsJztcbmltcG9ydCB0eXBlIHsgTVRvb25Ob2RlTWF0ZXJpYWwgfSBmcm9tICcuL25vZGVzL01Ub29uTm9kZU1hdGVyaWFsJztcblxuLyoqXG4gKiBQb3NzaWJsZSBzcGVjIHZlcnNpb25zIGl0IHJlY29nbml6ZXMuXG4gKi9cbmNvbnN0IFBPU1NJQkxFX1NQRUNfVkVSU0lPTlMgPSBuZXcgU2V0KFsnMS4wJywgJzEuMC1iZXRhJ10pO1xuXG4vKipcbiAqIEEgbG9hZGVyIHBsdWdpbiBvZiB7QGxpbmsgR0xURkxvYWRlcn0gZm9yIHRoZSBleHRlbnNpb24gYFZSTUNfbWF0ZXJpYWxzX210b29uYC5cbiAqXG4gKiBUaGlzIHBsdWdpbiBpcyBmb3IgdXNlcyB3aXRoIFdlYkdMUmVuZGVyZXIgYnkgZGVmYXVsdC5cbiAqIFRvIHVzZSBNVG9vbiBpbiBXZWJHUFVSZW5kZXJlciwgc2V0IHtAbGluayBtYXRlcmlhbFR5cGV9IHRvIHtAbGluayBNVG9vbk5vZGVNYXRlcmlhbH0uXG4gKlxuICogQGV4YW1wbGUgdG8gdXNlIHdpdGggV2ViR1BVUmVuZGVyZXJcbiAqIGBgYGpzXG4gKiBpbXBvcnQgeyBNVG9vbk1hdGVyaWFsTG9hZGVyUGx1Z2luIH0gZnJvbSAnQHBpeGl2L3RocmVlLXZybS1tYXRlcmlhbHMtbXRvb24nO1xuICogaW1wb3J0IHsgTVRvb25Ob2RlTWF0ZXJpYWwgfSBmcm9tICdAcGl4aXYvdGhyZWUtdnJtLW1hdGVyaWFscy1tdG9vbi9ub2Rlcyc7XG4gKlxuICogLy8gLi4uXG4gKlxuICogLy8gUmVnaXN0ZXIgYSBNVG9vbk1hdGVyaWFsTG9hZGVyUGx1Z2luIHdpdGggTVRvb25Ob2RlTWF0ZXJpYWxcbiAqIGxvYWRlci5yZWdpc3RlcigocGFyc2VyKSA9PiB7XG4gKlxuICogICAvLyBjcmVhdGUgYSBXZWJHUFUgY29tcGF0aWJsZSBNVG9vbk1hdGVyaWFsTG9hZGVyUGx1Z2luXG4gKiAgIHJldHVybiBuZXcgTVRvb25NYXRlcmlhbExvYWRlclBsdWdpbihwYXJzZXIsIHtcbiAqXG4gKiAgICAgLy8gc2V0IHRoZSBtYXRlcmlhbCB0eXBlIHRvIE1Ub29uTm9kZU1hdGVyaWFsXG4gKiAgICAgbWF0ZXJpYWxUeXBlOiBNVG9vbk5vZGVNYXRlcmlhbCxcbiAqXG4gKiAgIH0pO1xuICpcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBNVG9vbk1hdGVyaWFsTG9hZGVyUGx1Z2luIGltcGxlbWVudHMgR0xURkxvYWRlclBsdWdpbiB7XG4gIHB1YmxpYyBzdGF0aWMgRVhURU5TSU9OX05BTUUgPSAnVlJNQ19tYXRlcmlhbHNfbXRvb24nO1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgbWF0ZXJpYWwgdGhhdCB0aGlzIHBsdWdpbiB3aWxsIGdlbmVyYXRlLlxuICAgKlxuICAgKiBJZiB5b3UgYXJlIHVzaW5nIHRoaXMgcGx1Z2luIHdpdGggV2ViR1BVLCBzZXQgdGhpcyB0byB7QGxpbmsgTVRvb25Ob2RlTWF0ZXJpYWx9LlxuICAgKlxuICAgKiBAZGVmYXVsdCBNVG9vbk1hdGVyaWFsXG4gICAqL1xuICBwdWJsaWMgbWF0ZXJpYWxUeXBlOiB0eXBlb2YgVEhSRUUuTWF0ZXJpYWw7XG5cbiAgLyoqXG4gICAqIFRoaXMgdmFsdWUgd2lsbCBiZSBhZGRlZCB0byBgcmVuZGVyT3JkZXJgIG9mIGV2ZXJ5IG1lc2hlcyB3aG8gaGF2ZSBNYXRlcmlhbHNNVG9vbi5cbiAgICogVGhlIGZpbmFsIHJlbmRlck9yZGVyIHdpbGwgYmUgc3VtIG9mIHRoaXMgYHJlbmRlck9yZGVyT2Zmc2V0YCBhbmQgYHJlbmRlclF1ZXVlT2Zmc2V0TnVtYmVyYCBmb3IgZWFjaCBtYXRlcmlhbHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIHB1YmxpYyByZW5kZXJPcmRlck9mZnNldDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGVyZSBpcyBhIGxpbmUgb2YgdGhlIHNoYWRlciBjYWxsZWQgXCJjb21tZW50IG91dCBpZiB5b3Ugd2FudCB0byBQQlIgYWJzb2x1dGVseVwiIGluIFZSTTAuMCBNVG9vbi5cbiAgICogV2hlbiB0aGlzIGlzIHRydWUsIHRoZSBtYXRlcmlhbCBlbmFibGVzIHRoZSBsaW5lIHRvIG1ha2UgaXQgY29tcGF0aWJsZSB3aXRoIHRoZSBsZWdhY3kgc
|