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

Question Im trying to write out the number of vertices seen by a camera to a texture. I set ZTest to Always

Discussion in 'Shaders' started by ZackMcracken, Aug 12, 2023.

  1. ZackMcracken

    ZackMcracken

    Joined:
    Dec 13, 2020
    Posts:
    17
    I'm trying to write out the number of vertices seen by a camera to a 1x1 texture. I set ZTest to Always but i still get zero. Here is the shader code:

    Code (JavaScript):
    1.         Tags {"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
    2.         Pass
    3.         {
    4.         Tags {"Queue" = "Geometry"}
    5.         Cull Back
    6.         ZTest Always
    7.         HLSLPROGRAM
    8.             struct Attributes
    9.             {
    10.                 float4 positionOS : POSITION;
    11.                 uint vertexID : SV_VertexID;
    12.             };
    13.             struct Varyings
    14.             {
    15.                 float4 positionHCS  : SV_POSITION;
    16.             };
    17.             uint _numVertices = 0;
    18.             CBUFFER_START(UnityPerMaterial)
    19.             CBUFFER_END
    20.             Varyings vert(Attributes IN)
    21.             {
    22.                 _numVertices++;
    23.                 Varyings OUT;
    24.                 OUT.positionHCS = TransformObjectToHClip(IN.positionOS);
    25.                 return OUT;
    26.             }
    27.             half4 frag(Varyings IN) : SV_Target
    28.             {
    29.                return half4(_numVertices / 1000, 0, 0, 1);
    30.             }
     
    Last edited: Aug 12, 2023
  2. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    177
    This will not work. Global variables are not shared between pixel and vertex shader. Event though you can transfer data from vertex to pixel shader by using interpolators, all shader invocations are independent from each other. So you cant accumulate value like that. You can use ComputeBuffer for your purpose.
     
    ZackMcracken likes this.
  3. ZackMcracken

    ZackMcracken

    Joined:
    Dec 13, 2020
    Posts:
    17
    Im trying to do the same thing but i dont pass the value to the fragment shader. I write it to a RWTexture. But i always get the value '0.1'.

    Code (CSharp):
    1.             uniform RWTexture2D<half2> _rtMinDistScalpSurfAndNumVerts : register(u3);
    2.             uint _numVerticesUnderPOV = 0;
    3.             CBUFFER_START(UnityPerMaterial)
    4.             CBUFFER_END
    5.             Varyings vert(Attributes IN)
    6.             {
    7.                 _numVerticesUnderPOV++;
    8.                 _rtMinDistScalpSurfAndNumVerts[int2(0,0)] = half2(half(_numVerticesUnderPOV) / 10, half(0.0));
     
  4. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    177
    Global variables cannot be used to pass data between vertex shader invocations. You must do the following:
    Code (CSharp):
    1.  
    2. Buffer<int> numVerts;
    3. Varyings vert(Attributes IN)
    4. {
    5.     InterlockedAdd(numVerts[0], 1);
    6.     ...
    7. }
    8.  
    Buffer is ComputeBuffer. You can use texture here but due to internal format conversions during load/store you must adhere this.
     
    ZackMcracken likes this.
  5. ZackMcracken

    ZackMcracken

    Joined:
    Dec 13, 2020
    Posts:
    17
    Thank you for your counsel brother.