Search Unity

Stop executing the pixel shader by a specified vertex distance to the camera?

Discussion in 'Shaders' started by Quatum1000, May 24, 2018.

  1. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi everyone,

    I' searching for a solution to stop the surf/pixel shader from executing in a surf:vertex shader to raise performance.

    I the idea is simple. If a vertex eyedepth is > than a specified distance I want to stop executing the surf/pixel shader part. I thought about to set the vertex.xyz to any illegal world position outside the camera frustum, to prevent the triangle from drawing by the gpu. But this doesn't work well because it's not possible to get the other 2 corresponding vertexes from the current drawn triangle.

    Another solution could be to calculate the vertex position based on the normals to the cam, so the plane will be positioned as a back face side to the cam.

    Does anyone have an idea how to solve, or would this impossible?
    Thank you.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It's kind of not possible for the reasons you listed. Well, it is, but not really worth it.


    You could use a geometry shader to skip whole triangles that are outside a range. But that'll probably be slower then just rendering it. It also assumes you have access to geometry shaders.

    You could use custom clipping planes, but Unity doesn't support using those.

    You could adust the output position to clip on the camera's far plane, then output the depth from the fragment shader. But that disables early depth rejection which may end up being more expensive as it's trading not rending things in the distance for rendering everything else on screen regardless of if it's behind something or not.

    You could use clip() or discard in the fragment shader, but you have to be mindful of anything that requires pixel space derivatives (most commonly texture sampling) as this will prevent clip() from actually skipping the fragment shader. Also only works on hardware with support for dynamic branching, so that rules out a lot of mobile hardware.

    You could use a compute shader to remove tris fully outside of the range. Similar to geometry shaders but should be faster ... though that requires compute shader support, and requires a lot more script side work than just applying a shader to an object.

    You could preprocess the mesh to give each tri unique vertices and encode the positions of all of the tris, or maybe just the tri's center and spherical bounds, and use that to collapse tris that are out of range, but that's going to make rendering the mesh much more expensive (probably worse than the geometry shader).

    You could break up your mesh into chunks and use something like LODs to turn off parts that are too far away.



    Or you could just let the mesh render and not worry about it.
     
    Quatum1000 likes this.
  3. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Thank you!