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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Advice: Projecting lines on mesh

Discussion in 'Editor & General Support' started by JacobSabella, Mar 2, 2020.

  1. JacobSabella

    JacobSabella

    Joined:
    May 24, 2019
    Posts:
    2
    I've been researching the best way to do this for a while but I'm coming up at a loss. I'm working on an application that retrieves data on underground facilities. Currently, I'm drawing this on a flat map, coming in from Mapbox's Unity SDK to sort of visualize what's underground. I would like to be able to draw this on top of the terrain which can be generated by Mapbox, but I haven't be able to figure out how to get the lines to conform to the mesh. Previously, since I was just drawing on a flat surface, I could just get the minimum of the tile set and use that as the height.

    I've seen a few mentions of projectors, but I haven't seen a good example of how that would help me. Everything I see is usually some kind of shadow demo. Maybe I'm misunderstanding their use. The closest I've gotten so far is generating points along the mesh and using LineRenderer to make the line, but I'm afraid that this cant scale well and it tends to look rather jagged and unpleasant in general.

    I've also played around with using shaders and rendering the line under the surface and making them visible through ground. This just never really gave the impression that it was "painted on" to the mesh, and looked strange when looking at distant lines.

    Does anyone have any advice on approaching this problem?
     
  2. Gordon_G

    Gordon_G

    Joined:
    Jun 4, 2013
    Posts:
    358
    Can you come up with a representation of what you would like the end result to look like? Because given how textures are drawn to models, it's hard to imagine being able to get what you want.

    I'm no expert, but one way to do it is to project your map on to the terrain. (if that's the same as what you've seen, I don't know). I'm not sure that this would help you, but I have modified texture maps dynamically (using the texture3D drawing API) to display a hex grid that is then applied on a terrain mesh. It looks perfect looking straight down with an orthographic camera, but as soon as you view the terrain in perspective at some angle, you see how the grid lines are actually stretched way out over the slopes of the terrain. On relatively flat terrain it looks fine. That's partly issue with the number of vertices in the model - the finer the mesh the better, though there are other factors involved.

    For one, the model I created was generated from a noise map laid out on a regular grid, so extreme terrain slopes did not have the extra vertices that would be needed on the sides of the slopes. Just having a finer mesh would help, but anytime you have a rapid change in height the issue is related to a kind of "vertical sampling" of mesh vertices - a regular mesh grid won't work as well a terrain generation system where slopes actually have more vertices. It's analogous to audio representations - parts with less dynamic range don't require the same bit rate.

    There is a simple texture3d drawing API that lets you do basic shapes on a texture.

    You might take a look at Sebastian Lague's work in YouTube, and he has a series on Procedural Terrain Generation where, I think it is episode 16 or 17, he starts going through what it takes to generate a material for a terrain and prepare the mesh and project it . It's a detailed explanation, and where I got the base code for the projection shader, and terrain generation I used. It might give you some ideas.

    There is also a very comprehensive shader and texture mapping tutorial at https://catlikecoding.com/ that you should probably have a look at.
     
    Last edited: Mar 2, 2020
  3. JacobSabella

    JacobSabella

    Joined:
    May 24, 2019
    Posts:
    2
    upload_2020-3-2_15-36-13.png

    I'm getting tiles with height data like this from Mapbox. I'm wanting to basically visualize underground sewer systems by drawing them on top of the tile. I started out without terrain elevation and was just drawing them right above it using linerenderer, but of course when you add elevation it clips through it and above it etc.
     

    Attached Files:

  4. Gordon_G

    Gordon_G

    Joined:
    Jun 4, 2013
    Posts:
    358
    Is that graphic is drawn by hand and not using lineRenderer?

    Yes, with linerenderer you'd have to read through the mesh to determine where the points on the line should be with respect to your underlying model, which would be a mess of code of the top of my head, and you'd run into a similar problem that I described with the shader, where you want to plot a point that is in between vertices. The projection shader I used blends the texture between points and in such cases, and, as I wrote, that blending looks smeared where there are relatively high difference in elevation between adjacent vertices.

    OK, so maybe this approach of drawing the pixels directly on the terrain texture map could work, but to make it look decent you need a high resolution terrain models and also terrain texture maps.

    It's been a couple of years since I worked on this and I'm in the middle of something right now so I am jogging my memory. I do recall that my project was dealing with low resolution maps. I believed it uses 512 x 512 vertices and texture map pixels to match to make my hexgrid mapping simple: I wanted to draw a hex grid on the terrain texture so I had set up the terrain generator to create vertices that were hexagonally aligned. That way my hexgrid lines would align with the mesh vertices.

    I created a texturemap for the terrain mesh using Lague's tutorial. He explains creating a projection shader that uses vertex blending (or I altered it to do vertex blending - here my memory is a little fuzzy because I recall having to also alter the mesh generation code to ensure that vertices were not duplicated as his generation algorithm does - or I made a pass back through after the fact. In his mesh generation algorithm, as I recall, every mesh triangle has it's own unique set of vertices.)

    I think this is the part that is relevant to your quest: Once the terrain texture was created and applied, I made a RenderTexture from it using an orthographic camera looking down from the center of my textured mesh. In essence I took a snapshot and rendered that to another texture. I then used with the texture3D API to draw the outlines of my hexgrid over the resulting RenderTexture. The texture3D API provides a way to paint pixels on a texture, and I found this Drawing Library https://forum.unity.com/threads/bitmap-drawing-api-for-textures.251557/ to use to draw my hexgrid border lines on the rendered texture map.

    What you could do is, similarly, render a texture of your underground model from the top down (before your terrain is overlaid). Then, rather than using this texture3D drawing library that I adapted, use Graphics.Blit to combine your terrain texture and the RenderTexture snapshot you created in one command.

    I haven't used Graphics.Blit, but I believe that would combine the two textures with your lines over the terrain texture properly if you ensure that everything in the background of the RenderTexture are transparent pixels - otherwise I'm not sure why it would be called a "Blit". And I think using high enough resolution meshes and texture maps would get you closer to want and with a lot less hassle than trying to use LineRenderers.

    Here is a look at using Graphics.Blit: http://vfxmike.blogspot.com/2015/03/graphics-blitting-in-unity-part-1.html

    Again, I think to understand the projection/ vertex blending shader you should go through at least the two episodes in Lague's video that I referenced in my previous reply.
     
  5. Gordon_G

    Gordon_G

    Joined:
    Jun 4, 2013
    Posts:
    358
    I just opened my project and I guess i took care of the slope smearing issue - I was thinking of was the warping over slopes. You can notice that in these images - again, very low resolution so you see the pixels distinctly.

    Because I worked on this for a hex based game, I only draw hexes on parts of the mesh where the slope is "walkable" - I wrote code to go through the mesh and calculate slopes of adjacent mesh triangles.

    Looking down in orthographic view, you can see how perfect the low res hexes look.

    upload_2020-3-3_12-32-46.png

    Looking from the side at the same area, you can see the warping over the relatively gentle slopes.

    upload_2020-3-3_12-28-27.png

    Again, the red pixels are painted directly on to the terrain texture map. So, perhaps this is close what you are looking for - albeit at a higher resolution?
     

    Attached Files: