### Install Avatar Optimizer using vrc-get CLI Source: https://vpm.anatawa12.com/avatar-optimizer/en Adds the anatawa12 VPM repository and installs the com.anatawa12.avatar-optimizer package using the vrc-get command-line tool. ```bash # add our vpm repository vrc-get repo add https://vpm.anatawa12.com/vpm.json # add package to your project cd /path/to/your-unity-project vrc-get install com.anatawa12.avatar-optimizer ``` -------------------------------- ### Install Avatar Optimizer using VPM CLI Source: https://vpm.anatawa12.com/avatar-optimizer/en Adds the anatawa12 VPM repository and installs the com.anatawa12.avatar-optimizer package using the VPM/VCC command-line interface. ```bash # add our vpm repository vpm add repo https://vpm.anatawa12.com/vpm.json # add package to your project cd /path/to/your-unity-project vpm add package com.anatawa12.avatar-optimizer ``` -------------------------------- ### Register Shader Information by GUID Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a ShaderInformation implementation using the shader asset's GUID. Recommended because GUIDs are stable and don't require accessing AssetDatabase, which is invalid in InitializeOnLoad methods. ```csharp ShaderInformationRegistry.RegisterShaderInformationWithGUID( "your-shader-asset-guid", new YourShaderInformation() ); ``` -------------------------------- ### Create and register a ShaderInformation class Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Create a ShaderInformation subclass and register it with ShaderInformationRegistry. The class must be Editor-only and guarded with AVATAR_OPTIMIZER and UNITY_EDITOR. Registration uses [InitializeOnLoad] and a static constructor so it runs before Avatar Optimizer processes materials. Replace the shader GUID and implement GetMaterialInformation to register texture and UV usage. ```csharp #if AVATAR_OPTIMIZER && UNITY_EDITOR using Anatawa12.AvatarOptimizer.API; using UnityEditor; using UnityEngine; namespace YourNamespace { [InitializeOnLoad] internal class YourShaderInformation : ShaderInformation { static YourShaderInformation() { // Register with shader GUID (recommended for shader assets) string shaderGuid = "your-shader-guid-here"; ShaderInformationRegistry.RegisterShaderInformationWithGUID( shaderGuid, new YourShaderInformation() ); } public override ShaderInformationKind SupportedInformationKind => ShaderInformationKind.TextureAndUVUsage; public override void GetMaterialInformation(MaterialInformationCallback matInfo) { // Register texture and UV usage here (see examples below) } } } #endif ``` -------------------------------- ### Combine ShaderInformationKind flags with OR operator Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Use this snippet to combine multiple ShaderInformationKind flags in a shader information provider. The example combines TextureAndUVUsage and VertexIndexUsage, indicating the shader provides texture usage and vertex index usage information. ```csharp public override ShaderInformationKind SupportedInformationKind => ShaderInformationKind.TextureAndUVUsage | ShaderInformationKind.VertexIndexUsage; ``` -------------------------------- ### Register Shader Information with InitializeOnLoad Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers Shader Information in a static constructor with [InitializeOnLoad] to ensure registration happens before 'Apply on Play' builds. The registration occurs automatically when Unity loads. ```csharp [InitializeOnLoad] internal class YourShaderInformation : ShaderInformation { static YourShaderInformation() { // Registration happens automatically when Unity loads Register(); } private static void Register() { ShaderInformationRegistry.RegisterShaderInformationWithGUID( "guid", new YourShaderInformation() ); } } ``` -------------------------------- ### Check Keywords and Properties Before Registering Textures Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Shows how to conditionally register textures based on shader keywords and property values. Uses IsShaderKeywordEnabled and GetFloat to check if a feature is enabled, with a conservative approach for unknown values. ```csharp if (matInfo.IsShaderKeywordEnabled("_NORMALMAP") != false) { // Keyword might be enabled, register normal map } if (matInfo.GetFloat("_UseEmission") != 0) { // Emission is enabled, register emission map } ``` -------------------------------- ### Handle Unknown Values with Pattern Matching and Union Values Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Shows how to handle null values for material properties that might be animated or unknown. Uses pattern matching for Vector values and a switch expression for float values, treating null as unknown and using a union of UV channels. ```csharp // Use pattern matching var st = matInfo.GetVector("_MainTex_ST"); Matrix2x3? uvMatrix = st is { } st2 ? Matrix2x3.NewScaleOffset(st2) : null; // Use union value for null cases var uvChannel = matInfo.GetFloat("_UVChannel") switch { 0 => UsingUVChannels.UV0, 1 => UsingUVChannels.UV1, null => UsingUVChannels.UV0 | UsingUVChannels.UV1, // Unknown _ => UsingUVChannels.UV0 | UsingUVChannels.UV1 }; ``` -------------------------------- ### Define ComponentInformation for your component Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/make-your-components-compatible-with-aao This snippet shows how to define a ComponentInformation class for your component to register it with Avatar Optimizer. It should be wrapped in `#if AVATAR_OPTIMIZER && UNITY_EDITOR` to only be compiled when the Avatar Optimizer API is available and in the editor. Override `CollectMutations` to register mutations your component may perform, and `CollectDependency` to register build-time or run-time dependencies. This class must be in an assembly that references `com.anatawa12.avatar-optimizer.api.editor`. ```csharp #if AVATAR_OPTIMIZER && UNITY_EDITOR [ComponentInformation(typeof(YourComponent))] internal class YourComponentInformation : ComponentInformation { protected override void CollectMutations(YourComponent component, ComponentMutationsCollector collector) { // call methods on the collector to tell about the component } protected override void CollectDependency(YourComponent component, ComponentDependencyCollector collector) { // call methods on the collector to tell about the component } } #endif ``` -------------------------------- ### Register Texture Usage with Dynamic UV Channel Selection Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Selects UV channel based on a material property; if unknown, registers both UV0 and UV1. ```csharp var uvChannel = matInfo.GetFloat("_UVChannel") switch { 0 => UsingUVChannels.UV0, 1 => UsingUVChannels.UV1, _ => UsingUVChannels.UV0 | UsingUVChannels.UV1 // Unknown, could be either }; matInfo.RegisterTextureUVUsage("_DetailTex", "_DetailTex", uvChannel, uvMatrix); ``` -------------------------------- ### Convert Scale and Offset to Matrix2x3 Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Converts Vector4 _MainTex_ST to a Matrix2x3 using Matrix2x3.NewScaleOffset, or null if not present. ```csharp var texST = matInfo.GetVector("_MainTex_ST"); Matrix2x3? uvMatrix = texST is { } st ? Matrix2x3.NewScaleOffset(st) : null; ``` -------------------------------- ### Registering Texture Usage with RegisterTextureUVUsage Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a 2D texture's UV usage, including its UV transform from _MainTex_ST. Uses sampler from the same property. ```csharp public override void GetMaterialInformation(MaterialInformationCallback matInfo) { // Get the UV transform (scale/offset) var mainTexST = matInfo.GetVector("_MainTex_ST"); Matrix2x3? uvMatrix = mainTexST is { } st ? Matrix2x3.NewScaleOffset(st) : null; // Register the texture matInfo.RegisterTextureUVUsage( textureMaterialPropertyName: "_MainTex", samplerState: "_MainTex", // Uses sampler from _MainTex property uvChannels: UsingUVChannels.UV0, uvMatrix: uvMatrix ); } ``` -------------------------------- ### Register Shader Information by Shader Instance Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a ShaderInformation implementation using a shader instance, useful for shaders dynamically created on build or when you have the shader instance. ```csharp Shader shader = Shader.Find("Your/Shader/Name"); ShaderInformationRegistry.RegisterShaderInformation( shader, new YourShaderInformation() ); ``` -------------------------------- ### Register Texture Usage with Implicit Sampler Conversion Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers texture usage with samplerState as a string; implicitly converted to SamplerStateInformation. ```csharp matInfo.RegisterTextureUVUsage( "_MainTex", samplerState: "_MainTex", // String implicitly converts UsingUVChannels.UV0, uvMatrix ); ``` -------------------------------- ### Simple Shader with Main Texture Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a ShaderInformation for a shader with a single main texture. It reports UV usage for _MainTex on UV0 with the scale-offset transform from _MainTex_ST. ```csharp [InitializeOnLoad] internal class SimpleShaderInformation : ShaderInformation { static SimpleShaderInformation() { ShaderInformationRegistry.RegisterShaderInformationWithGUID( "your-shader-guid", new SimpleShaderInformation() ); } public override ShaderInformationKind SupportedInformationKind => ShaderInformationKind.TextureAndUVUsage; public override void GetMaterialInformation(MaterialInformationCallback matInfo) { var mainTexST = matInfo.GetVector("_MainTex_ST"); Matrix2x3? uvMatrix = mainTexST is { } st ? Matrix2x3.NewScaleOffset(st) : null; matInfo.RegisterTextureUVUsage( "_MainTex", "_MainTex", UsingUVChannels.UV0, uvMatrix ); } } ``` -------------------------------- ### Reading Material Properties with MaterialInformationCallback Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Reads float, int, Vector4 properties and checks shader keywords. Returns null if property doesn't exist or value is unknown. ```csharp // Read float properties float? value = matInfo.GetFloat("_PropertyName"); // Read int properties int? value = matInfo.GetInt("_PropertyName"); // Read Vector4 properties (like _MainTex_ST) Vector4? value = matInfo.GetVector("_MainTex_ST"); // Check if shader keyword is enabled bool? enabled = matInfo.IsShaderKeywordEnabled("KEYWORD_NAME"); ``` -------------------------------- ### Shader Using Vertex Indices Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a ShaderInformation for a shader that uses SV_VertexID. It reports both texture and UV usage for _MainTex and vertex index usage via RegisterVertexIndexUsage. ```csharp [InitializeOnLoad] internal class VertexShaderInformation : ShaderInformation { static VertexShaderInformation() { ShaderInformationRegistry.RegisterShaderInformationWithGUID( "your-shader-guid", new VertexShaderInformation() ); } public override ShaderInformationKind SupportedInformationKind => ShaderInformationKind.TextureAndUVUsage | ShaderInformationKind.VertexIndexUsage; public override void GetMaterialInformation(MaterialInformationCallback matInfo) { var mainTexST = matInfo.GetVector("_MainTex_ST"); Matrix2x3? uvMatrix = mainTexST is { } st ? Matrix2x3.NewScaleOffset(st) : null; matInfo.RegisterTextureUVUsage( "_MainTex", "_MainTex", UsingUVChannels.UV0, uvMatrix ); // Shader uses SV_VertexID for effects matInfo.RegisterVertexIndexUsage(); } } ``` -------------------------------- ### Shader with Conditional Features Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a ShaderInformation for a shader with optional textures controlled by keywords and properties. It conditionally registers _BumpMap when _NORMALMAP is enabled, _DetailTex when _UseDetail is non-zero (choosing UV channel based on _DetailUV), and _MatCap when _MATCAP is enabled using a non-mesh UV channel. ```csharp [InitializeOnLoad] internal class FeatureShaderInformation : ShaderInformation { static FeatureShaderInformation() { ShaderInformationRegistry.RegisterShaderInformationWithGUID( "your-shader-guid", new FeatureShaderInformation() ); } public override ShaderInformationKind SupportedInformationKind => ShaderInformationKind.TextureAndUVUsage; public override void GetMaterialInformation(MaterialInformationCallback matInfo) { // Main texture (always present) var mainTexST = matInfo.GetVector("_MainTex_ST"); Matrix2x3? mainUVMatrix = mainTexST is { } st ? Matrix2x3.NewScaleOffset(st) : null; matInfo.RegisterTextureUVUsage( "_MainTex", "_MainTex", UsingUVChannels.UV0, mainUVMatrix ); // Normal map (conditional on keyword) if (matInfo.IsShaderKeywordEnabled("_NORMALMAP") != false) { matInfo.RegisterTextureUVUsage( "_BumpMap", "_BumpMap", UsingUVChannels.UV0, mainUVMatrix ); } // Detail texture (conditional on property) if (matInfo.GetFloat("_UseDetail") != 0) { var detailST = matInfo.GetVector("_DetailTex_ST"); Matrix2x3? detailUVMatrix = detailST is { } st2 ? Matrix2x3.NewScaleOffset(st2) : null; var detailUV = matInfo.GetFloat("_DetailUV") switch { 0 => UsingUVChannels.UV0, 1 => UsingUVChannels.UV1, _ => UsingUVChannels.UV0 | UsingUVChannels.UV1 }; matInfo.RegisterTextureUVUsage( "_DetailTex", "_DetailTex", detailUV, detailUVMatrix ); } // MatCap (screen-space, no UV transform) if (matInfo.IsShaderKeywordEnabled("_MATCAP") != false) { matInfo.RegisterTextureUVUsage( "_MatCap", SamplerStateInformation.LinearClampSampler, UsingUVChannels.NonMesh, null ); } } } ``` -------------------------------- ### Register Texture Usage with NonMesh UV Channel Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers a MatCap texture that does not use mesh UVs; uses NonMesh channel and null UV transform. ```csharp matInfo.RegisterTextureUVUsage( "_MatCapTexture", "_MatCapTexture", UsingUVChannels.NonMesh, // Not from mesh UVs null // No UV transform ); ``` -------------------------------- ### Register Vertex Index Usage Conditionally Source: https://vpm.anatawa12.com/avatar-optimizer/en/docs/developers/shader-information Registers vertex index usage only when a feature using vertex indices is enabled. Note: this disables automatic Merge Skinned Mesh in Trace and Optimize. ```csharp public override void GetMaterialInformation(MaterialInformationCallback matInfo) { // ... register textures ... // Check if the feature using vertex indices is enabled if (matInfo.GetFloat("_UseVertexIdEffect") != 0) { // Tell this shader wants Avatar Optimizer to preserve vertex indices matInfo.RegisterVertexIndexUsage(); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.