DrummerCraig-ShaderHelperForMac icon

ShaderHelperForMac

New V2 refactor. Check README.md. Mod for Apple Silicon (ARM Mac) that automatically fixes broken/pink materials caused by mod shaders that were compiled without Metal GPU support.

Last updated 2 weeks ago
Total downloads 140
Total rating 2 
Categories Client-side Utility AI Generated
Dependency string DrummerCraig-ShaderHelperForMac-2.0.0
Dependants 0 other packages depend on this package

README

ShaderHelperForMac

v2.0.0 — A mod for Valheim on Apple Silicon (ARM Mac) that fixes broken/pink materials caused by mod shaders compiled without Metal GPU support.

Do not run this mod unless you are on an Apple Silicon Mac.

I created this mod for myself but it has made such a meaningful difference that I wanted to share it with the community. It is a work in progress and no guarantees are provided.

To get the most out of playing on an ARM Mac, take the time and watch this instructional video here: https://youtu.be/SQCVkaRel40?si=wxOIYrW1vIzIdtzh


The Problem

Valheim mods ship Unity asset bundles with shaders compiled only for Windows (Direct3D 11). When loaded on macOS with the Metal graphics API, Unity cannot find a Metal-compatible shader variant and substitutes a bright magenta/pink error material. This happens silently — the mod author doesn't need to do anything wrong for it to occur.


Installation

Requirements

Steps

  1. Create the folder:
    BepInEx/plugins/ShaderHelperForMac-DrummerCraig/
    
  2. Copy both files from the download into that folder:
    ShaderHelperForMac.dll
    AssetsTools.NET.dll
    
  3. Launch Valheim. The plugin initializes automatically.

Configuration

BepInEx config file

Located at BepInEx/config/drummercraig.shaderhelperformac.cfg.

Setting Default Description
Default All Transparent false When true, all unsupported shaders are made transparent automatically. When false, shaders are left pink unless the mod is explicitly listed in a config file or covered by a per-mod txt file.
Force Transparent Shader Prefixes (empty) Comma-separated shader name prefixes always made transparent, regardless of other settings.
Force Fallback Shader Prefixes (empty) Comma-separated shader name prefixes always replaced with the fallback shader, even if Unity reports them as supported. Use for shaders that render pink despite isSupported=true.
Periodic Sweep Interval 30 How often (seconds) to re-sweep all materials. Set to 0 to disable.

Per-mod txt files (recommended)

Located at BepInEx/config/ShaderHelperForMac/. Create one file per mod, named after the mod's DLL (e.g. WardIsLove.txt). Use shaderhelper initmod <DllName> to auto-generate a starting file.

Each file uses section headers to control behaviour for that mod:

[forcefallback]
# Shader name prefixes that render pink despite isSupported=true.
# Start here when solid objects (armour, weapons, furniture) are pink.
SomeAuthor/SomePinkShader

[forcetransparent]
# Same as forcefallback but hides the object (for particles/effects).

[fallback]
# Specific materials to replace with the solid fallback shader.
mat:some_material_name
suffix:_glow          # matches any material ending with _glow

[transparent]
# Specific materials to make invisible.
mat:some_particle
suffix:Trail

[original]
# Specific materials to leave completely untouched.

[default]
fallback              # or: transparent, original

Files are reloaded automatically when changed. Run shaderhelper sweep to apply immediately.

Legacy DLL list files

Also located at BepInEx/config/ShaderHelperForMac/. These apply a single action to all broken-shader materials in a mod.

File Effect
usetransparentshader.txt Makes all broken-shader materials in the mod invisible.
usefallbackshader.txt Replaces all broken-shader materials with a solid visible placeholder.
useoriginalshader.txt Leaves the mod's shaders completely untouched.

One DLL name per line (without .dll), case-insensitive. Lines starting with # are comments.


Console Commands

Open the in-game console with F5.

Fixing pink shaders

Command Description
shaderhelper sweep Re-run the material sweep immediately. Reloads config files first. Shows a HUD notification when complete.
shaderhelper reload Reload all config files without running a sweep.
shaderhelper initmod <DllName> Auto-generate a starter txt file for a mod based on what the plugin has already seen.
shaderhelper initmod <DllName> force Regenerate the txt file even if one already exists.

Diagnosing pink shaders

