Search Unity

VR, Raymarching, Graphics.blit and custom render textures

Discussion in 'AR/VR (XR) Discussion' started by HamtaroDeluxe, Jun 16, 2018.

  1. HamtaroDeluxe

    HamtaroDeluxe

    Joined:
    Jun 16, 2018
    Posts:
    11
    Hello everyone :)
    I'm working on implementing some raymarching in VR to be displayed and blended over the actual camera.
    The raymarching itself is working well in VR. I render the raymarching image into a custom render texture (2 actually, one for each eye), during update, and then mix theses with the actual scene, calling Graphics.blit() during OnRenderImage().

    For very high framerate (>120 fps) it works well.
    For lower but acceptable framerate ( 90 fps), which I'm targeting, the raymarching it self still looks good. Scripted rotation and movement passed to the raymarching shader are smooth.
    But, still on 90 fps, head rotations create some weird rumble, like if the raymarching image where struggling to follow the head movement. Actually, it has nothing to do with the raymarching itself because a screen space circle, drawn using this same technique, still behave weird on head rotations.
    I think it has to do with some anticipation or some trick (image reprojection) of the headset, that are applied differently on the final blited image and on the pre-blit render.

    Instead of blit, I tried to display my raymarching using a camera space UI. The problem disappear. So I believe It has something to do with the place of the blit in the rendering pipe...

    I can't acces my project right now; but the shader I'm using in blit is a very basic post processing shader for alpha blending that read left or right texture depending on eye index.

    So any help would be appreciated... Thank you very much :)
     
    Last edited: Jun 18, 2018
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    In the past I tried raymarching in VR (Occulus Rift) and as far I remember, I have no problem related with topic (only framerate was quite low, caused by complex pixel shader algorithm).

    Here is my deconstructed code for Graphic.Blit, it maybe useful:

    Code (CSharp):
    1. //see more: https://github.com/przemyslawzaworski/Unity3D-C-programming
    2.  
    3. //copy source render texture to destination, with material
    4.  
    5. using UnityEngine;
    6.  
    7. public class blit : MonoBehaviour
    8. {
    9.     public RenderTexture Source;
    10.     public RenderTexture Destination;
    11.     public Material ExternalMaterial;
    12.    
    13.     protected Material InternalMaterial;
    14.        
    15.     void Blit(RenderTexture source, RenderTexture destination)
    16.     {
    17.         if (!InternalMaterial) InternalMaterial = new Material(Shader.Find("Sprites/Default"));
    18.         RenderTexture.active = destination;
    19.         InternalMaterial.SetTexture("_MainTex", source);
    20.         GL.PushMatrix();
    21.         GL.LoadOrtho();
    22.         InternalMaterial.SetPass(0);
    23.         GL.Begin(GL.QUADS);
    24.         GL.MultiTexCoord2(0, 0.0f, 0.0f);
    25.         GL.Vertex3(0.0f, 0.0f, 0.0f);
    26.         GL.MultiTexCoord2(0, 1.0f, 0.0f);
    27.         GL.Vertex3(1.0f, 0.0f, 0.0f);
    28.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    29.         GL.Vertex3(1.0f, 1.0f, 1.0f);
    30.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    31.         GL.Vertex3(0.0f, 1.0f, 0.0f);
    32.         GL.End();
    33.         GL.PopMatrix();      
    34.     }
    35.    
    36.     void Blit(RenderTexture source, RenderTexture destination, Material mat)
    37.     {
    38.         RenderTexture.active = destination;
    39.         mat.SetTexture("_MainTex", source);
    40.         GL.PushMatrix();
    41.         GL.LoadOrtho();
    42.         GL.invertCulling = true;
    43.         mat.SetPass(0);
    44.         GL.Begin(GL.QUADS);
    45.         GL.MultiTexCoord2(0, 0.0f, 0.0f);
    46.         GL.Vertex3(0.0f, 0.0f, 0.0f);
    47.         GL.MultiTexCoord2(0, 1.0f, 0.0f);
    48.         GL.Vertex3(1.0f, 0.0f, 0.0f);
    49.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    50.         GL.Vertex3(1.0f, 1.0f, 1.0f);
    51.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    52.         GL.Vertex3(0.0f, 1.0f, 0.0f);
    53.         GL.End();
    54.         GL.invertCulling = false;
    55.         GL.PopMatrix();      
    56.     }
    57.    
    58.     void Update ()
    59.     {
    60.         Blit(Source,Destination,ExternalMaterial);
    61.     }
    62. }
    See also:
    https://forum.unity.com/threads/converting-a-shadertoy-multipass-shader-to-unity-hlsl.418238/
    where is long discussion about raymarching and render textures.
     
  3. HamtaroDeluxe

    HamtaroDeluxe

    Joined:
    Jun 16, 2018
    Posts:
    11
    Hey :) Thank you for that thread.
    Looking at your code, I did something similar but updating a custom render texture with it's update() method. I suppose you are calling a blit during OnRenderImage to display your render texture at the end ?
    Some extra informations :
    Actually, I did more VR post processing effects using that "organisation" with render textures, but not doing raymarching at all, and had the same jitter.
    I'm using a microsoft mixed reality headset. The problem didn't seem to occur on a HTC Vive, or at a way less noticeable level.