Home / Forums / Creating Material Replacement Chams in Unity C# (Flat, Wireframe & Visible Check)

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Source

Creating Material Replacement Chams in Unity C# (Flat, Wireframe & Visible Check)

GlowShader
Shader & Overlay Artist
MEMBER
Rep: 185
Join Date: Oct 2023
Posts: 36
Thanks: 46
2y ago · Jul 29, 2024 4:15 PM
#1
Chams (colored material replacement on 3D character meshes) make players visible through walls without any 2D overlay math.

How Chams work in Unity:
By replacing the
CSHARP
material
or
CSHARP
sharedMaterial
of the player's
CSHARP
Renderer
(or
CSHARP
SkinnedMeshRenderer
) with an unlit shader where depth testing (
CODE
_ZTest
) is disabled (
CODE
CompareFunction.Always
):

CSHARP
using UnityEngine;

public static class ChamsManager
{
    private static Material _chamMaterialOccluded;
    private static Material _chamMaterialVisible;

    public static void InitializeChams()
    {
        Shader shader = Shader.Find("Hidden/Internal-Colored");

        // Occluded (Behind Walls) - Red
        _chamMaterialOccluded = new Material(shader);
        _chamMaterialOccluded.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Greater);
        _chamMaterialOccluded.color = new Color(1f, 0.2f, 0.2f, 1f);

        // Visible (In Line of Sight) - Green
        _chamMaterialVisible = new Material(shader);
        _chamMaterialVisible.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.LessEqual);
        _chamMaterialVisible.color = new Color(0.2f, 1f, 0.2f, 1f);
    }

    public static void ApplyChams(GameObject playerObj)
    {
        if (_chamMaterialVisible == null) InitializeChams();

        var renderers = playerObj.GetComponentsInChildren<Renderer>();
        foreach (var rend in renderers)
        {
            if (rend == null) continue;
            // Apply dual-pass materials: Behind wall (Red) & Visible (Green)
            rend.materials = new Material[] { _chamMaterialOccluded, _chamMaterialVisible };
        }
    }
}
GlowShader | Shaders, Stencils & DirectX DrawLists
The following users thanked GlowShader for this post:
RustMechanic
Unity & IL2CPP Reverser
VIP
Rep: 295
Join Date: Nov 2022
Posts: 32
Thanks: 74
2y ago · Jul 29, 2024 6:40 PM
#2
Using
CODE
CompareFunction.Greater
for occluded and
CODE
CompareFunction.LessEqual
for visible is the textbook two-tone Chams setup. Works seamlessly in almost any Unity game!
RustMechanic | IL2CPP & Unity Engine Analysis
ZeroMemory
Member
MEMBER
Rep: 75
Join Date: Oct 2024
Posts: 32
Thanks: 18
2y ago · Jul 30, 2024 8:50 AM
#3
Originally Posted by @GlowShader
Behind wall (Red) & Visible (Green)

This makes distinguishing whether enemies are behind cover vs in open sight instant. Fantastic code snippet!
ZeroMemory · Always experimenting