#Obtaining list of RenderFeatures assigned to current RenderAsset

1 messages · Page 1 of 1 (latest)

stark inlet
#

Hello,

I was unable to find any API for obtaining the list of RenderFeatures curently added to the active RendererData. I found some posts regarding using reflection to do the job, however.

Is that still the only option for getting the RenderFeatures at runtime?

My current code is following:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static List<ScriptableRendererFeature> GetRendererFeatures(int rendererIndex = 0)
{
    // Get desired pipeline asset
    var renderer = (GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset)?.GetRenderer(rendererIndex);
          
    // Get the rendererFeatures property
    var property = typeof(ScriptableRenderer).GetProperty("rendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance);
              
    // Return the list of ScriptableFeatures
    return property?.GetValue(renderer) as List<ScriptableRendererFeature>;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetRenderFeatureInstance<T> (List<ScriptableRendererFeature> featureList) where T : ScriptableRendererFeature
{
    if (featureList == null)
        return null;

    foreach (var feature in featureList)
    {
        if (feature is T desiredFeature)
        {
            return desiredFeature;
        }
    }

    return null;
}
bronze wren
# stark inlet Hello, I was unable to find any API for obtaining the list of RenderFeatures c...

If you need a specific instance, the easiest way is to just make a public/serialised field of the feature's type and assign it in the inspector.

Though depending on the way the feature was written, changing fields might not affect anything if the values were passed directly to ScriptableRenderPass constructor.
I tend to always have serialised fields on the feature in a separate "Settings" class to workaround that.

e.g.

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class SomeScript : MonoBehaviour {

    public MyCustomRendererFeature feature;

    public void SetMaterial(Material material, int passIndex){
        feature.settings.overrideMaterial = material;
        feature.settings.overrideMaterialPass = passIndex;
    }

}
#

Could also be an array if you need multiple references, i.e. if the feature is assigned to multiple Renderer assets per camera / quality setting

#

Or use a ScriptableObject to hold the settings and have the feature & scripts expose a field to reference that

stark inlet
#

Thanks. I was primarily looking for way to automatically find the instance, so I wouldn't have to assign it manually (I prefer to use OnValidate to handle the references for me), because sometimes after restarting the Editor, the field was strangely unset.

The reflection method is the only one I found when searching for it, since there doens't appear to be a public API for getting the RenderFeatures.

As of now, I'm only interested in having a singleton of the RenderFeature (since it applies the effect per-object, depending on its public property - Renderer array), but creating a separate function for getting all instances of given type of RenderFeature can be added easily.