关于unity shader Offset两个参数的解释

 

多边形偏移

如果要突出显示实体对象的边缘,可能会尝试使用多边形模式GL_FILL绘制对象,然后再次绘制它,但使用多边形模式GL_LINE以不同的颜色绘制。但是,因为线和填充多边形不是以完全相同的方式进行光栅化,所以为线上像素生成的深度值通常与多边形边的深度值不同,即使在相同的两个顶点之间也是如此。突出显示线可以淡入和淡出重合多边形,这有时被称为“缝合”并且在视觉上令人不愉快。

通过使用多边形偏移可以消除视觉上的不愉快,多边形偏移增加了适当的偏移以强制重合的z值,以便将多边形边缘与其突出显示线干净地分开。(第10章“模板测试”中描述的模板缓冲区也可用于消除拼接。但是,多边形偏移几乎总是比模板更快。)多边形偏移对于将贴花应用于曲面,渲染隐藏图像也很有用线删除。除了线条和填充多边形之外,此技术还可以与点一起使用。

有三种不同的方法可以打开多边形偏移,每种类型的多边形光栅化模式都有一种:GL_FILL,GL_LINE或GL_POINT。通过将适当的参数传递给glEnable() GL_POLYGON_OFFSET_FILL,GL_POLYGON_OFFSET_LINE或GL_POLYGON_OFFSET_POINT 来启用多边形偏移。您还必须调用glPolygonMode()来设置当前的多边形光栅化方法。

void glPolygonOffset(GLfloat factor ,GLfloat units );

启用后,每个片段的深度值将添加到计算的偏移值中。在执行深度测试之前和深度值写入深度缓冲区之前添加偏移。偏移值o通过以下公式计算:

o = m *因子+ r *单位

其中m是多边形的最大深度斜率,r是保证产生窗口坐标深度值的可解析差异的最小值。值r是特定于实现的常量。

为了在没有视觉瑕疵的情况下实现突出显示的实体对象的良好渲染,您可以向实体对象添加正偏移(将其推离您)或向线框添加负偏移(将其拉向您)。最大的问题是:“抵消多少就足够了?” 不幸的是,所需的偏移取决于各种因素,包括每个多边形的深度斜率和线框中线的宽度。

OpenGL为您计算多边形的深度斜率(见图6-5),但重要的是要了解深度斜率,以便为因子选择合理的值。当您遍历多边形时,深度斜率是z(深度)值的变化除以xy坐标的变化。深度值在窗口坐标中,夹在[0,1]范围内。要估计多边形的最大深度斜率(偏移方程中的m),请使用以下公式:

关于unity shader Offset两个参数的解释_第1张图片

图6-5:多边形及其深度斜率

对于与近剪裁平面和远剪裁平面平行的多边形,深度斜率为零。对于场景中具有接近零的深度斜率的多边形,仅需要小的恒定偏移。要创建一个小的常量偏移量,可以将factor = 0.0和units = 1.0传递给glPolygonOffset()

对于与剪切平面成大角度的多边形,深度斜率可以显着大于零,并且可能需要更大的偏移。因子的小的非零值例如0.75或1.0)可能足以生成不同的深度值并消除令人不快的视觉伪像。

示例6-8显示了代码的一部分,其中显示列表(可能绘制实体对象)首先使用光照,默认GL_FILL多边形模式和因子为1.0且单位为1.0的多边形偏移进行渲染。无论深度斜率如何,这些值都可确保场景中所有多边形的偏移量足够。(这些值实际上可能比所需的最小偏移量稍微偏移,但是过多的偏移量不会太明显。)然后,为了突出显示第一个对象的边缘,对象将呈现为未点亮的线框,并且偏移量已禁用。

例6-8:消除视觉伪像的多边形偏移:polyoff.c

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_POLYGON_OFFSET_FILL);
   glPolygonOffset(1.0,1.0);
   glCallList(list);
   glDisable(GL_POLYGON_OFFSET_FILL);

   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHT0);
   glColor3f(1.0,1.0,1.0);
   glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
   glCallList(list);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

在少数情况下,因子单位(1.0和1.0)的最简单值不是答案。例如,如果突出显示边缘的线条的宽度大于1,则可能需要增加因子的值。此外,由于深度值在使用透视投影时不均匀地转换为窗口坐标(请参阅第3章中的“变换深度坐标”),因此更接近近剪裁平面的多边形需要更少的偏移,并且多边形需要更多的偏移离得更远了。再一次,可能需要尝试使用因子的价值。

你可能感兴趣的:(Unity,Shader)