我基于顶点数组在three.js中绘制一条线,并希望将线的颜色设置为沿线的两个点(不是顶点)之间的特定值。 这两个点是距直线原点特定距离的点,例如我想沿着500单位的线在50到100单位的距离之间更改颜色。我该怎么做?
使用vertexColors: THREE.VertexColors
,我只能指定线顶点之间的颜色。我想我需要将两个点作为附加顶点传递,但是如何获得沿线具有XYZ坐标的位置?
感谢您提示如何完成此操作!
答案 0 :(得分:2)
一种选择是使用THREE.LineDashedMaterial()
来修改.onBeforeCompile()
:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 250, 500);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.GridHelper(500, 10));
var geom = new THREE.BufferGeometry().setFromPoints(
[
new THREE.Vector3(-250, 0, 0),
new THREE.Vector3(250, 0, 0)
]
);
var mat = new THREE.LineDashedMaterial({
color: "red"
});
var uniforms = {
segmentStart: {
value: 50
},
segmentEnd: {
value: 100
},
segmentColor: {
value: new THREE.Color("yellow")
}
}
mat.onBeforeCompile = shader => {
shader.uniforms.segmentStart = uniforms.segmentStart;
shader.uniforms.segmentEnd = uniforms.segmentEnd;
shader.uniforms.segmentColor = uniforms.segmentColor;
shader.fragmentShader = `
uniform float segmentStart;
uniform float segmentEnd;
uniform vec3 segmentColor;
` + shader.fragmentShader; // add uniforms
shader.fragmentShader = shader.fragmentShader.replace(
`if ( mod( vLineDistance, totalSize ) > dashSize ) {
discard;
}`, // remove the part for dash
``
);
shader.fragmentShader = shader.fragmentShader.replace(
`gl_FragColor = vec4( outgoingLight, diffuseColor.a );`,
`gl_FragColor = vec4( outgoingLight, diffuseColor.a );
if (vLineDistance >= segmentStart && vLineDistance <= segmentEnd) gl_FragColor.rgb = vec3(1, 1, 0);
`
); // add showing of a segment
console.log(shader.fragmentShader);
}
var line = new THREE.Line(geom, mat);
line.computeLineDistances();
scene.add(line);
var clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
uniforms.segmentEnd.value = 250 + Math.sin(clock.getElapsedTime()) * 150;
renderer.render(scene, camera)
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>