我正在尝试在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,看起来没问题。
这里出了什么问题?
或者,更好的是,我该如何调试这样的问题呢?
答案 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内存中的现有顶点缓冲区,可能有更多内存有效的方法,但这对我们的应用程序来说效果非常好。