Насколько я понимаю, вы хотите, чтобы плитка была плоской на земле, но вы хотите, чтобы она была затенена, как если бы она стояла, и свет падал на нее под углом.
Для этого есть три возможных решения. Первый вариант заключается в том, что вы запекаете нормали как наклоненные на карту нормалей. Рассмотрим эту нормальную карту сферы:
The teal parts are pointing upwards, and the purple parts are pointing downwards. You can sample a color from an angle of your choice and overlay that color into your normal map. There is a tutorial on how to property combine normal maps здесь .
Другой метод - передать матрицу вращения в ваш шейдер и использовать ее для вращения вашей нормали в вершинном шейдере.
Вот как создаются матрицы вращения:
В шейдере вы определяете матрицы следующим образом:
float3x3 _RotMatrix;
В вершинном шейдере вы применяете их следующим образом:
float3 normal = UnityObjectToWorldNormal(v.normal);
o.normal = mul(normal, _RotMatrix);
Вы можете передавать матрицы в шейдеры, используя эту функцию:
Matrix4x4 rotMatrix = Matrix4x4.Rotate(rotation);
GetComponent<MeshRenderer>().material.SetMatrix("_RotMatrix", matrix);
Или вы можете просто передать вектор вращения и построить матрицу внутри вершинного шейдера. В любом случае, вы можете установить смещение вращения для каждого материала для ваших объектов для использования в расчетах освещения.
Третий вариант - установить пользовательские нормали для вашей модели самолета. Вы можете сделать это внутри меша - это, вероятно, самое простое решение. Возьмите сетку из фильтра сетки, обведите все нормали и поверните их, используя кватернион, чтобы они были примерно ориентированы в том направлении, в котором вы хотите видеть стену.
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] normals = mesh.normals;
for(int i=0; i<= normals.Length; i++) {
normals[i] = Quaternion.Euler(new Vector3(45, 0, 0)) * normals[i];
}
mesh.normals = normals;
mesh.RecalculateTangents();
GetComponent<MeshFilter>().mesh = mesh;