Open7
UnityのURP-MToon触ってみたメモ
背景
- メタバースでバーチャルライブをするときに、URPは軽量で便利そう
- 過去、URP未対応のMToonに苦戦していた
- どうも、UniVRMがURP MToon 利用可能になったみたい
目的
- バーチャルライブでどんな感じで使えるかをチェックしたい
- VRMへのライトの当たり方をチェックできるプロジェクトあれば便利そう
- アバターをサクサク差し替えたい
スコープ
- ランタイムでURPプロジェクトにVRMを入れる
制約
- unitypackageとして出せる状態にする
前提
- 特になし
UniVRMインポート
- githubリリースページ
- vrm-1.0向けらしい
- via UPM Package(上記サイトにunitypackageもある)
com.vrmc.vrmshaders
com.vrmc.gltf
com.vrmc.vrm
- Assetsに追加確認
VRMモデル導入
- 3Dモデル「止丸式初音ミクNT」をお借りする
問題
- .vrmが.fbxに展開されない
検討
-
https://github.com/vrm-c/UniVRM/releases/tag/v0.112.0
- リリースノートいわく、「VRM-0.x モデルでも import 時に migrate して VRM-1.0 として運用することで URP 適用が可能です」
解決
- VRMドキュメント:https://vrm.dev/univrm1/migrate_vrm0/index.html
- 手順:https://vrm.dev/univrm1/migrate_vrm0/migrate_editor.html
- vrm0.x の vrm ファイルを Unity Project Asset に投入
- インスペクタで Migration フラグを有効にし Apply
- ライセンスなどを適切に修正する
- Prefab を vrm1.0 としてそのまま Export する
- 手順:https://vrm.dev/univrm1/migrate_vrm0/migrate_editor.html
- できたけどピンク
URP-MToon利用
- mtoon_urpのパスは以下参照
- デフォルトでピンク表示で、結局手作業でシェーダ切り替えすることになる
問題
- シェーダ一括変換スクリプトで動的に切り替えたいが、不具合がある
- 半透明系のシェーダが入ってると使えないのかな?
- もし動的変更でうまくいかないなら、URP対応のMToonはあまり意味がない
- もしかしたらVroid_SampleB特有のバグかも

