I am trying to add road placement functionality to my game. I’ve decided to go with a splatmap approach, where the splat map defines the road locations, and the road types. I use the following shader to accomplish this:
Shader "Custom/Terrain" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
// For roads
_RoadMap ("Road Splat Map", 2D) = "white"
_RoadMapIDDirt ("Dirt Road Value", Float) = 128
_RoadDirt ("Road Dirt Texture", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
// for debugging
#pragma enable_d3d11_debug_symbols
sampler2D _MainTex;
// road stuff
sampler2D _RoadMap;
float _RoadMapIDDirt;
sampler2D _RoadDirt;
struct Input {
float2 uv_MainTex;
float2 uv_RoadMap;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
// Handle roads
// Roads are drawn using a splat map where one pixel is equivalent
// to one tile in the terrain grid.
// Color defines the road type
fixed4 road = tex2D (_RoadMap, IN.uv_RoadMap - (0.5 / 128));
if(road.a == 1) {
if(round(road.r * 255) == _RoadMapIDDirt) {
o.Albedo = tex2D (_RoadDirt, IN.uv_MainTex);
}
}
}
ENDCG
}
FallBack "Diffuse"
}
The game is grid based, and currently is 128x128 tiles, defined by a 129x129 vertex plane. _RoadMap is a 128x128 pixel texture, with filter mode point.
The problem I am having is that all of the roads are offset by 0.5 grid units, and as such they show up between tiles, not on tiles. I understand this has to do with the way UVs are sampled, and I tried to fix this (as demonstrated in the above shader). While this fixes it in the dead center of the terrain, there is still a slight offset that increases the further away from center I get:
I use the following splat map:
How could I go about getting the road to line up with the grid properly?