2

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

然而,在这个例子中,为了实现两种渲染(一种用于边缘,一种用于漫反射图像),作者复制了主要几何图形并在两个不同的场景中创建了两个网格,以便分别应用两种不同的材质(一种用于仅基于法线进行渲染,以及使用 Gooch 着色进行渲染)。这种方法在我的应用程序中并不是很有吸引力,因为几何图形非常大并且动态更新。没关系,我想我只需要使用 aoverrideMaterialRenderPass绘制所有带有 a 的对象NormalShader(如下)。不幸的是,这不起作用,因为我的一些对象是THREE.Lines 或其他任何东西并且没有正常属性,产生如下错误:

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;
    } 
}) 

但我不断收到同样的错误,我不知道如何追踪导致它们的对象。

所以这是我的问题:是否有一种好方法可以过滤掉没有特定属性(例如法线)的对象,即使某些对象是MeshesGeometry而不是BufferGeometry

谢谢你的帮助!

编辑:我已经删除了关于替代方法的内容,并在这里开始了一个单独的问题:使用自定义着色器渲染“硬”边缘


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")

};
4

0 回答 0