解決
- AlphaModeをcutoutに変更すれば直るが、ランタイムでcutoutのパラメータを引き継いでも、再度別のパラメータに変えてまたcutoutにしないと変更が反映されない
- いずれにせよランタイムで変更しても不具合が出ることに変わりない
- 不具合があったモデルは使わないという方針で、いったん運用でなんとかする
ランタイムロード機能を入れる
- ランタイムロードをする際に、vrm0系の知見を使えないなら、わざわざ1系にしてまでMToonのURPを使おうとは思わない
シェーダ変換スクリプト
使い方
ステップ1: スクリプトの配置
- シーン内の任意の空のオブジェクトを作成し、このスクリプトをそのオブジェクトにアタッチします。
ステップ2: 対象オブジェクトの指定
- インスペクター上で
targetObjectsフィールドにシェーダーを適用したいオブジェクトをドラッグ&ドロップします。 - 複数のオブジェクトにシェーダーを適用する場合、配列にそれらのオブジェクトを追加します。
ステップ3: URPシェーダーの指定
-
urpShaderフィールドに切り替えたいURPシェーダーを指定します。必要なURPシェーダーをプロジェクト内で見つけ、そのシェーダーをこのフィールドにドラッグ&ドロップします。
ステップ4: ゲームの開始
- シーンを再生すると、指定されたオブジェクトのシェーダーが自動的にURPへ切り替わります。
注意事項
- 正しく動作させるためには、指定するシェーダーがURPに対応している必要があります。
- オブジェクトがnullまたはシェーダーが未指定の場合、エラーメッセージが表示されます。
このスクリプトを使用することで、ゲーム開始時に自動的に指定したオブジェクトのシェーダーがURPへ切り替わります。
コード
using UnityEngine;
public class MToon2URPSwitcher : MonoBehaviour
{
public GameObject[] targetObjects; // 対象となるオブジェクトの配列
public Shader urpShader; // URPへ切り替えるためのシェーダー
private void Start()
{
// 開始時に全ターゲットにシェーダーを適用
foreach (var target in targetObjects)
{
ApplyShader(target);
}
}
private void ApplyShader(GameObject target)
{
// シェーダーが指定されていない場合のエラー処理
if (urpShader == null)
{
Debug.LogError("URP shader is not specified.");
return;
}
// ターゲットオブジェクトが指定されていない場合のエラー処理
if (target == null)
{
Debug.LogError("Target object is not specified.");
return;
}
Renderer[] childRenderers = target.GetComponentsInChildren<Renderer>();
// 各レンダラーに対してマテリアルを変更
foreach (Renderer renderer in childRenderers)
{
Material[] materials = renderer.materials;
for (int i = 0; i < materials.Length; i++)
{
Material originalMaterial = materials[i];
Material newMaterial = new Material(urpShader);
// レンダリングとライティングのプロパティをコピー
CopyRenderingProperties(originalMaterial, newMaterial);
CopyLightingProperties(originalMaterial, newMaterial);
materials[i] = newMaterial;
}
renderer.materials = materials;
}
}
// レンダリングプロパティのコピー
private void CopyRenderingProperties(Material original, Material destination)
{
CopyProperties(original, destination, "_AlphaMode", "_TransparentWithZWrite", "_Cutoff", "_RenderQueueOffset", "_DoubleSided");
}
// ライティングプロパティのコピー
private void CopyLightingProperties(Material original, Material destination)
{
CopyProperties(original, destination, "_Color", "_MainTex", "_ShadeColor", "_ShadeTex", "_BumpMap", "_BumpScale");
}
// 指定されたプロパティ名でマテリアルのプロパティをコピー
private void CopyProperties(Material original, Material destination, params string[] propertyNames)
{
foreach (var propName in propertyNames)
{
if (original.HasProperty(propName) && destination.HasProperty(propName))
{
if (propName == "_MainTex" || propName == "_ShadeTex" || propName == "_BumpMap")
{
destination.SetTexture(propName, original.GetTexture(propName));
}
else if (propName == "_Color" || propName == "_ShadeColor")
{
destination.SetColor(propName, original.GetColor(propName));
}
else
{
destination.SetFloat(propName, original.GetFloat(propName));
}
}
}
}
}
Appendix
変換前:普通のMToon
VRM10/Universal Render Pipeline/MToon10
Shader "VRM10/Universal Render Pipeline/MToon10"
{
Properties
{
// Rendering
_AlphaMode ("alphaMode", Int) = 0
_TransparentWithZWrite ("mtoon.transparentWithZWrite", Int) = 0
_Cutoff ("alphaCutoff", Range(0, 1)) = 0.5 // Unity specified name
_RenderQueueOffset ("mtoon.renderQueueOffsetNumber", Int) = 0
_DoubleSided ("doubleSided", Int) = 0
// Lighting
_Color ("pbrMetallicRoughness.baseColorFactor", Color) = (1, 1, 1, 1) // Unity specified name
_MainTex ("pbrMetallicRoughness.baseColorTexture", 2D) = "white" {} // Unity specified name
_ShadeColor ("mtoon.shadeColorFactor", Color) = (1, 1, 1, 1)
_ShadeTex ("mtoon.shadeMultiplyTexture", 2D) = "white" {}
[Normal] _BumpMap ("normalTexture", 2D) = "bump" {} // Unity specified name
_BumpScale ("normalTexture.scale", Float) = 1.0 // Unity specified name
_ShadingShiftFactor ("mtoon.shadingShiftFactor", Range(-1, 1)) = -0.05
_ShadingShiftTex ("mtoon.shadingShiftTexture", 2D) = "black" {} // channel R
_ShadingShiftTexScale ("mtoon.shadingShiftTexture.scale", Float) = 1
_ShadingToonyFactor ("mtoon.shadingToonyFactor", Range(0, 1)) = 0.95
// GI
_GiEqualization ("mtoon.giEqualizationFactor", Range(0, 1)) = 0.9
// Emission
[HDR] _EmissionColor ("emissiveFactor", Color) = (0, 0, 0, 1) // Unity specified name
_EmissionMap ("emissiveTexture", 2D) = "white" {} // Unity specified name
// Rim Lighting
_MatcapColor ("mtoon.matcapFactor", Color) = (0, 0, 0, 1)
_MatcapTex ("mtoon.matcapTexture", 2D) = "black" {}
_RimColor ("mtoon.parametricRimColorFactor", Color) = (0, 0, 0, 1)
_RimFresnelPower ("mtoon.parametricRimFresnelPowerFactor", Range(0, 100)) = 5.0
_RimLift ("mtoon.parametricRimLiftFactor", Range(0, 1)) = 0
_RimTex ("mtoon.rimMultiplyTexture", 2D) = "white" {}
_RimLightingMix ("mtoon.rimLightingMixFactor", Range(0, 1)) = 1
// Outline
_OutlineWidthMode ("mtoon.outlineWidthMode", Int) = 0
[PowerSlider(2.2)] _OutlineWidth ("mtoon.outlineWidthFactor", Range(0, 0.05)) = 0
_OutlineWidthTex ("mtoon.outlineWidthMultiplyTexture", 2D) = "white" {} // channel G
_OutlineColor ("mtoon.outlineColorFactor", Color) = (0, 0, 0, 1)
_OutlineLightingMix ("mtoon.outlineLightingMixFactor", Range(0, 1)) = 1
// UV Animation
_UvAnimMaskTex ("mtoon.uvAnimationMaskTexture", 2D) = "white" {} // channel B
_UvAnimScrollXSpeed ("mtoon.uvAnimationScrollXSpeedFactor", Float) = 0
_UvAnimScrollYSpeed ("mtoon.uvAnimationScrollYSpeedFactor", Float) = 0
_UvAnimRotationSpeed ("mtoon.uvAnimationRotationSpeedFactor", Float) = 0
// Unity ShaderPass Mode
_M_CullMode ("_CullMode", Float) = 2.0
_M_SrcBlend ("_SrcBlend", Float) = 1.0
_M_DstBlend ("_DstBlend", Float) = 0.0
_M_ZWrite ("_ZWrite", Float) = 1.0
_M_AlphaToMask ("_AlphaToMask", Float) = 0.0
// etc
_M_DebugMode ("_DebugMode", Float) = 0.0
// for Editor
_M_EditMode ("_EditMode", Float) = 0.0
}
// Shader Model 3.0
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "Lit"
"IgnoreProjector" = "True"
}
// Built-in Forward Base Pass
Pass
{
Name "UniversalForward"
Tags { "LightMode" = "UniversalForward" }
Cull [_M_CullMode]
Blend [_M_SrcBlend] [_M_DstBlend]
ZWrite [_M_ZWrite]
ZTest LEqual
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_fwdbase nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile __ _NORMALMAP
#pragma multi_compile __ _MTOON_EMISSIVEMAP
#pragma multi_compile __ _MTOON_RIMMAP
#pragma multi_compile __ _MTOON_PARAMETERMAP
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#define MTOON_URP
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Built-in Forward Base Pass
Pass
{
Name "MToonOutline"
Tags { "LightMode" = "MToonOutline" }
Cull Front
Blend [_M_SrcBlend] [_M_DstBlend]
ZWrite [_M_ZWrite]
ZTest LEqual
Offset 1, 1
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_fwdbase nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile __ _NORMALMAP
#pragma multi_compile __ _MTOON_EMISSIVEMAP
#pragma multi_compile __ _MTOON_RIMMAP
#pragma multi_compile __ _MTOON_PARAMETERMAP
#pragma multi_compile __ _MTOON_OUTLINE_WORLD _MTOON_OUTLINE_SCREEN
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#define MTOON_URP
#define MTOON_PASS_OUTLINE
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Shadow rendering pass
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
Cull [_M_CullMode]
ZWrite On
ZTest LEqual
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_shadowcaster nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma vertex MToonShadowCasterVertex
#pragma fragment MToonShadowCasterFragment
#define MTOON_URP
#include "./vrmc_materials_mtoon_shadowcaster_vertex.hlsl"
#include "./vrmc_materials_mtoon_shadowcaster_fragment.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "VRMShaders.VRM10.MToon10.Editor.MToonInspector"
}
変換後:URP対応MToon
VRM10/Universal Render Pipeline/MToon10
Shader "VRM10/Universal Render Pipeline/MToon10"
{
Properties
{
// Rendering
_AlphaMode ("alphaMode", Int) = 0
_TransparentWithZWrite ("mtoon.transparentWithZWrite", Int) = 0
_Cutoff ("alphaCutoff", Range(0, 1)) = 0.5 // Unity specified name
_RenderQueueOffset ("mtoon.renderQueueOffsetNumber", Int) = 0
_DoubleSided ("doubleSided", Int) = 0
// Lighting
_Color ("pbrMetallicRoughness.baseColorFactor", Color) = (1, 1, 1, 1) // Unity specified name
_MainTex ("pbrMetallicRoughness.baseColorTexture", 2D) = "white" {} // Unity specified name
_ShadeColor ("mtoon.shadeColorFactor", Color) = (1, 1, 1, 1)
_ShadeTex ("mtoon.shadeMultiplyTexture", 2D) = "white" {}
[Normal] _BumpMap ("normalTexture", 2D) = "bump" {} // Unity specified name
_BumpScale ("normalTexture.scale", Float) = 1.0 // Unity specified name
_ShadingShiftFactor ("mtoon.shadingShiftFactor", Range(-1, 1)) = -0.05
_ShadingShiftTex ("mtoon.shadingShiftTexture", 2D) = "black" {} // channel R
_ShadingShiftTexScale ("mtoon.shadingShiftTexture.scale", Float) = 1
_ShadingToonyFactor ("mtoon.shadingToonyFactor", Range(0, 1)) = 0.95
// GI
_GiEqualization ("mtoon.giEqualizationFactor", Range(0, 1)) = 0.9
// Emission
[HDR] _EmissionColor ("emissiveFactor", Color) = (0, 0, 0, 1) // Unity specified name
_EmissionMap ("emissiveTexture", 2D) = "white" {} // Unity specified name
// Rim Lighting
_MatcapColor ("mtoon.matcapFactor", Color) = (0, 0, 0, 1)
_MatcapTex ("mtoon.matcapTexture", 2D) = "black" {}
_RimColor ("mtoon.parametricRimColorFactor", Color) = (0, 0, 0, 1)
_RimFresnelPower ("mtoon.parametricRimFresnelPowerFactor", Range(0, 100)) = 5.0
_RimLift ("mtoon.parametricRimLiftFactor", Range(0, 1)) = 0
_RimTex ("mtoon.rimMultiplyTexture", 2D) = "white" {}
_RimLightingMix ("mtoon.rimLightingMixFactor", Range(0, 1)) = 1
// Outline
_OutlineWidthMode ("mtoon.outlineWidthMode", Int) = 0
[PowerSlider(2.2)] _OutlineWidth ("mtoon.outlineWidthFactor", Range(0, 0.05)) = 0
_OutlineWidthTex ("mtoon.outlineWidthMultiplyTexture", 2D) = "white" {} // channel G
_OutlineColor ("mtoon.outlineColorFactor", Color) = (0, 0, 0, 1)
_OutlineLightingMix ("mtoon.outlineLightingMixFactor", Range(0, 1)) = 1
// UV Animation
_UvAnimMaskTex ("mtoon.uvAnimationMaskTexture", 2D) = "white" {} // channel B
_UvAnimScrollXSpeed ("mtoon.uvAnimationScrollXSpeedFactor", Float) = 0
_UvAnimScrollYSpeed ("mtoon.uvAnimationScrollYSpeedFactor", Float) = 0
_UvAnimRotationSpeed ("mtoon.uvAnimationRotationSpeedFactor", Float) = 0
// Unity ShaderPass Mode
_M_CullMode ("_CullMode", Float) = 2.0
_M_SrcBlend ("_SrcBlend", Float) = 1.0
_M_DstBlend ("_DstBlend", Float) = 0.0
_M_ZWrite ("_ZWrite", Float) = 1.0
_M_AlphaToMask ("_AlphaToMask", Float) = 0.0
// etc
_M_DebugMode ("_DebugMode", Float) = 0.0
// for Editor
_M_EditMode ("_EditMode", Float) = 0.0
}
// Shader Model 3.0
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "Lit"
"IgnoreProjector" = "True"
}
// Built-in Forward Base Pass
Pass
{
Name "UniversalForward"
Tags { "LightMode" = "UniversalForward" }
Cull [_M_CullMode]
Blend [_M_SrcBlend] [_M_DstBlend]
ZWrite [_M_ZWrite]
ZTest LEqual
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_fwdbase nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile __ _NORMALMAP
#pragma multi_compile __ _MTOON_EMISSIVEMAP
#pragma multi_compile __ _MTOON_RIMMAP
#pragma multi_compile __ _MTOON_PARAMETERMAP
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#define MTOON_URP
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Built-in Forward Base Pass
Pass
{
Name "MToonOutline"
Tags { "LightMode" = "MToonOutline" }
Cull Front
Blend [_M_SrcBlend] [_M_DstBlend]
ZWrite [_M_ZWrite]
ZTest LEqual
Offset 1, 1
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_fwdbase nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile __ _NORMALMAP
#pragma multi_compile __ _MTOON_EMISSIVEMAP
#pragma multi_compile __ _MTOON_RIMMAP
#pragma multi_compile __ _MTOON_PARAMETERMAP
#pragma multi_compile __ _MTOON_OUTLINE_WORLD _MTOON_OUTLINE_SCREEN
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#define MTOON_URP
#define MTOON_PASS_OUTLINE
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Shadow rendering pass
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
Cull [_M_CullMode]
ZWrite On
ZTest LEqual
HLSLPROGRAM
#pragma target 3.0
// Unity defined keywords
#pragma multi_compile_shadowcaster nolightmap nodynlightmap nodirlightmap novertexlight
#pragma multi_compile_instancing
#pragma multi_compile __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma vertex MToonShadowCasterVertex
#pragma fragment MToonShadowCasterFragment
#define MTOON_URP
#include "./vrmc_materials_mtoon_shadowcaster_vertex.hlsl"
#include "./vrmc_materials_mtoon_shadowcaster_fragment.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "VRMShaders.VRM10.MToon10.Editor.MToonInspector"
}




