自定义属性在shaderMaterial上失败

时间:2014-07-13 08:42:12

标签: three.js webgl

我正在尝试在shaderMaterial上使用自定义属性,但我无法让它工作。 我的简化代码是

attributes = {
    aColor:     { type: "f", value:] }, 
};

for ( i = 0; i < points.length; i ++ ) {
    attributes.aColor.value.push (0.9) ;
}

var uniforms = THREE.UniformsLib['lights'];

sMaterial = new THREE.ShaderMaterial ({
    attributes: attributes,
    uniforms: uniforms,
    vertexShader: vShader,
    fragmentShader: fShader,
    lights: true,
})
var line2 = new THREE.Line( geometry, sMaterial);
scene.add( line2 );

在我的着色器中,我设置了一个调试语句

attribute float aColor;     

void main() 
    if (aColor == 0.0) {
          // debugcode
    }

并且始终执行debugcode。

检查WebGlProgram,我可以在ACTIVE_ATTRIBUTES中看到aColor,看起来没问题。

这里出了什么问题?

或者,更好的是,我该如何调试这样的问题呢?

2 个答案:

答案 0 :(得分:1)

试着,我发现了问题。

我正在重复使用我已经用于另一个网格的几何体,并且不知何故导致了这个问题。

无论如何,我仍然有兴趣学习处理这类问题的技巧

答案 1 :(得分:1)

来自@ vals&#39;回答,我刚刚解决了一个类似的问题,不是使用共享的几何,而是尝试将具有属性的新着色器材质分配给现有对象。这是因为如果three.js检测到几何体及其拥有对象已经初始化(使用变量geometry.__webglInit),那么即使材料发生了变化,它也不会尝试更新GPU内存中的几何缓冲区,包括属性。除非渲染器检测到对象已添加到场景中,否则初始化也不会运行。

我使用的解决方案:

// Create the new shader
var shader = new THREE.ShaderMaterial({
    attributes: {intensity: {type: 'f', value: []}},
    vertexShader: vShaderText,
    fragmentShader: fShaderText
});

// Populate the intensity attribute
// ...

// Remove the existing scene object
var existingObject = myObjects[0]; // ... retrieve from scene or variable
var geometry = existingObject.geometry;
scene.remove(existingObject);

// Recreate the new scene object (important!: note geometry.clone() below)
var pc = new THREE.PointCloud(geometry.clone(), shader);
scene.add(pc);

// Clean up memory
geometry.dispose();

通过重用已经存在于GPU内存中的现有顶点缓冲区,可能有更多内存有效的方法,但这对我们的应用程序来说效果非常好。