Do I need triangle information in my surface shader?

810 views Asked by At

Update

The main question is: How can I pass the world space vertex positions of the triangle to the surface shader in a Unity shader. As mentioned in a comment it might be possible to pass them from a geometry shader. But I read somewhere that implementing a custom geometry shader overwrites Unitys logic to calculate shadows etc. I would add the triangle information in the Input structure. But before I change my mesh generation logic for it I would like to know if this is feasible. For this solution the vertex positions of the triangle must be constant for every pixel in a triangle and not be interpolated.

This is the original question:

I am writing a surface shader for a triangle mesh. I set a custom vertex attribute with a texture id to every vertex. Now I want the surface shader to apply the texture as seen in the following image. (Note that each color is representing a texture) enter image description here

In the surface shader I need the 3 vertices that define the triangle and their texture ids. Furthermore I need to position of the pixel I am drawing.

  1. If all texture ids are the same I pick this texture for all pixels.
  2. If one or two texture ids differ I calculate the pixels distance to the triangle vertices and pick the texture like seen in the next image: enter image description here

The surface shader needs to be aware of the pixels triangle. With this logic I should get the shading I am looking for. I am creating my mesh programmatically so I can add the triangle vertices and their texture ids as vertex attributes and pass it to the surface shader.

But I am not sure if this is feasible with how surface/vertex shaders work. Is there a relationship between the vertex and the pixel to get my custom triangle information from? Is there a better way of doing this?

I am using Unitys ShaderLab for my shaders.

2

There are 2 answers

0
Luca Hofmann On BEST ANSWER

Ok I think I found a solution. Thank you for the comments, they where useful.

Fist I change my grid topology to not use shared vertices. With this I can use a vertex color channel to set the texture ids.

vertexColor.r = vertexTextureId0; // Texture to use for vertex 0
vertexColor.g = vertexTextureId1; // Texture to use for vertex 1
vertexColor.b = vertexTextureId2; // Texture to use for vertex 2

I do not have to worry about interpolation because all vertices of the triangle have the same color information. Now I create a texture to look up to which vertex my pixel belongs to. This texture looks similar to the images I posted in the question. I have to transpose the UV coordinates according to the TWO or THREE case. This solution gives me the freedom to easily change the edge and make it more ragged.

2
zambari On

No, you should not be (nor have acceess to) using vertex data in a fragment shader. In a fragment shader you only have access to data about that given pixel, you cannot go back and look at the mesh that formed it (this is the way the pipeline is constructed).

What you can do (and is a common practice) is to bake the data into one of the available channels (i.e. other UV Mapping channels) of the verts within the Vertex Shader. This way the Fragment shader will have access to the value via interpolators