使用自定义着色器渲染“硬”边缘

时间:2014-10-03 16:23:59

标签: three.js shader

我想重现使用THREE.EdgesHelper(在“硬”对象边缘上绘制边界)创建的效果,但使用自定义着色器而不是添加单独的THREE.Line对象。基本上我想做this demo中所做的事情,但仅限于“硬”边界;例如不在两个共面面之间的边界

方法:将类似的例程应用于EdgesHelper,但使用自定义属性(例如isEdge)标记硬边中的顶点;可能需要使用BufferGeometry,因为常规Geometry允许在多个面中重复使用顶点,但BufferGeometry复制顶点,使得每个顶点只是一个面的一部分(至少,这个是我的理解;文件不明确)。

到目前为止的进展:

  1. 在线框材质示例中重现效果,但使用BufferGeometryhttp://jsfiddle.net/ogav6o77/
  2. EdgesHelper的逻辑移植到与BufferEdgesHelper一起使用的“BufferGeometry”功能(但仍然用它来创建THREE.Line):http://jsfiddle.net/L2aertya/
  3. 尝试调整BufferEdgesHelper以将结果保存在自定义属性(isEdge)中,然后在决定是否渲染边缘时在自定义着色器中读取该属性:{{3} }
  4. 前两个小提琴按预期工作,显示(1)着色器渲染的白色线框边,然后(2)着色器的白色边缘加上Line的红色“硬”边缘。但是,(3)给出与(2)相同的结果,而不是使用isEdge属性来决定是否画线;我无法弄清楚为什么会这样。

    任何想法如何解决这个问题,以便着色器渲染硬边(例如红线和白线重叠)?

    谢谢!

1 个答案:

答案 0 :(得分:3)

首先,需要稍微调整边缘修剪算法。您需要保存两个面的顶点,而不仅仅是第一个面,因为您需要更改与边相关的两个三角形,以便使用重心坐标正确渲染。

其次,我认为这可以在没有新isEdge变量的情况下完成,只需更改centers

重心坐标的常规设置是三个顶点为(1,0,0)(0,1,0)(0,0,1)。但是,如果我们不想在顶点0和1之间绘制边缘,我们可以将其更改为(1,0,1)(0,1,1)(0,0,1),这样无论距离顶点2有多远,vCenter.z总是1.然后,我们可以从centers开始填充1(禁用所有边),并在我们看到哪些边应该保留时逐个启用边。

考虑到这一点,我已经重新编写了一些代码。我剥去了边缘物体并离开了重心物:http://jsfiddle.net/v72rn4bk/4/

我发现计算法线的调用应在转换为BufferGeometry后完成。调用.fromGeometry确实会复制顶点,但如果您正在使用的对象具有共享顶点,则必须重新计算法线。