Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Fluid not rendering on VR (URP) with single-pass stereo
#1
Pregunta 
I purchased and am a long time user of all of your assets (Cloth, rope, softbody) and have happily been using it even with URP until I got stuck with a unique client requirement this time.

I have a project specifically needing VR with URP, and can't get OBI fluid to render anything in standalone android builds running on Quest 3 devices.

I cannot switch from single-pass stereo to multi pass for performance reasons as this is a standalone project and not PC-VR. Been through all your VR related forums and answers suggest using Built-In for VR, which is not possible for our team's pipeline right now.

Is there ANY way I could get Fluid working on VR with URP? Desperately need help right now, as without your asset we really have no other options at all for dynamic fluid sim.

For context, we are simulating blood in a VR-based surgery scene.
Reply
#2
Solved!

What worked for me was to set the stereo render mode from class OpenXRSettings (UnityEngine.XR.Management and UnityEngine.XR.OpenXR assemblies) on runtime, courtesy of Virtual Method's support and a helpful post from another forum.

I simply switch to Multi-pass when fluid rendering is needed/visible in my scene, then switch back to single-pass instanced using event calls when done. Works great on my Quest 3 standalone  URP build on Unity 2022.3.36f1.


Code:
public class VRRenderModeSwitcher : MonoBehaviour
{
    [SerializeField] private GameObject[] multiPassCams;
    [SerializeField] private GameObject singlePassInstancedCam;

    public void SwitchToSinglePassInstanced() => SwitchMode(OpenXRSettings.RenderMode.SinglePassInstanced);

    public void SwitchToMultiPass() => SwitchMode(OpenXRSettings.RenderMode.MultiPass);

    private void SwitchMode(OpenXRSettings.RenderMode newMode) => StartCoroutine(SwitchModeCoroutine(newMode));
       
    private IEnumerator SwitchModeCoroutine(OpenXRSettings.RenderMode newMode)
    {
        var openXRSettings = OpenXRSettings.Instance;
        openXRSettings.renderMode = newMode;
        yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
    }
}


Also, for performance reasons, I additionally ended up enabling or disabling the 'ObiFluidRendererFeature' in my renderer asset on runtime as well, using the same event calls as above to enable/disable Obi rendering when needed. Below code uses reflections and is a hacky way to set renderer features, but it's the only way I found which works on current URP. This greatly boosts performance on standalone when fluid is not used:

Code:
public class SetUrpRenderFeature : MonoBehaviour
{
    [SerializeField] private string rendererFeatureNameToLookup;
       
    private static List<ScriptableRendererFeature> _rendererFeatures;

    private void Awake() => _rendererFeatures = GetRendererFeatures();

    private static List<ScriptableRendererFeature> GetRendererFeatures() {
        var renderer = (GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset)?.scriptableRenderer;
        return typeof(ScriptableRenderer)
            .GetField("m_RendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance)
            ?.GetValue(renderer) as List<ScriptableRendererFeature>;
    }

    public void EnableRendererFeature(bool enable)
    {
        foreach (var rendererFeature in _rendererFeatures
                     .Where(rendererFeature => rendererFeature.name == rendererFeatureNameToLookup))
        {
            rendererFeature.SetActive(enable);
            return;
        }
    }
}
Reply