0

我不知道如何克服三个渲染器的潜在限制,并希望有人可能有一个很好的设计来最好地克服这个问题。

假设您使用网格对象创建了一个场景并将基本材质应用于它们。因为您已经使用基本材质创建了对象,所以几何体将永远不会为其生成法线,因为基本材质不需要它。(以及大多数其他属性)。

假设我现在想再次渲染场景(用于后期处理),但这次我在渲染器上使用了覆盖材质。此覆盖材质是着色器材质,它确实需要法线。

渲染场景时,渲染器将应用覆盖材质,但它会抛出无效指针错误,因为新着色器需要普通属性但网格几何体没有任何属性,因为它是使用基本材质创建的。

那么我如何才能实现第二次渲染通道呢?第一次渲染必须使用基本材质,因为任何更多的东西都是多余的,可能会减慢应用程序的速度。第二遍必须包含法线作为其渲染后期处理效果的重要信息。我不能每次都在材质或几何体上调用 needsUpdate 作为渲染循环的一部分,并且必须在每帧重建它们将非常昂贵。

那么我该如何处理呢?甚至可能吗?显然,一个答案是我必须首先使用 phong 材料才能生成法线。但在只需要基本着色器和材质的复杂场景中,这可能非常昂贵。

任何帮助将不胜感激。

谢谢


编辑


忘了提到第二次渲染是在插件中完成的。而且它并不总是在场景之前渲染。后期处理效果可以随意添加和删除。

4

2 回答 2

0

无需经历所有的麻烦。实际上 initMeshBuffers 考虑了法线的存在或缺乏,但它们可以在事后成功计算。我在这里使用应用程序进行了基本测试,在将 MeshBasicMaterial 应用到我的模型后,我简单地调用了

geometry.computeTangents();

然后构建一个新的 ShaderMaterial 并将其应用为我的新材质。像魅力一样工作,希望有所帮助。

编辑:我应该提到这可能与上述computeVertexNormals()computeFaceNormals()依赖,哦,并且着色器材质使用法线作为我的法线贴图。

于 2013-08-21T16:09:00.027 回答
0

我能够想出一个解决方案。它可能不是最优雅的,但它确实有效。我在渲染调用之前添加了以下代码。不幸的是,函数 initWebGLObjects 在插件之前被调用,因此错过了对几何图形的任何更新。这意味着当对象材质为基本时,我必须在插件中再次手动调用 initWebGLObjects。理想情况下,我想调用 renderer.updateObject 但该函数是私有的....

//If its a basic material on a mesh, we need to make sure the object is re-built with normals
//This is to make sure when any of the post processes are rendered they have all the vertex 
//attributes they need.
var obj = webglObject.object;
if ( objectMaterial instanceof THREE.MeshBasicMaterial && obj.geometry.__builtNormals === undefined )
{
    var geometry = obj.geometry;
    geometry.__builtNormals = true;                 
    geometry.buffersNeedUpdate = true;
    geometry.uvsNeedUpdate = true;
    geometry.normalsNeedUpdate = true;

    //material.needsUpdate = true;                  
    obj.material = material;
    _renderer.initWebGLObjects( scene );
    obj.material = objectMaterial;
}
于 2013-08-22T14:26:12.283 回答