【问题标题】:Managing Vertex / Face color on Geometry (r71 vs r73)管理几何上的顶点/面颜色(r71 vs r73)
【发布时间】:2016-02-12 21:56:41
【问题描述】:

我正在尝试在我的应用程序中升级 ThreeJS 的发布版本。我在 3D 场景中展示了一些网格,并允许用户设置他们的颜色映射。网格可以通过两种方式着色,按顶点或按面。

在创建网格的材质时,我将 vertexColors 属性设置为 THREE.VertexColors 或 THREE.FaceColors,具体取决于我想要的行为。

在rev71上,我实现了这样的颜色变化:

var geometry = mesh.geometry;
/* For each face, change it's face colour or vertex colour */
for(var i = 0; i < geometry.faces.length; i++) {
    if (colourFace) {
        geometry.faces[i].color = myColorFace;
    } else {
        geometry.faces[i].vertexColors =
            [myColorVert1, myColorVert2, myColorVert3];
    }
}

每次我更改网格的当前映射时,它都会在场景中更新。

在 rev73 上,ThreeJS 似乎只更新了第一个映射更改(就在 Mesh 和它的 Geometry 被推送到 GPU 之前)。我得到的唯一线索是 WebGLGeometries 上的这些行:

/* ... */
} else if ( geometry instanceof THREE.Geometry ) {
    if ( geometry._bufferGeometry === undefined ) {
        geometry._bufferGeometry =
            new THREE.BufferGeometry().setFromObject( object );
    }
    buffergeometry = geometry._bufferGeometry;
}
/* ... */

然后,WebGLRenderer 使用 buffergeometry 属性来更新 WebGL 数组缓冲区(在我的例子中是颜色缓冲区)。似乎从网格更新几何时,它永远不会为 WebGLGeometry 更新。

有人有解决方案吗?或者我应该发布问题或拉取请求来解决问题吗?

【问题讨论】:

  • 试试 r.74。也不要使用= 重新分配颜色,而是使用copy()set()
  • 在应用更改后仍然无法在 rev73/74 上工作,我快速查看了 ThreeJS 代码,似乎在 WebGLGeometry 上创建了 BufferGeometry 以便将其发送到 GPU 之后,这个 BufferGeometry 是修改关联的几何图形时从不更新。
  • 您是否设置了必要的needsUpdate 标志?否则,请通过编辑 this fiddle 提供一个简单的问题示例。代码片段是不够的。

标签: three.js


【解决方案1】:

正如我在评论中所说,您不能重新分配颜色(使用=),您必须使用copy()set() 更改颜色。更改颜色时还需要设置colorsNeedUpdate 标志。

使用您的示例,首先创建几何图形,并在渲染之前实例化顶点颜色数组:

for (var i = 0; i < size; i++) {

    face = faces[i];
    var color = new THREE.Color( 1, 0, 1 );
    face.vertexColors = [ color, color, color ];

  }

渲染后,像这样更新颜色:

for (var i = 0; i < size; i++) {

    face = faces[i];
    var color = new THREE.Color().setHSL( (i / size) * 0.8, 1.0, 0.5 );
    // change colors
    face.vertexColors[ 0 ].copy( color );
    face.vertexColors[ 1 ].copy( color );
    face.vertexColors[ 2 ].copy( color );

}

mesh.geometry.colorsNeedUpdate = true;

小提琴:http://jsfiddle.net/akmcv7Lh/29/

three.js r.74

【讨论】:

  • 好的,它正在工作,谢谢 :) 我试图更好地了解 ThreeJS 如何与 WebGL 一起工作,但似乎我还需要很长时间才能做到这一点:o
  • 使用调试器单步执行three.js 源代码是正确的。这是开始拥抱它的好方法。
【解决方案2】:

添加/删除 setTimeout 以查看更改:http://jsfiddle.net/akmcv7Lh/28/

setTimeout(function() {
  for (var i = 0; i < size; i++) {
    face = faces[i];
    var color = new THREE.Color().setHSL((i / size) * 0.8, 1.0, 0.5);
    face.vertexColors = [color, color, color];
  } 
}, 1000);

当您在添加网格后的下一次渲染调用之前修改颜色时(即没有超时),它可以工作。

在下一次渲染调用后修改颜色时,它不起作用。

我深入研究了 ThreeJS 代码,发现几何用于生成 DirectGeometry,然后将 BufferGeometry 推送到 GPU。几何体修改后 DirectGeometry 没有更新。查看第 333 行的https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js

BufferGeometry 似乎已正确更新为 DirectGeometry,但 DirectGeometry 仅创建一次且从未更新。我成功破解了 ThreeJS 以进行测试,并在需要时更新 DirectGeometry,一切正常。

我考虑发送一个拉取请求,但我不确定我是否会遵循 ThreeJS 的概念规则。至少有 2-3 种方法可以解决问题,但也许我没有正确使用这些功能;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多