Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Shader only rendering one eye with multiview

Discussion in 'Shaders' started by Incode, Aug 19, 2021.

  1. Incode

    Incode

    Joined:
    Apr 5, 2015
    Posts:
    77
    I'm modifying a relatively simple wireframe shader to render an object on Quest in Multiview. Not really sure what's gone wrong, as it seems like I should be outputting to stereo correctly.


    Code (CSharp):
    1. uniform float _WireThickness = 100;
    2. uniform float _WireSmoothness = 3;
    3. uniform float4 _WireColor = float4(0.0, 1.0, 0.0, 1.0);
    4. uniform float4 _BaseColor = float4(0.0, 0.0, 0.0, 0.0);
    5. uniform float _MaxTriSize = 25.0;
    6.  
    7. struct appdata
    8. {
    9.     float4 vertex : POSITION;
    10.     UNITY_VERTEX_INPUT_INSTANCE_ID
    11. };
    12.  
    13. struct v2g
    14. {
    15.     float4 projectionSpaceVertex : SV_POSITION;
    16.     float4 worldSpacePosition : TEXCOORD1;
    17.     UNITY_VERTEX_OUTPUT_STEREO
    18. };
    19.  
    20. struct g2f
    21. {
    22.     float4 projectionSpaceVertex : SV_POSITION;
    23.     float4 worldSpacePosition : TEXCOORD0;
    24.     float4 dist : TEXCOORD1;
    25.     float4 area : TEXCOORD2;
    26.     UNITY_VERTEX_OUTPUT_STEREO
    27. };
    28.  
    29. v2g vert (appdata v)
    30. {
    31.     v2g o;
    32.     UNITY_SETUP_INSTANCE_ID(v);
    33.     UNITY_INITIALIZE_OUTPUT(v2g, o);
    34.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    35.     o.projectionSpaceVertex = UnityObjectToClipPos(v.vertex);
    36.     o.worldSpacePosition = mul(unity_ObjectToWorld, v.vertex);
    37.     return o;
    38. }
    39.  
    40. [maxvertexcount(3)]
    41. void geom(triangle v2g i[3], inout TriangleStream<g2f> triangleStream)
    42. {
    43.     float2 p0 = i[0].projectionSpaceVertex.xy / i[0].projectionSpaceVertex.w;
    44.     float2 p1 = i[1].projectionSpaceVertex.xy / i[1].projectionSpaceVertex.w;
    45.     float2 p2 = i[2].projectionSpaceVertex.xy / i[2].projectionSpaceVertex.w;
    46.  
    47.     float2 edge0 = p2 - p1;
    48.     float2 edge1 = p2 - p0;
    49.     float2 edge2 = p1 - p0;
    50.  
    51.     float4 worldEdge0 = i[0].worldSpacePosition - i[1].worldSpacePosition;
    52.     float4 worldEdge1 = i[1].worldSpacePosition - i[2].worldSpacePosition;
    53.     float4 worldEdge2 = i[0].worldSpacePosition - i[2].worldSpacePosition;
    54.  
    55.     // To find the distance to the opposite edge, we take the
    56.     // formula for finding the area of a triangle Area = Base/2 * Height,
    57.     // and solve for the Height = (Area * 2)/Base.
    58.     // We can get the area of a triangle by taking its cross product
    59.     // divided by 2.  However we can avoid dividing our area/base by 2
    60.     // since our cross product will already be double our area.
    61.     float area = abs(edge1.x * edge2.y - edge1.y * edge2.x);
    62.     float wireThickness = 800 - _WireThickness;
    63.  
    64.     g2f o;
    65.  
    66.     o.area = float4(0, 0, 0, 0);
    67.     o.area.x = max(length(worldEdge0), max(length(worldEdge1), length(worldEdge2)));
    68.  
    69.     o.worldSpacePosition = i[0].worldSpacePosition;
    70.     o.projectionSpaceVertex = i[0].projectionSpaceVertex;
    71.     o.dist.xyz = float3( (area / length(edge0)), 0.0, 0.0) * o.projectionSpaceVertex.w * wireThickness;
    72.     o.dist.w = 1.0 / o.projectionSpaceVertex.w;
    73.     UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[0], o);
    74.     triangleStream.Append(o);
    75.  
    76.     o.worldSpacePosition = i[1].worldSpacePosition;
    77.     o.projectionSpaceVertex = i[1].projectionSpaceVertex;
    78.     o.dist.xyz = float3(0.0, (area / length(edge1)), 0.0) * o.projectionSpaceVertex.w * wireThickness;
    79.     o.dist.w = 1.0 / o.projectionSpaceVertex.w;
    80.     UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[1], o);
    81.     triangleStream.Append(o);
    82.  
    83.     o.worldSpacePosition = i[2].worldSpacePosition;
    84.     o.projectionSpaceVertex = i[2].projectionSpaceVertex;
    85.     o.dist.xyz = float3(0.0, 0.0, (area / length(edge2))) * o.projectionSpaceVertex.w * wireThickness;
    86.     o.dist.w = 1.0 / o.projectionSpaceVertex.w;
    87.     UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[2], o);
    88.     triangleStream.Append(o);
    89. }
    90.  
    91. fixed4 frag(g2f i) : SV_Target
    92. {
    93.     UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    94.     float minDistanceToEdge = min(i.dist[0], min(i.dist[1], i.dist[2])) * i.dist[3];
    95.  
    96.     // Early out if we know we are not on a line segment.
    97.     if(minDistanceToEdge > 0.9 || i.area.x > _MaxTriSize)
    98.     {
    99.         return fixed4(_BaseColor.rgb,0);
    100.     }
    101.  
    102.     // Smooth our line out
    103.     float t = exp2(_WireSmoothness * -1.0 * minDistanceToEdge * minDistanceToEdge);
    104.     fixed4 finalColor = lerp(_BaseColor, _WireColor, t);
    105.  
    106.     return finalColor;
    107. }
     
    Last edited: Aug 29, 2021
  2. Incode

    Incode

    Joined:
    Apr 5, 2015
    Posts:
    77
    Bump, still seems like this should be working. Running in 2020.3.2, possibly a Unity bug?