Learn how to set and use the Renderer Shader User Value (RSUV) through an example.
To set the value, you have to write a script.
The following example sets a random color to all MeshRenderer of the sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary, encoded as a 24-bit integer:
MeshRenderer[] allMeshRenderers = FindObjectsByType<MeshRenderer>(FindObjectsSortMode.InstanceID);
foreach (MeshRenderer meshRenderer in allMeshRenderers)
{
// compute a random color
Color32 c = Color.HSVToRGB(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0.6f, 1.0f), UnityEngine.Random.Range(0.6f, 1.0f));
// set it as a LDR color in the RSUV value of the renderer
uint cc = ((uint)c.b << 16) | ((uint)c.g << 8) | ((uint)c.r << 0);
meshRenderer.SetShaderUserValue(cc);
}
Once you’ve set the value, you can use it in shaderA program that runs on the GPU. More info
See in Glossary code or in a shader graph. You can also use it with Entities Graphics.
In shader code, you can decode the 24-bit integer as a float4 color. For example:
uint c = unity_RendererUserValue;
float4 mycolor = float4((float)((c >> 0) & 255) * (1.f / 255.f),
(float)((c >> 8) & 255) * (1.f / 255.f),
(float)((c >> 16) & 255) * (1.f / 255.f),
(float)1.f);
In a shader graph, you need to create a custom node with an HLSL function.
For example:
Create a custom node by reflection from HLSL with the following function and hints:
#include "ShaderApiReflectionSupport.hlsl"
///<funchints>
/// <sg:ProviderKey>DecodeRsuvColor</sg:ProviderKey>
/// <sg:DisplayName>Decode RSUV Color</sg:DisplayName>
/// <sg:SearchName>Decode Color</sg:SearchName>
/// <sg:SearchCategory>RSUV</sg:SearchCategory>
///</funchints>
UNITY_EXPORT_REFLECTION
float4 DecodeRsuvColor()
{
uint c = unity_RendererUserValue;
float4 mycolor = float4((float)((c >> 0) & 255) * (1.f / 255.f),
(float)((c >> 8) & 255) * (1.f / 255.f),
(float)((c >> 16) & 255) * (1.f / 255.f),
(float)1.f);
return mycolor;
}
In Shader Graph, select RSUV > Decode Color to add the node reflected from the function.
Connect the Decode Color node’s Out port to the Fragment’s Base Color input.
You can also use the RSUV feature along with Unity’s Entities Graphics package.
The following code example assigns a distinct RSUV value to all entities that include a MaterialMeshInfo component.
using Unity.Entities;
using UnityEngine;
using Unity.Rendering;
using Unity.Burst;
[MaterialProperty("unity_RendererUserValuesPropertyEntry")]
public struct RendererUserValue_BaseValue : IComponentData
{
public uint Value;
}
[BurstCompile]
public partial struct MaterialMeshInfoDebugSystem : ISystem
{
private bool m_done;
public void OnCreate(ref SystemState state)
{
m_done = false;
}
public void OnUpdate(ref SystemState state)
{
if ( !m_done )
{
var entityManager = state.EntityManager;
var mQuery = entityManager.CreateEntityQuery(ComponentType.ReadOnly<MaterialMeshInfo>());
// subscene may not be fully loaded, so wait for some entities to be here
if (!mQuery.IsEmpty)
{
using (var entities = mQuery.ToEntityArray(Unity.Collections.Allocator.Temp))
{
foreach (var entity in entities)
{
Color32 c = Color.HSVToRGB(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0.6f, 1.0f), UnityEngine.Random.Range(0.6f, 1.0f));
uint cc = ((uint)255<<24) | ((uint)c.b << 16) | ((uint)c.g << 8) | ((uint)c.r << 0);
entityManager.AddComponentData(entity, new RendererUserValue_BaseValue { Value = cc });
}
}
m_done = true;
}
}
}
}