【问题标题】:ID Rendering + Diffuse Rendering in THREE.jsTHREE.js 中的 ID 渲染 + 漫反射渲染
【发布时间】:2018-10-10 03:14:34
【问题描述】:

我正在尝试使用 onBeforeRender 在我的 THREEjs 应用程序中添加一个 id 材质覆盖功能。这是渲染应用程序的一个非常常见的功能,我希望能够使用 scene.overrideMaterial 来完成它,但从我的研究来看,我似乎要自己动手了。

我的做法如下。

当我实例化对象时:

...
      m.onBeforeRender = function (){
        if(Renderer._renderID){
            this.material = new THREE.MeshBasicMaterial(this.userData.idColor.getHex());
            this.material.needsUpdate = true;

            // Attempt at using a shader material
            //this.material = Renderer._idMat;
            //this.material.uniforms.idColor.value = this.userData.idColor;
            //this.material.uniforms.needsUpdate = true;
        }
      }
      m.onAfterRender = function (){
            if(Renderer._renderID){
                this.material = this.userData.material;
            }
      }
...

在我的渲染循环中:

...
        var idTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
        Renderer._renderID = true;
        Renderer._renderer.render(Renderer._scene, Renderer._camera, idTarget);
        Renderer._renderID = false;
...

现在 id 缓冲区和漫反射缓冲区都使用漫反射材质进行渲染。

任何帮助将不胜感激。如果需要更多信息,请告诉我,我会更新这篇文章。

【问题讨论】:

  • 我不确定我是否理解了这个问题,但你真的不想在onBeforeRender 回调中的每一帧都实例化一个新材质。
  • 你的问题是什么,你能做个小提琴吗?
  • @pailhead 这种技术的一个应用是用于 GPU 拾取,您可以在其中交换正在渲染的颜色,而不是整个材质定义。这样,您只需发送一个着色器代码实例,并通过更改其制服来简单地控制每个对象的颜色(就像在尼克的代码中被注释掉的一样)。
  • 尼克,不幸的是,你是对的,你自己来实现这个。 (我做过类似的事情——一旦你理解了发生的事情就不会太难了。)如果three.js 提供了第一方实现会很方便吗?当然。但是three.js 不是一个应用程序,它在很大程度上是一个工具包,它为您提供了足够的包装器来让事情变得更容易,同时又不会对您的设计过于霸道。
  • 我必须举一个例子作为答案,这样我才能澄清我的观点。

标签: javascript three.js rendering


【解决方案1】:

Three.js 有一个官方的 gpu 选择示例,可以看到here

他们似乎在两个不同的场景中用顶点颜色渲染事物。这不是一个坏方法,我不同意评论和你注释掉的代码。改变制服不是实现这一点的唯一方法,官方示例使用顶点颜色并合并所有几何图形。

有很多方法可以给这只猫剥皮。

您应该尽一切办法避免在紧密的循环中创建新材料。

太糟糕了:

  m.onBeforeRender = function (){
    if(Renderer._renderID){
        this.material = new THREE.MeshBasicMaterial(this.userData.idColor.getHex()); //just a big NO
        this.material.needsUpdate = true; //no it doesnt! it's a new material it has this true by default

要实现这样的目标,或者您自己的自定义覆盖:

const myMesh = new Mesh()
myMesh.myMaterials = [
  someRenderMaterial,
  someIDMaterial,
]

scene.traverse(o=>{if(o.myMaterials) o.material = o.myMaterials[1]})
renderer.render(scene,camera)

scene.traverse(o=>{if(o.myMaterials) o.material = o.myMaterials[0]})
renderer.render(scene,camera)

但同样,有很多方法可以做到这一点。您可以制作另一个场景并渲染顶点颜色。您可以制作覆盖材质并渲染顶点颜色。许多参数,许多排列。

【讨论】:

  • 谢谢 - 非常感谢您的建议!我会试试这个,让你知道结果如何!
猜你喜欢
  • 2012-09-22
  • 2023-03-18
  • 2018-09-10
  • 1970-01-01
  • 2016-10-21
  • 2021-04-13
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多