更改着色器Unity3D中图块的平面

问题描述 投票:0回答:1

首先,我会解释。我正在编写2D游戏,添加了法线贴图和照明。所有物体都躺在同一平面上。结果,墙壁的行为不当,字面意思是躺在地板上。是否可以编写这样的着色器来替换此墙的坐标,就好像它在另一个平面中一样,垂直于其所在的平面,然后再进行处理?

当前平面:

enter image description here

所需平面:

enter image description here

unity3d shader light
1个回答
0
投票

根据我的理解,您希望将瓷砖平放在地面上,但是希望对其进行阴影处理,使其看起来像是直立的,光线会从一定角度照射到瓷砖上。

存在三种可能的解决方案。第一种选择是将法线倾斜到法线贴图中进行烘焙。考虑这个球体的法线贴图:

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

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

这是旋转矩阵的构造方式:

enter image description here

在着色器中,您可以这样定义矩阵:

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;
© www.soinside.com 2019 - 2024. All rights reserved.