1

更新

主要问题是:如何将三角形的世界空间顶点位置传递给 Unity 着色器中的表面着色器。正如评论中提到的,可能可以从几何着色器中传递它们。但是我在某处读到,实现自定义几何着色器会覆盖 Unitys 逻辑以计算阴影等。我将在 Input 结构中添加三角形信息。但在我改变我的网格生成逻辑之前,我想知道这是否可行。对于这个解决方案,三角形的顶点位置对于三角形中的每个像素都必须是恒定的,并且不能被插值。

这是原始问题:

我正在为三角形网格编写表面着色器。我为每个顶点设置了一个带有纹理 ID 的自定义顶点属性。现在我希望表面着色器应用纹理,如下图所示。(注意每种颜色代表一种纹理) 在此处输入图像描述

在表面着色器中,我需要定义三角形的 3 个顶点及其纹理 ID。此外,我需要定位我正在绘制的像素。

  1. 如果所有纹理 ID 都相同,我会为所有像素选择此纹理。
  2. 如果一个或两个纹理 id 不同,我会计算到三角形顶点的像素距离并选择下一张图像中看到的纹理: 在此处输入图像描述

表面着色器需要知道像素三角形。有了这个逻辑,我应该得到我正在寻找的阴影。我正在以编程方式创建我的网格,因此我可以将三角形顶点及其纹理 ID 添加为顶点属性并将其传递给表面着色器。

但我不确定这对于表面/顶点着色器的工作方式是否可行。顶点和像素之间是否存在关系以获取我的自定义三角形信息?有没有更好的方法来做到这一点?

我正在为我的着色器使用 Unitys ShaderLab。

4

2 回答 2

1

不,您不应该(也不能访问)在片段着色器中使用顶点数据。在片段着色器中,您只能访问有关给定像素的数据,您无法返回查看形成它的网格(这是构建管道的方式)。

您可以做的(并且是一种常见做法)是将数据烘焙到顶点着色器中顶点的一个可用通道(即其他 UV 映射通道)中。这样,片段着色器将可以通过插值器访问该值

于 2018-10-05T13:32:52.357 回答
0

好的,我想我找到了解决方案。感谢您的评论,它们很有用。

拳头我将网格拓扑更改为不使用共享顶点。有了这个,我可以使用顶点颜色通道来设置纹理 ID。

vertexColor.r = vertexTextureId0; // Texture to use for vertex 0
vertexColor.g = vertexTextureId1; // Texture to use for vertex 1
vertexColor.b = vertexTextureId2; // Texture to use for vertex 2

我不必担心插值,因为三角形的所有顶点都具有相同的颜色信息。现在我创建一个纹理来查找我的像素属于哪个顶点。此纹理看起来与我在问题中发布的图像相似。我必须根据两种或三种情况转置 UV 坐标。这个解决方案让我可以自由地轻松更改边缘并使其更加粗糙。

于 2018-10-14T11:26:50.867 回答