Reputation: 79
I'm implementing a particules systems with dedicated Vertex shader. Here a code example: https://jsfiddle.net/dthevenin/7arntcog/
I do use a Raycaster to do mouse picking and make possible to interact with one particule.
The code works as expected until I try to change the position of a vertex from the Vertex Shader. For instance in that example, I do pass a time value as an Uniform, and modify the x position with that time's value.
vec4 mvPosition = modelViewMatrix * vec4(position.x + time, position.y, position.z, 1.0);
Then the Raycaster failed to calculate the intersection.
To see the issue, uncomment the line 86, then clicking on a particule does not work.
What is wrong with that code / that solution?
Upvotes: 0
Views: 271
Reputation: 28472
When you use the raycaster intersection method, you're testing against the original geometry.attributes.position
vertex values. This calculation takes place in your CPU before they get displaced in your vertex shader. These values don't know what's going on in the GPU, so any vertex-shader position changes won't reflect in your raycasting.
If you need to displace your vertices and also perform raycasting after this displacement, you'll have to constantly update the position
attribute so the changes are accessible both in CPU and GPU calculations. Here's an official example of this method in action. You can see the source code in the button in the corner, but here's the relevant code to make your geometry dynamic.
const position = geometry.attributes.position;
position.usage = THREE.DynamicDrawUsage;
for ( let i = 0; i < position.count; i ++ ) {
const y = 35 * Math.sin( i / 2 );
position.setY( i, y );
}
It's definitely less efficient to do it in the CPU than in the vertex shader, but it's the only easy solution if you need to do raycasting.
Upvotes: 2