我的表面着色器中需要三角形信息吗?

时间:2018-10-04 17:59:20

标签: unity3d graphics shader shaderlab

更新

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

这是原始问题:

我正在为三角形网格编写表面着色器。我为每个顶点设置了一个带有纹理ID的自定义顶点属性。现在,我希望曲面着色器应用纹理,如下图所示。 (请注意,每种颜色都代表一种纹理) enter image description here

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

  1. 如果所有纹理id都相同,则为所有像素选择该纹理。
  2. 如果一个或两个纹理ID不同,我将计算到三角形顶点的像素距离,然后选择纹理,如下图所示: enter image description here

表面着色器需要注意像素三角形。按照这种逻辑,我应该得到想要的阴影。我正在以编程方式创建我的网格,以便可以将三角形顶点及其纹理ID添加为顶点属性,并将其传递到曲面着色器。

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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坐标。这种解决方案使我能够轻松地更改边缘并使边缘更粗糙。