How can i get sampled meshes shaders color property in VFX graph

When using a MeshRenderer / SkinnedMeshRenderer as a shape in particle system, there is an option called “Use Mesh Colors” I want to recreate this in VFX graph. I thought this option was simply just using vertex colors and my models had vertex colors, but i was wrong. My models have no vertex colors, they have the _Color property from their shaders, and it was probably using that.

Therefore when i tried to do the same thing on the VFX graph using the “Sample Skinned Mesh” node the Color output just returns black, because unlike the particle system it only checks the vertex colors, not the shader color property. Is there any way i can access the shader of the vertex, and get the _Color property?

:hushed:I wasn’t aware that it was possible to do with Shuriken.

It’s not doable out of the box in VFXGraph. VFX Graph allows you to sample a Mesh or Skinned Mesh and get a lot of information, such as the Normals, Vertex Colors, UVs, or velocity to name a few. When selecting a sample Skinned Mesh operator, you can choose what you want to get. With the UVs and a texture2D property, you can easily retrieve the BaseColor applied to Mesh with the Texture. You can find more information in this Post .

9919374--1434360--upload_2024-7-2_12-57-58.png

While getting the Mesh’s Vertex Colors makes sense to me, I must be honest and say that I’m having trouble finding a good use case for getting the Mesh Shader Color property. That being said, it’s doable with a little bit of scripting.

  • First Create a Color and SkinnedMesh exposed property.

  • Use the SkinnedMesh property to define your particle position and the Color property to define the Particle Color.
    9919374--1434369--upload_2024-7-2_13-17-50.png

  • Bind your SkinnedMesh Property to your SkinnedMesh in the Scene.

  • Add a new Script Component to your VFX.

  • Take a look at the provided code to create a solution that suits your needs.

using System.Collections.Generic;
using System.Linq;

using UnityEngine;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;

[ExecuteInEditMode]
public class VFXGetColor : MonoBehaviour
{
  
    [SerializeField] private VisualEffect visualEffect;
    [SerializeField] private bool updateEveryFrame = false;
  
    private ExposedProperty m_ColorProperty;
    private ExposedProperty m_MeshProperty;
    private bool m_HasMesh = false;
    private bool m_HasColor = false;

    void Awake()
    {

        //create and populate a list that contains all the Exposed Properties of the VFX.
        var exProps = new List<VFXExposedProperty>();
        visualEffect.visualEffectAsset.GetExposedProperties(exProps);

        /* Find the first property of type SkinnedMeshRenderer. If one is find set the m_MeshProperty with it's name.
        and Set the m_HasMesh bool to true.*/
        var exPropMesh = exProps.FirstOrDefault(x => x.type == typeof(SkinnedMeshRenderer));
        if (exPropMesh.type != null)
        {
            m_MeshProperty = exPropMesh.name;
            m_HasMesh = true;
        }
      
        /* Find the first property of type Vector4. If one is find set the m_ColorProperty with it's name.
        and Set the m_HasColor bool to true.*/
        var exPropColor = exProps.FirstOrDefault(x => x.type == typeof(Vector4));
        if (exPropColor.type != null)
        {
            m_ColorProperty = exPropColor.name;
            m_HasColor = true;
        }
      
        /*if a SkinnedMesh and a Color property have been found run  SetColor() */
        if (m_HasMesh && m_HasColor)
        {
            SetColor();
        }
    }
  

    void Update()
    {
        /*if m_HasMesh, m_HasColor and updateEveryFrame are all true,then  SetColor() */
        if (m_HasMesh && m_HasColor && updateEveryFrame)
        {
            SetColor();
        }
    }

    void SetColor()
    {
        // Get the SkinnedMeshRenderer referenced in the Founded SkinnedMeshRenderer exposed property.
        var sMesh = visualEffect.GetSkinnedMeshRenderer(m_MeshProperty);
        // Get the Color of the Shader of the SkinnedMeshRenderer.
        var meshColor = sMesh.sharedMaterial.color;
        // Set the m_ColorProperty with the SkinnedMesh Shader Color.
        visualEffect.SetVector4(m_ColorProperty, meshColor); 
    }
}

I’m far from a coding expert, so I’m pretty sure there are corner cases and issues that I didn’t consider.
The general idea of this script is the following:

  • The user references a VFX.

  • The Script creates a list with all the Exposed Properties of this VFX.

  • We’re checking if a SkinnedMesh and Color(Vector4) property are present.

  • If present we get their names.

  • We’re getting the SkinnedMesh referenced in the SkinnedMesh property

  • We’re getting the color property from its shader.

  • We’re setting the Color property with this color.

9919374--1434375--Unity_HB11Zt4ndx_0002-0151_1000x559.gif
The script in action retrieving the Shader color property to feed the VFXGraph Color exposed property

As I said, I’m not a Script expert, but I still hope that it will help you. If you could expose me to your use cases and reasons why you find this feature useful, I would be very interested. Thanks in advance and have a great day ;).

100000001218704--1121384--clear.png