我正在使用THREE.js积分,有时我需要它们具有不同的每点颜色。有时,我也在修改他们的alpha值,所以我必须编写自己的着色器程序。
在JavaScript中,我有以下代码:
let materials;
if (pointCloudData.colors !== undefined) {
geometry.colors = pointCloudData.colors.map(hexColor => new THREE.Color(hexColor));
// If the point cloud has color for each point...
materials = new THREE.ShaderMaterial({
vertexColors: THREE.VertexColors,
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
} else {
// Set color for the whole cloud
materials = new THREE.ShaderMaterial({
uniforms: {
unicolor: { value: pointCloudData.color },
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
}
const pointCloud = new THREE.Points(geometry, materials);
我基本上将网格颜色设置为均匀值,除非我已经定义了每个点颜色 - 然后我将vertexColors设置为几何。我还检查了存储在geometry.colors中的值,它们是范围[0,1]中的正确RGB值。
我的顶点着色器代码:
attribute float size;
attribute float alpha;
varying float vAlpha;
varying vec3 vColor;
void main() {
vAlpha = alpha;
#ifdef USE_COLOR
vColor = color;
#endif
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( 300.0 / -mvPosition.z );
gl_Position = projectionMatrix * mvPosition;
}
我的Fragment着色器代码:
uniform vec3 unicolor;
varying vec3 vColor;
varying float vAlpha;
void main() {
#ifdef USE_COLOR
gl_FragColor = vec4(vColor, vAlpha);
#else
gl_FragColor = vec4(unicolor, vAlpha);
#endif
}
同样,我正在检查是否设置了vertexColor,然后将其传递给片段着色器,然后设置每点。
出于某种原因,在设置每点颜色时顶点都是白色的(屏幕截图:The white pixels should be green/red)。我远非WebGL的高级用户,任何帮助将不胜感激。我做错了,我不知道吗?
答案 0 :(得分:2)
您正在创建自定义ShaderMaterial
并在片段着色器中使用此模式:
#ifdef USE_COLOR
vColor = color;
#endif
因此,您需要指定material.defines
,如此:
var defines = {};
defines[ "USE_COLOR" ] = "";
// points material
var shaderMaterial = new THREE.ShaderMaterial( {
defines: defines,
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexshader' ).textContent,
fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
transparent: true
} );
您无需设置vertexColors: THREE.VertexColors
。这只是内置材质使用的一个标志,用于提醒渲染器为您设置defines
。
three.js r.85
答案 1 :(得分:1)
好吧,我想我已经弄明白了,因为它现在正在运作。
我必须将颜色设置为几何属性:
const colors = new Float32Array(n * 3);
for (let i = 0; i < n; i += 1) {
new THREE.Color(pointCloudData.colors[i]).toArray(colors, i * 3);
}
geometry.addAttribute('colors', new THREE.BufferAttribute(colors, 1));
我还使用了WestLangley提供的建议,并从Material定义中删除了vertexColors: THREE.VertexColors,
部分并设置了定义:
materials = new THREE.ShaderMaterial({
defines: {
USE_COLOR: '',
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
然后在我的Vertex着色器中添加了:
attributes vec3 colors;
获取从JavaScript传递的颜色。其余的是相同的,我只是使用与上面发布的问题相同的代码将颜色传递给片段着色器。