使用自定义着色器进行NPR边缘检测

时间:2014-09-29 16:33:05

标签: three.js shader edge-detection npr

我正在尝试在着色器中实现边缘检测,以在Three.js中实现非真实感的“轮廓”效果,遵循此处的方法:http://ar3f.in/goochShading.html。我主要对黑暗轮廓感兴趣,而不是Gooch阴影。我理解在这段代码中采用的方法,即首先使用对象空间法线渲染模型,然后在该图像上使用Canny边缘检测(在一些过滤之后),最后反转以获得轮廓的图像。然后将该轮廓图像与场景的常规(“漫反射”)渲染相乘。

但是,在此示例中,为了实现两个渲染(一个用于边缘,一个用于漫反射图像),作者复制主要几何体并在两个不同的场景中创建两个网格,以便分别应用两种不同的材质(一个只根据法线渲染,另一个渲染使用Gooch着色)。这种方法在我的应用程序中并不十分吸引人,因为几何图形非常大并且是动态更新的。无论如何,我想我只需在overrideMaterial上使用RenderPass来绘制所有带NormalShader的对象(下方)。不幸的是,这不起作用,因为我的一些对象是THREE.Line或其他什么,并且没有正常的属性,产生这样的错误:

WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER three.js:21636
WebGL: INVALID_OPERATION: drawArrays: attribute 1 is enabled but has no buffer bound three.js:21748
WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER three.js:21636
2[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 dev.html:1
[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 1 

我尝试在每次render调用之前使用这样的代码隐藏这些对象:

scene.traverse(function(obj) {
    if ( !!obj && obj.geometry && obj.geometry.attributes && !obj.geometry.attributes.normal ) {
        obj._visible = obj.visible;
        obj.visible = false;
    } 
}) 

但我一直得到同样的错误,我不知道如何跟踪导致它们的对象。

所以这是我的问题:是否有一种很好的方法来过滤掉没有特定属性的对象(例如法线),即使某些对象是Mesh es {{1而不是Geometry

感谢您的帮助!

编辑:我已删除了有关替代方法的内容,并在此处开始单独提问:Render "hard" edges using custom shader


NormalShader的代码,供参考:

BufferGeometry

0 个答案:

没有答案