片段着色器中的“基于面部”与“基于顶点”属性

时间:2018-06-21 13:19:27

标签: three.js webgl shader

我正在 three.js 中编写一个相当复杂的 webgl 应用程序,为了更好地控制我的网格物体,我通过着色器对其进行定义。

但是,我面临一个严重的问题,无法找到任何真正令人满意的答案。让我们假设以下先决条件:

  1. 索引了我的几何图形,即顶点在面之间不重复,并且我不想更改此
  2. 几何图形存储在THREE.BufferGeometry对象中,再次我不想切换到THREE.Geometry
  3. 我不想复制面孔和/或创建新的几何形状
  4. 我不希望任何双向渲染都会降低我的帧率

鉴于上述情况,假设我点击了我的几何图形的三角形(即,发出光线并获得与该光线相交的最接近的面),我希望用不同的颜色突出显示该三角形。

我已经通过将自定义顶点属性(例如1.0分配给属于要突出显示的脸部的每个顶点)以一种非常有效的方式执行此操作。

在顶点着色器中,我定义了具有这种顶点属性的变量,并且在片段着色器中,我仅执行以下操作(伪代码):

vec4 frag_color=mix(default_color,highlight_color,(vert_attribute>1-eps));

其中eps是一个小值(例如1.0e-4)。

这个想法是,每个片段都插值其相应的顶点属性,例如Vatt_1Vatt_2Vatt_3,并且如果所有三个属性都获得值1.0,则它们的插值仍然接近1.0(并非完全由于舍入误差,这就是为什么我使用较小公差eps的原因),并且测试是正确的。

如果测试为true,我有frag_color=highlight_color

另一方面,如果至少一个Vatt_ii=1,2,3)不是1.0而是默认的0.0,则当前分片处的插值为{{1 }},测试为<1-eps(给予false)。

这似乎工作得很好,但是现在我遇到了以下看起来确实具有挑战性的问题(考虑到上面的约束1和2):

我在片段着色器中没有任何简单的方法来知道当前片段是否属于特定的面(或停留在三个特定的顶点内,这是相同的)。因此,如果我选择两个三角形frag_color=default_colorT1,并且偶然地,第三个三角形T2具有与T3共享的一个(或两个)顶点和两个(或一个)顶点与T1共享的顶点我也知道T2也被突出显示,因为它的三个顶点都具有属性T3

当然,从人类的角度来看,这不应该发生,因为1.0的三个“ 突出显示的”顶点应该“逻辑上”指的是两个不同的突出显示的面孔,但是出于明显的原因片段着色器也突出显示T3

我猜这是一个非常普遍的问题,我在很多论坛上都找不到任何令人满意的解决方案。我知道“ 这就是它的工作方式”,并且片段着色器不了解背景三角形及其顶点,但是我在这里寻找一些聪明的主意或技巧。

有人有面对这个问题的建议吗?很抱歉打扰,但只是为了防止出现一些可能的争论:我认为上述1-4点是很强的要求,因为否则我会遇到其他与整体性能有关的问题,并且我不想为此付出代价。

预先感谢

1 个答案:

答案 0 :(得分:1)

使用重心坐标可以知道点是否在三角形内。可以根据需要在顶点或片段着色器级别完成此操作。

只需获取要测试的三角形的顶点坐标,然后将当前顶点或片段的坐标转换为重心坐标即可。之后,对重心坐标值的简单测试将告诉您该点是否在三角形内。