keijiro / Pcx

Point cloud importer & renderer for Unity
The Unlicense
1.36k stars 197 forks source link

Shaders does not work for Single Pass Stereo rendering (VR) #66

Open elwes opened 3 years ago

elwes commented 3 years ago

Would love to use this in VR. But to make it work with single pass stereo rendering the shaders would need some changes. Does anybody know a fix for that? I know it will work for multi pass stereo rendering, but that will be not really the way to go for VR.

No idea right now how to change the shader and make it work. This would be the reference for what I am talking about: https://docs.unity3d.com/Manual/SinglePassStereoRendering.html

annapompermaier commented 3 years ago

did you find a solution for this? have the same problem here!

keli95566 commented 3 years ago

any update please?

keijiro commented 3 years ago

I don't have any VR device for testing (I'm still WFH for the COVID situation).

keli95566 commented 3 years ago

Hi there, thank you for responding! At the moment, if I deploy it on Hololens, I only see the point cloud from the left lens. No rendering from the right lens

ruiying commented 3 years ago

followed unity instruction on single pass instanced rendering adapted bee's shader singleDisk.zip

elwes commented 3 years ago

It works! Just tested with Unity 2019 and 2020 on Win10. Thanks a lot for this!

Camille-FM commented 3 years ago

It works! Just tested with Unity 2019 and 2020 on Win10. Thanks a lot for this!

@elwes can you please specify what settings you are using to get that working? For Player settings but also the shaders. You took ruiying's singleDisk.cginc and changed Disk.shader to reference this file in the #include lines?

I am using an Oculus Quest 2 so in XR Plug-in Management have the Stereo Rendering Mode set to Multiview. I'm not entirely sure if my issues right now are due to lag of the large point cloud or if I've got these settings wrong. It renders in the Oculus but is quite laggy, the screen only updates once every few seconds so despite the tracking being fine I can see black around the image as if it's just an image I'm looking at in VR, while my head moves around it sees black around it.

ruiying commented 3 years ago

the shader we are talking about here is for "single pass instanced" rendering mode. the lagging happens on the bee? or your own large scale data?

elwes commented 3 years ago

@CamilleFirstMode I replaced the code from Disk.cginc with the code of singleDisk.cginc. Just copy/paste. Since I work on a PC with SteamVR-Unity-PlugIn (Unity 2020 and openXR) and set "Settings->XR Plug-in Managment->OpenVR->Stereo Rendering Mode->Single Pass Instanced".

Right now I can not help with the Quest2 (I have only a Quest1 and no time to set up something for it). The size of the disks is very relevant and will affect the performance a lot. The bigger you make the disks, the worse the performance becomes. I think this might be the same on Oculus/Android. Multiview on Android or Single Stereo Instance on PC will save performance on the CPU but not on the GPU. This is indeed something you want to have on the Quest/Quest2.

Maybe to test the performance, you could try to use a different shader. Open one of the pxc-demos (e. g. Bee) and change the shader from "Point Cloud/Disk" ot "Particle/Standard Unlit". "Color Mode" -> Additive and "Albedo"-Color -> black. This shader will also work with Stereo Pass Instanced and I guess it will work with Multiview on the Quest2. Would love to hear, if this is working better or if you still have bad performance.

I tested some point cloud models on sketchfab but I could not get them to work with the Quest in VR-mode: https://sketchfab.com/search?q=point+cloud&sort_by=-relevance&type=models

But this might not really tell anything about how this would run in a Unity-App.

StephenHodgson commented 4 weeks ago
// Pcx - Point cloud importer & renderer for Unity
// https://github.com/keijiro/Pcx

Shader "Point Cloud/VR Point"
{
    Properties
    {
        _Tint("Tint", Color) = (0.5, 0.5, 0.5, 1)
        _PointSize("Point Size", Float) = 0.05
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct Attributes
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 color : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 color : COLOR;
                float psize : PSIZE;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            half4 _Tint;
            float _PointSize;

            v2f vert(Attributes v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_OUTPUT(v2f, o);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.psize = _PointSize;
                o.color = v.color * _Tint;
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
                return i.color;
            }

            ENDCG
        }
    }
}

Works for OpenGL, Vulkan & Metal as well with AR Foundation