Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 使用自定义着色器的NPR边缘检测_Three.js_Shader_Edge Detection_Npr - Fatal编程技术网

Three.js 使用自定义着色器的NPR边缘检测

Three.js 使用自定义着色器的NPR边缘检测,three.js,shader,edge-detection,npr,Three.js,Shader,Edge Detection,Npr,我尝试在着色器中实现边缘检测,以在Three.js中实现非照片级真实感的“轮廓”效果,方法如下:。我主要对深色轮廓感兴趣,而不是古奇阴影。我理解这段代码中采用的方法,即首先使用对象空间法线渲染模型,然后对该图像使用Canny边缘检测(经过一些过滤),最后反转以获得轮廓图像。然后,该轮廓图像与场景的常规(“漫反射”)渲染相乘 但是,在本例中,为了实现两种渲染(一种用于边缘,另一种用于漫反射图像),作者复制了主几何体并在两个不同场景中创建了两个网格,以便分别应用两种不同的材质(一种仅基于法线渲染,另

我尝试在着色器中实现边缘检测,以在Three.js中实现非照片级真实感的“轮廓”效果,方法如下:。我主要对深色轮廓感兴趣,而不是古奇阴影。我理解这段代码中采用的方法,即首先使用对象空间法线渲染模型,然后对该图像使用Canny边缘检测(经过一些过滤),最后反转以获得轮廓图像。然后,该轮廓图像与场景的常规(“漫反射”)渲染相乘

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

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;
    } 
}) 
但我总是会遇到同样的错误,我不知道如何追踪导致这些错误的对象

因此,我的问题是:是否有一种很好的方法可以过滤掉没有特定属性的对象(例如法线),即使其中一些对象是
网格
而不是
缓冲几何体

谢谢你的帮助

编辑:我已经删除了关于替代方法的部分,并在这里开始了一个单独的问题:


NormalShader的代码,供参考:

THREE.NormalShader = {

    uniforms: {
    },

    vertexShader: [

        "varying vec3 vNormal;",

        "void main() {",
            "vNormal = normalize(normal);",
            "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",

        "}"

    ].join("\n"),

    fragmentShader: [

        "varying vec3 vNormal;",
        "void main(void) {",

          "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, 1.0 );",
        "}"

    ].join("\n")

};