Search Unity

Scaling vertices in a surface shader

Discussion in 'Shaders' started by moosefetcher, Nov 30, 2016.

  1. moosefetcher

    moosefetcher

    Joined:
    Sep 23, 2015
    Posts:
    74
    I've got 2 spheres that make up the planets in the space game I'm making; One for the actual planet surface and one to represent both the background 'halo' of the planet and the cloud layer.
    Rendering the clouds on this outer sphere, puts them too far away from the surface, but I don't want to shrink the whole outer sphere because the background halo (rendered on the INSIDE of the outer sphere) looks perfect as is.
    So I thought I could 'shrink' the vertices of the mesh that have normals that point 'toward' the camera.
    First up I discovered that I have to transform the vertex to world space, perform the scaling, then transform back to eyespace. Fair enough.
    Now I am stuck on getting access to viewDir in the vert function. I need to calculate the dot product of the face normal and the view direction to check if the current vertex should be 'shrunk' slightly (making the cloud layer lower to the actual planet surface).
    So how can I access the view direction in the vert function of a Surface Shader? I'm being told that v.viewDir is not part of a struct.
    Any ideas? Thanks.
     
  2. tsangwailam

    tsangwailam

    Joined:
    Jul 30, 2013
    Posts:
    280
    You should add "float3 viewDir;" into your surface shader input structure.
    Code (CSharp):
    1. struct Input {
    2. .....
    3.    float3 viewDir;
    4. };
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You don't, you calculate it yourself.

    To calculate it in the vertex function you just need this:
    float3 viewDir = WorldSpaceViewDir(v.vertex);

    But I'm also going to suggest you don't want this at all. You just want two separate passes of the sphere, one with front culling and one with back culling. Using the view direction to detect when vertices are facing you will work, but will also destroy the silhouette of the sphere or cause odd warping as the vertices go from facing away to facing towards the camera.

    Nope. The Input struct is only accessible in the surface function as that data is calculated after the custom vertex function either in the actual vertex function (which mostly runs after the custom one) or during the fragment shader prior to the surface function being called.
     
    Last edited: Dec 1, 2016
  4. moosefetcher

    moosefetcher

    Joined:
    Sep 23, 2015
    Posts:
    74
    Thanks bgolus. I guess the next question then is 'how do I implement multiple passes'. I've encountered this as I've been learning, but I should probably start paying more attention to that aspect.
    And I did get the vertex-shrinking working but, because it was calculating at the vertex level of detail and not per fragment, the sphere surface did, indeed, 'bend' from one height to the other producing an entirely ugly look.
    So I might look at multiple passes, or just add a third sphere for the cloud layer.
    Thanks again.