Command Description
shaderhelper nearby [radius] Log all materials on objects within radius units (default 30). Shows shader name, support status, action, and DLL. Best tool for identifying pink objects you can see.
shaderhelper nearby [radius] mod Same as above but filters out vanilla Valheim/Unity shaders — only shows mod materials.
shaderhelper nearby [radius] <DllName> Same as above but filtered to a specific mod's DLL.
shaderhelper pink Log all materials with unsupported shaders that currently have no fix rule.
shaderhelper loaded [DllName] Log all materials in memory, optionally filtered to a specific DLL. Finds prefab assets that haven't been placed in the scene yet.
shaderhelper scan <DllName> Log all loaded materials attributed to a specific DLL with shader name and support status.
shaderhelper dumpmod <DllName> List all shader names the scanner recorded for a specific DLL.
shaderhelper status Show plugin state — fallback shader, config counts, loaded rules.
shaderhelper shaders Dump all shader objects in memory with names and support status.
shaderhelper renderers Dump materials from active scene renderers only (faster than loaded).
shaderhelper all Dump all materials in memory (both supported and unsupported).

Troubleshooting

Objects are still pink

Stand near the pink objects and run shaderhelper nearby 15. Check BepInEx/LogOutput.log — it shows every nearby material with its shader name and action. If the action is Original, that material has no fix rule yet. Add a mat: entry to the appropriate mod's txt file and run shaderhelper sweep.

If the shader shows isSupported=True but still renders pink, add the shader name prefix to [forcefallback] in that mod's txt file.

Objects that should be visible are transparent

The plugin made them invisible because their shader was broken. Find the material name from shaderhelper nearby and add mat:MaterialName to [fallback] in the mod's txt file. Run shaderhelper sweep to apply.

A mod looks wrong after being set to fallback (flat color, no textures)

Expected — the fallback shader has no textures. This is a compatibility placeholder. Correct visuals require the mod author to recompile with Metal support.

I don't know which DLL a mod uses

Look in BepInEx/plugins/. The .dll filename without the extension is what to use. If a mod bundles its shaders inside the DLL itself (rather than a separate bundle), the scanner may report it as a large embedded bundle — in that case, dll='unknown' is expected and per-material mat: rules in the txt file still work.

The plugin seems slow at startup

The scanner reads all mod bundles at launch. With many large mods this takes a few seconds. The log shows [N/total] 'ModName' — X shader(s) lines as it progresses.


Why It May Not Always Work

  • Bundle byte layout varies by Unity version. The plugin reads shader names directly from the raw bundle binary. Different Unity versions and build tools place data at different byte offsets. If the layout doesn't match a known pattern, the shader's name can't be read — DLL-based attribution won't apply to it.

  • shader.isSupported is not always accurate. Some shaders report isSupported = true while still rendering pink on Metal. Use [forcefallback] in a mod's txt file to force replacement of these.

  • Shaders loaded after startup are not always caught immediately. The plugin sweeps at scene load, after ZNetScene.Awake, after DungeonGenerator.Generate, and when items are equipped. Shaders that appear between these points may stay pink until the next sweep. Run shaderhelper sweep in the console to force an immediate re-sweep.

  • Valheim's own shaders exist in both the game and mod bundles. Shaders like Custom/Piece and Custom/Creature are built into the game with Metal support, but mod bundles often ship their own copies without Metal support. The plugin distinguishes these using instance IDs captured at startup.

  • The fallback shader carries no textures. When a material is replaced with the fallback, it renders as a solid flat color with no textures, normal maps, or emission. This is a compatibility shim — correct visuals require the mod author to recompile their shaders with Metal support.

  • Some mods manage shader replacement themselves. Mods using Jotunn's JVLmock_ system replace their own shaders at runtime. The plugin is aware of these and skips them. Other mods doing custom runtime replacement may conflict — add them to useoriginalshader.txt.


How It Works

At startup the plugin:

  1. Scans all .dll and .bundle files in BepInEx/plugins/ for shader names, recording which DLL each shader came from.
  2. Captures a baseline of all materials in memory before mod prefabs load, so vanilla materials are never touched.
  3. Selects a fallback shader — tries Custom/Piece, Custom/Creature, Custom/Vegetation in order, using the first one supported on Metal.
  4. Records canonical Valheim shader IDs — to distinguish the game's own supported copies from unsupported bundle copies of the same name.
  5. Installs Harmony patchesZNetScene.Awake, DungeonGenerator.GenerateDungeon, and VisEquipment.AttachItem postfixes trigger sweeps when new objects are spawned; AssetBundle.LoadAsset intercepts materials the moment a bundle is loaded; Shader.Find intercepts runtime shader lookups.
  6. Sweeps all loaded materials on every scene load and periodically on a configurable timer, applying replacements based on config files.