更改着色器Unity3D中平铺的平面

更改着色器Unity3D中平铺的平面,unity3d,shader,light,Unity3d,Shader,Light,首先,我要解释一下。我正在写一个2D游戏,添加了普通地图和灯光。所有对象都位于一个平面上。因此,墙的行为不恰当,实际上是躺在地板上。是否可以编写这样一个着色器来替换这面墙的坐标,就像它在另一个平面上一样,垂直于它所在的平面,然后再进行处理 当前平面: 所需平面: 根据我的理解,你希望瓷砖平放在地面上,但你希望它像直立一样进行着色,光线从一个角度照射到瓷砖上 有三种可能的解决方案。第一个选项是将法线倾斜烘焙到法线贴图中。考虑球面的正常映射: 青色部分朝上,紫色部分朝下。您可以从选择的角度采样颜

首先,我要解释一下。我正在写一个2D游戏,添加了普通地图和灯光。所有对象都位于一个平面上。因此,墙的行为不恰当,实际上是躺在地板上。是否可以编写这样一个着色器来替换这面墙的坐标,就像它在另一个平面上一样,垂直于它所在的平面,然后再进行处理

当前平面:

所需平面:


根据我的理解,你希望瓷砖平放在地面上,但你希望它像直立一样进行着色,光线从一个角度照射到瓷砖上

有三种可能的解决方案。第一个选项是将法线倾斜烘焙到法线贴图中。考虑球面的正常映射:

青色部分朝上,紫色部分朝下。您可以从选择的角度采样颜色,并将该颜色覆盖到法线贴图中。有一个关于如何组合法线贴图属性的教程

另一种方法是将旋转矩阵传递到着色器中,并使用它在顶点着色器中旋转法线

以下是如何构造旋转矩阵:

在着色器中,可以定义如下所示的矩阵:

float3x3 _RotMatrix;
float3 normal = UnityObjectToWorldNormal(v.normal);
o.normal = mul(normal, _RotMatrix);
在顶点着色器中,将按如下方式应用它们:

float3x3 _RotMatrix;
float3 normal = UnityObjectToWorldNormal(v.normal);
o.normal = mul(normal, _RotMatrix);
可以使用以下函数将矩阵传递到着色器:

Matrix4x4 rotMatrix = Matrix4x4.Rotate(rotation);
GetComponent<MeshRenderer>().material.SetMatrix("_RotMatrix", matrix);
Matrix4x4旋转矩阵=Matrix4x4.Rotate(旋转);
GetComponent().material.SetMatrix(“旋转矩阵”,矩阵);
或者,您可以只传递一个旋转向量并在顶点着色器中构造矩阵。无论采用哪种方法,都可以为对象设置每种材质的旋转偏移,以便在照明计算中使用

第三个选项是为平面模型设置自定义法线。您可以在网格内部执行此操作-这可能是最简单的解决方案。从“网格过滤器”中获取网格,在所有法线上循环,并使用四元数旋转它们,使它们大致朝向您希望墙朝向的方向

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;
Mesh-Mesh=GetComponent().Mesh;
Vector3[]法线=mesh.normals;

对于(int i=0;ii着色器不太可能是执行此操作的正确位置。是否有任何特殊原因表明您不只是在编辑器中调整对象的变换?它是二维的。摄影机通过z轴查看。如果我更改瓷砖的变换,摄影机将看不到该瓷砖。因此我需要更改着色器中的坐标。听起来好像您正在尝试将墙旋转为peR垂直于地板,而不实际旋转墙壁。这里需要一些说明。我需要它来更好地工作。我不需要旋转瓦拉,但光线应该位于墙壁中,因为墙壁垂直于地板。