Published Monday 3rd July 2023
In case you don't already know, I'm making an MMORPG, and in doing so I'm also learning Unity. I've been a programmer for a very long time but I'm not particularly familiar with drag and drop programming so the concept of making a scene by dragging in objects, setting them up via dialogs full of options, and only writing actual code as a last resort when the engine doesn't already offer the desired functionality still feels a bit alien to me. It's been about a year now since I first installed Unity, and of all the stumbling blocks I've come across in this time, the ones that seem to trip me up the most always relate to imported game objects, and making them look how they're supposed to via the various dialogs of settings. Unless you're using your own shaders and rendering pipelines, things feel pretty restrictive a lot of the time.
One of the first things I did when starting to develop this game, was to create a terrain with a river flowing through the middle. I created a couple of base textures to represent dirt, sand, and grass areas, and I painted the terrain with these, sinking a deep cut-out in the middle where the river would be. I then added a plane inside this cut-out and designed a custom shader for the water flow. So far, so good.
Then I designed a bridge in Blender ready to import in. My idea was to texture everything except for the top face, so that I could just replace this in Unity with the same dirt texture used for the terrain and create a seamless path over the river. I created a material in Unity, set it up to use the URP Lit shader, applied the same dirt texture and normals map as used on the terrain, and imported my bridge.
As expected, the import options let me re-map the material I'd applied to that top face in Blender, swapping out for the material I'd created in Unity to match the terrain material. I set everything up, dragged the bridge into the scene to create a prefab, positioned it appropriately across the river, and... it didn't look at all right! Awful seams where the terrain and bridge textures meet.
At this point I tried adjusting everything I could. I experimented with the Lit, SimpleLit, TerrainLit, and even non URP shaders to try and make the two textures consistent. I also considered forking the TerrainLit and/or Lit shaders to create my own, but it felt like I was missing something simple. Nothing really got me very far until somebody on Mastodon with evidently more experience than I have, mentioned that terrain normals always point upwards, which makes a lot of sense!
Terrains in Unity aren't real meshes you see, they're effectively just a plane with a height-map applied so that the renderer knows to distort the vertical position of a particular pixel, so when sculpting a terrain all that you're really doing is colouring in a height-map texture to control that distortion. Terrains have to work this way for performance but it means that they effectively only have the one face, which in turn means they only have one per-face normal and this always points up regardless of the curves of your terrain. So the lighting engine is looking at that one upward pointing normal when calculating how brightly to render a pixel. On the flip side, the imported object is a real mesh with many per-face normals pointing in all sorts of directions, so when the lighting engine hits a face on this, it's calculating a different brightness to apply and the resulting rendered texture looks completely different.
Object with default normals, rendered by the URP Lit shader differently to the terrain rendered by the URP TerrainLit shader.
Object with corrected normals, rendered by the URP Lit shader the same as terrain rendered by the URP TerrainLit shader.
In a nutshell, the fix is to make sure the per-face normals of the object all point upwards, the same as with the terrain, and then the results of the URP Lit shader will match up with the results of the URP TerrainLit shader. You're probably reading this post because you've come across this problem yourself and hit Google, so here's what to do:
These options combined with the upward pointing per-face normals should mean that the objects material now renders the same as the terrains.
Blog posts are written by individuals and do not necessarily depict the opinions or beliefs of QWeb Ltd or its current employees. Any information provided here might be biased or subjective, and might become out of date.
Nobody has commented yet.
Your email address is used to notify you of new comments to this thread, and also to pull your Gravatar image. Your name, email address, and message are stored as encrypted text. You won't be added to any mailing list, and your details won't be shared with any third party.